diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 116628d8186..27481f95a73 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -191,7 +191,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { } public IBinding getBindingInAST(IASTName name, boolean forceResolve) { - IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, false); + IBinding[] bs= getBindingsInAST(name, forceResolve, false, false); return CPPSemantics.resolveAmbiguities(name, bs); } @@ -201,7 +201,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet, boolean checkPointOfDecl) { - IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl, true); + IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl); final IASTTranslationUnit tu = name.getTranslationUnit(); if (tu != null) { IIndex index = tu.getIndex(); @@ -242,8 +242,9 @@ abstract public class CPPScope implements ICPPASTInternalScope { return (IBinding[]) ArrayUtil.trim(IBinding.class, result); } + public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup, - boolean checkPointOfDecl, boolean expandUsingDirectives) { + boolean checkPointOfDecl) { populateCache(); final char[] c = name.getLookupKey(); IBinding[] result = null; @@ -272,17 +273,17 @@ abstract public class CPPScope implements ICPPASTInternalScope { if (obj instanceof ObjectSet) { ObjectSet os= (ObjectSet) obj; for (int j = 0; j < os.size(); j++) { - result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); + result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, result); } } else { - result = addCandidate(obj, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); + result = addCandidate(obj, name, forceResolve, checkPointOfDecl, result); } } return (IBinding[]) ArrayUtil.trim(IBinding.class, result); } private IBinding[] addCandidate(Object candidate, IASTName name, boolean forceResolve, - boolean checkPointOfDecl, boolean expandUsingDirectives, IBinding[] result) { + boolean checkPointOfDecl, IBinding[] result) { if (checkPointOfDecl) { IASTTranslationUnit tu= name.getTranslationUnit(); if (!CPPSemantics.declaredBefore(candidate, name, tu != null && tu.getIndex() != null)) { @@ -308,13 +309,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { binding= (IBinding) candidate; } - if (expandUsingDirectives && binding instanceof ICPPUsingDeclaration) { - IBinding[] delegates = ((ICPPUsingDeclaration) binding).getDelegates(); - result= (IBinding[]) ArrayUtil.addAll(IBinding.class, result, delegates); - } else { - result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding); - } - return result; + return (IBinding[]) ArrayUtil.append(IBinding.class, result, binding); } public final void populateCache() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 1999efadc07..107cf4976a2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -1195,41 +1195,46 @@ public class CPPSemantics { // For index scopes the point of declaration is ignored. bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet); } + return expandUsingDeclarationsAndRemoveObjects(bindings, data.typesOnly); + } + + private static IBinding[] expandUsingDeclarationsAndRemoveObjects(final IBinding[] bindings, boolean removeObjects) { + if (bindings == null || bindings.length == 0) + return IBinding.EMPTY_BINDING_ARRAY; - if (data.typesOnly) { - return removeObjects(bindings); + for (IBinding b : bindings) { + if (b == null) + break; + + if (b instanceof ICPPUsingDeclaration || (removeObjects && isObject(b))) { + List result= new ArrayList(bindings.length); + expandUsingDeclarations(bindings, removeObjects, result); + return result.toArray(new IBinding[result.size()]); + } } return bindings; } - private static IBinding[] removeObjects(final IBinding[] bindings) { - final int length = bindings.length; - IBinding[] copy= null; - int pos= 0; - for (int i = 0; i < length; i++) { - final IBinding binding= bindings[i]; - IBinding check= binding; - if (binding instanceof ICPPUsingDeclaration) { - IBinding[] delegates= ((ICPPUsingDeclaration) binding).getDelegates(); - if (delegates.length > 0) - check= delegates[0]; - } - if (check instanceof IType || check instanceof ICPPNamespace) { - if (copy != null) { - copy[pos]= binding; - } - pos++; - } else { - if (copy == null) { - copy= new IBinding[length-1]; - System.arraycopy(bindings, 0, copy, 0, pos); + private static boolean isObject(IBinding b) { + return !(b instanceof IType || b instanceof ICPPNamespace); + } + + private static void expandUsingDeclarations(IBinding[] bindings, boolean removeObjects, List result) { + if (bindings != null) { + for (IBinding b : bindings) { + if (b == null) + return; + if (b instanceof ICPPUsingDeclaration) { + for (IBinding d : ((ICPPUsingDeclaration) b).getDelegates()) { + if (d != null && !(removeObjects && isObject(d))) { + result.add(d); + } + } + } else if (!(removeObjects && isObject(b))) { + result.add(b); } - } + } } - if (pos == 0) - return IBinding.EMPTY_BINDING_ARRAY; - - return copy == null ? bindings : copy; } private static ICPPTemplateScope enclosingTemplateScope(IASTNode node) { diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 6fd0957fcef..978cd2f35f3 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -46,128 +46,135 @@ public class CompletionTests extends AbstractContentAssistTest { private IProject fProject; - //{DisturbWith.cpp} - // int gTemp; - // void gFunc(); - // typedef struct { - // int mem; - // } gStruct; - // class gClass {}; - // namespace gns { - // int gnsTemp; - // void gnsFunc(); - // typedef struct { - // int mem; - // } gnsStruct; - // class gnsClass {}; - // }; + // {DisturbWith.cpp} + // int gTemp; + // void gFunc(); + // typedef struct { + // int mem; + // } gStruct; + // class gClass {}; + // namespace gns { + // int gnsTemp; + // void gnsFunc(); + // typedef struct { + // int mem; + // } gnsStruct; + // class gnsClass {}; + // }; - //{CompletionTest.h} - //class C1; - //class C2; - //class C3; + // {CompletionTest.h} + // class C1; + // class C2; + // class C3; // - //extern C1* gC1; - //C2* gC2 = 0; + // extern C1* gC1; + // C2* gC2 = 0; // - //extern C1* gfC1(); - //C2* gfC2(); + // extern C1* gfC1(); + // C2* gfC2(); // - //enum E1 {e11, e12}; + // enum E1 {e11, e12}; // - //class C1 { - //public: - // enum E2 {e21, e22}; + // class C1 { + // public: + // enum E2 {e21, e22}; // - // C1* fMySelf; - // void iam1(); + // C1* fMySelf; + // void iam1(); // - // C1* m123(); - // C1* m12(); - // C1* m13(); + // C1* m123(); + // C1* m12(); + // C1* m13(); // - //protected: - // void m1protected(); - //private: - // void m1private(); - //}; - //typedef C1 T1; + // protected: + // void m1protected(); + // private: + // void m1private(); + // }; + // typedef C1 T1; // // - //class C2 : public T1 { - //public: - // C2* fMySelf; - // void iam2(); + // class C2 : public T1 { + // public: + // C2* fMySelf; + // void iam2(); // - // C2* m123(); - // C2* m12(); - // C2* m23(); - // C1* operator()(int x); + // C2* m123(); + // C2* m12(); + // C2* m23(); + // C1* operator()(int x); // - //protected: + // protected: // void m2protected(); - //private: + // private: // void m2private(); - // friend void _friend_function(C3* x); - // friend class _friend_class; - //}; - //typedef C2 T2; + // friend void _friend_function(C3* x); + // friend class _friend_class; + // }; + // typedef C2 T2; // // - //class C3 : public C2 { - //public: - // C3* fMySelf; - // void iam3(); + // class C3 : public C2 { + // public: + // C3* fMySelf; + // void iam3(); // - // C3* m123(); - // C3* m13(); + // C3* m123(); + // C3* m13(); // - // template T tConvert(); - //protected: + // template T tConvert(); + // protected: // void m3protected(); - //private: + // private: // void m3private(); - //}; - //typedef C3 T3; + // }; + // typedef C3 T3; // - //namespace ns { - // const int NSCONST= 1; - // class CNS { - // void mcns(); - // }; - //}; - //template class TClass { - // T fTField; - //public: - // TClass(T tArg) : fTField(tArg) { - // } - // T add(T tOther) { - // return fTField + tOther; - // } - //}; - //// bug 109480 - //class Printer - //{ - //public: - // static void InitPrinter(unsigned char port); - //private: - // //Storage for port printer is on - // static unsigned char port; - //protected: - //}; - //struct Struct1; - //struct Struct2; - //union Union1; - //union Union2; + // namespace ns { + // const int NSCONST= 1; + // class CNS { + // void mcns(); + // }; + // }; + // template class TClass { + // T fTField; + // public: + // TClass(T tArg) : fTField(tArg) { + // } + // T add(T tOther) { + // return fTField + tOther; + // } + // }; + // // bug 109480 + // class Printer + // { + // public: + // static void InitPrinter(unsigned char port); + // private: + // //Storage for port printer is on + // static unsigned char port; + // protected: + // }; + // struct Struct1; + // struct Struct2; + // union Union1; + // union Union2; // struct s206450 { // struct {int a1; int a2;}; // union {int u1; char u2;}; // struct {int a3;} a4; // int b; // }; - // typedef enum {__nix} _e204758; - // void _f204758(_e204758 x); - + // typedef enum {__nix} _e204758; + // void _f204758(_e204758 x); + // + // // Bug 331056 + // namespace _A_331056 { + // class Reference {}; + // } + // namespace _B_331056 { + // using ::_A_331056::Reference; + // } public CompletionTests(String name) { super(name, true); @@ -747,7 +754,7 @@ public class CompletionTests extends AbstractContentAssistTest { assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); } - //using namespace /*cursor*/ + //using namespace n/*cursor*/ public void testAutoColons2() throws Exception { final String[] expected= { "ns" @@ -1233,7 +1240,7 @@ public class CompletionTests extends AbstractContentAssistTest { public void testConstructorInitializerList_EmptyInput_Bug266586() throws Exception { final String[] expected= {"mOne", "Base", "Base(int)", "Base(const Base &)", "Helper", - "Helper(void)", "Helper(const Helper &)", + "Helper(void)", "Helper(const Helper &)", "_A_331056", "_B_331056", // Namespaces must be offered as well. In order for this code // to compile with gcc (e.g. 4.1.2), you need to write // ::ns::Base() instead of just Base(). @@ -1326,4 +1333,11 @@ public class CompletionTests extends AbstractContentAssistTest { final String[] expected= { "push_back(const int & value) : void" }; assertParameterHint(expected); } + + // using namespace ::_B_331056; + // Ref/*cursor*/ + public void testUsingDeclaration_Bug331056() throws Exception { + final String[] expected= { "Reference" }; + assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS); + } } \ No newline at end of file