Index: cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h =================================================================== --- cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h +++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h @@ -821,6 +821,9 @@ /// Whether this result is hidden by another name. bool Hidden : 1; + /// Whether this is a class member from base class. + bool InBaseClass : 1; + /// Whether this result was found via lookup into a base class. bool QualifierIsInformative : 1; @@ -859,7 +862,7 @@ bool Accessible = true, std::vector FixIts = std::vector()) : Declaration(Declaration), Priority(Priority), Kind(RK_Declaration), - FixIts(std::move(FixIts)), Hidden(false), + FixIts(std::move(FixIts)), Hidden(false), InBaseClass(false), QualifierIsInformative(QualifierIsInformative), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(Qualifier) { @@ -870,7 +873,7 @@ /// Build a result that refers to a keyword or symbol. CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword) : Keyword(Keyword), Priority(Priority), Kind(RK_Keyword), - CursorKind(CXCursor_NotImplemented), Hidden(false), + CursorKind(CXCursor_NotImplemented), Hidden(false), InBaseClass(false), QualifierIsInformative(false), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false) {} @@ -879,28 +882,29 @@ const MacroInfo *MI = nullptr, unsigned Priority = CCP_Macro) : Macro(Macro), Priority(Priority), Kind(RK_Macro), - CursorKind(CXCursor_MacroDefinition), Hidden(false), + CursorKind(CXCursor_MacroDefinition), Hidden(false), InBaseClass(false), QualifierIsInformative(false), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false), MacroDefInfo(MI) {} /// Build a result that refers to a pattern. - CodeCompletionResult(CodeCompletionString *Pattern, - unsigned Priority = CCP_CodePattern, - CXCursorKind CursorKind = CXCursor_NotImplemented, - CXAvailabilityKind Availability = CXAvailability_Available, - const NamedDecl *D = nullptr) + CodeCompletionResult( + CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern, + CXCursorKind CursorKind = CXCursor_NotImplemented, + CXAvailabilityKind Availability = CXAvailability_Available, + const NamedDecl *D = nullptr) : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability), Hidden(false), - QualifierIsInformative(false), StartsNestedNameSpecifier(false), - AllParametersAreInformative(false), DeclaringEntity(false) {} + InBaseClass(false), QualifierIsInformative(false), + StartsNestedNameSpecifier(false), AllParametersAreInformative(false), + DeclaringEntity(false) {} /// Build a result that refers to a pattern with an associated /// declaration. CodeCompletionResult(CodeCompletionString *Pattern, const NamedDecl *D, unsigned Priority) : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern), - Hidden(false), QualifierIsInformative(false), + Hidden(false), InBaseClass(false), QualifierIsInformative(false), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false) { computeCursorKindAndAvailability(); Index: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp =================================================================== --- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp +++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp @@ -548,13 +548,18 @@ switch (Results[I].Kind) { case CodeCompletionResult::RK_Declaration: OS << *Results[I].Declaration; - if (Results[I].Hidden) - OS << " (Hidden)"; - if (CodeCompletionString *CCS - = Results[I].CreateCodeCompletionString(SemaRef, Context, - getAllocator(), - CCTUInfo, - includeBriefComments())) { + { + std::vector Tags; + if (Results[I].Hidden) + Tags.push_back("Hidden"); + if (Results[I].InBaseClass) + Tags.push_back("InBase"); + if (!Tags.empty()) + OS << " (" << llvm::join(Tags, ",") << ")"; + } + if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( + SemaRef, Context, getAllocator(), CCTUInfo, + includeBriefComments())) { OS << " : " << CCS->getAsString(); if (const char *BriefComment = CCS->getBriefComment()) OS << " : " << BriefComment; Index: cfe/trunk/lib/Sema/SemaCodeComplete.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp @@ -970,6 +970,11 @@ MaybeAddConstructorResults(R); } +static void setInBaseClass(ResultBuilder::Result &R) { + R.Priority += CCD_InBaseClass; + R.InBaseClass = true; +} + void ResultBuilder::AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, bool InBaseClass = false) { if (R.Kind != Result::RK_Declaration) { @@ -1030,7 +1035,7 @@ // Adjust the priority if this result comes from a base class. if (InBaseClass) - R.Priority += CCD_InBaseClass; + setInBaseClass(R); AdjustResultPriorityForDecl(R); @@ -5659,7 +5664,7 @@ R.StartParameter = SelIdents.size(); R.AllParametersAreInformative = (WantKind != MK_Any); if (!InOriginalClass) - R.Priority += CCD_InBaseClass; + setInBaseClass(R); Results.MaybeAddResult(R, CurContext); } } @@ -7763,10 +7768,10 @@ } unsigned Priority = CCP_CodePattern; + auto R = Result(Builder.TakeString(), Method, Priority); if (!M->second.getInt()) - Priority += CCD_InBaseClass; - - Results.AddResult(Result(Builder.TakeString(), Method, Priority)); + setInBaseClass(R); + Results.AddResult(std::move(R)); } // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of Index: cfe/trunk/test/CodeCompletion/member-access.cpp =================================================================== --- cfe/trunk/test/CodeCompletion/member-access.cpp +++ cfe/trunk/test/CodeCompletion/member-access.cpp @@ -51,16 +51,16 @@ }; // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:31:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 --implicit-check-not="Derived : Derived(" %s - // CHECK-CC1: Base1 : Base1:: - // CHECK-CC1: member1 : [#int#][#Base1::#]member1 - // CHECK-CC1: member1 : [#int#][#Base2::#]member1 - // CHECK-CC1: member2 : [#float#][#Base1::#]member2 - // CHECK-CC1: member3 + // CHECK-CC1: Base1 (InBase) : Base1:: + // CHECK-CC1: member1 (InBase) : [#int#][#Base1::#]member1 + // CHECK-CC1: member1 (InBase) : [#int#][#Base2::#]member1 + // CHECK-CC1: member2 (InBase) : [#float#][#Base1::#]member2 + // CHECK-CC1: member3 (InBase) // CHECK-CC1: member4 - // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#float#>) - // CHECK-CC1: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] - // CHECK-CC1: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>) - // CHECK-CC1: memfun2 : [#void#][#Base3::#]memfun2(<#int#>) + // CHECK-CC1: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>) + // CHECK-CC1: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#] + // CHECK-CC1: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>) + // CHECK-CC1: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>) // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>) // Make sure this doesn't crash @@ -93,12 +93,12 @@ TemplateClass *object2) { object.field; object2->field; -// CHECK-CC2: baseTemplateField : [#T#][#BaseTemplate::#]baseTemplateField -// CHECK-CC2: baseTemplateFunction : [#T#][#BaseTemplate::#]baseTemplateFunction() +// CHECK-CC2: baseTemplateField (InBase) : [#T#][#BaseTemplate::#]baseTemplateField +// CHECK-CC2: baseTemplateFunction (InBase) : [#T#][#BaseTemplate::#]baseTemplateFunction() // CHECK-CC2: field : [#T#]field // CHECK-CC2: function : [#T#]function() -// CHECK-CC2: member1 : [#int#][#Base1::#]member1 -// CHECK-CC2: member2 : [#float#][#Base1::#]member2 +// CHECK-CC2: member1 (InBase) : [#int#][#Base1::#]member1 +// CHECK-CC2: member2 (InBase) : [#float#][#Base1::#]member2 // CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>) // CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>) @@ -111,12 +111,12 @@ TemplateClass *object2) { object.field; object2->field; -// CHECK-CC3: baseTemplateField : [#int#][#BaseTemplate::#]baseTemplateField -// CHECK-CC3: baseTemplateFunction : [#int#][#BaseTemplate::#]baseTemplateFunction() +// CHECK-CC3: baseTemplateField (InBase) : [#int#][#BaseTemplate::#]baseTemplateField +// CHECK-CC3: baseTemplateFunction (InBase) : [#int#][#BaseTemplate::#]baseTemplateFunction() // CHECK-CC3: field : [#int#]field // CHECK-CC3: function : [#int#]function() -// CHECK-CC3: member1 : [#int#][#Base1::#]member1 -// CHECK-CC3: member2 : [#float#][#Base1::#]member2 +// CHECK-CC3: member1 (InBase) : [#int#][#Base1::#]member1 +// CHECK-CC3: member2 (InBase) : [#float#][#Base1::#]member2 // CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>) // CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>) @@ -182,31 +182,31 @@ } // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:177:6 %s -o - | FileCheck -check-prefix=CHECK-CC8 --implicit-check-not="Derived : Derived(" %s -// CHECK-CC8: Base1 : Base1:: -// CHECK-CC8: member1 : [#int#][#Base1::#]member1 -// CHECK-CC8: member1 : [#int#][#Base2::#]member1 -// CHECK-CC8: member2 : [#float#][#Base1::#]member2 -// CHECK-CC8: member3 : [#double#][#Base2::#]member3 +// CHECK-CC8: Base1 (InBase) : Base1:: +// CHECK-CC8: member1 (InBase) : [#int#][#Base1::#]member1 +// CHECK-CC8: member1 (InBase) : [#int#][#Base2::#]member1 +// CHECK-CC8: member2 (InBase) : [#float#][#Base1::#]member2 +// CHECK-CC8: member3 (InBase) : [#double#][#Base2::#]member3 // CHECK-CC8: member4 : [#int#]member4 // CHECK-CC8: member5 : [#int#]member5 (requires fix-it: {177:4-177:6} to ".") -// CHECK-CC8: memfun1 : [#void#][#Base3::#]memfun1(<#float#>) -// CHECK-CC8: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] -// CHECK-CC8: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>) -// CHECK-CC8: memfun2 : [#void#][#Base3::#]memfun2(<#int#>) +// CHECK-CC8: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>) +// CHECK-CC8: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#] +// CHECK-CC8: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>) +// CHECK-CC8: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>) // CHECK-CC8: memfun3 : [#int#]memfun3(<#int#>) // CHECK-CC8: operator-> : [#Derived *#]operator->()[# const#] (requires fix-it: {177:4-177:6} to ".") // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:181:6 %s -o - | FileCheck -check-prefix=CHECK-CC9 --implicit-check-not="Derived : Derived(" %s -// CHECK-CC9: Base1 : Base1:: -// CHECK-CC9: member1 : [#int#][#Base1::#]member1 (requires fix-it: {181:4-181:5} to "->") -// CHECK-CC9: member1 : [#int#][#Base2::#]member1 (requires fix-it: {181:4-181:5} to "->") -// CHECK-CC9: member2 : [#float#][#Base1::#]member2 (requires fix-it: {181:4-181:5} to "->") -// CHECK-CC9: member3 : [#double#][#Base2::#]member3 (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: Base1 (InBase) : Base1:: +// CHECK-CC9: member1 (InBase) : [#int#][#Base1::#]member1 (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: member1 (InBase) : [#int#][#Base2::#]member1 (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: member2 (InBase) : [#float#][#Base1::#]member2 (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: member3 (InBase) : [#double#][#Base2::#]member3 (requires fix-it: {181:4-181:5} to "->") // CHECK-CC9: member4 : [#int#]member4 (requires fix-it: {181:4-181:5} to "->") // CHECK-CC9: member5 : [#int#]member5 -// CHECK-CC9: memfun1 : [#void#][#Base3::#]memfun1(<#float#>) (requires fix-it: {181:4-181:5} to "->") -// CHECK-CC9: memfun1 : [#void#][#Base3::#]memfun1(<#double#>)[# const#] (requires fix-it: {181:4-181:5} to "->") -// CHECK-CC9: memfun1 (Hidden) : [#void#]Base2::memfun1(<#int#>) (requires fix-it: {181:4-181:5} to "->") -// CHECK-CC9: memfun2 : [#void#][#Base3::#]memfun2(<#int#>) (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>) (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#] (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>) (requires fix-it: {181:4-181:5} to "->") +// CHECK-CC9: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>) (requires fix-it: {181:4-181:5} to "->") // CHECK-CC9: memfun3 : [#int#]memfun3(<#int#>) (requires fix-it: {181:4-181:5} to "->") // CHECK-CC9: operator-> : [#Derived *#]operator->()[# const#] Index: cfe/trunk/test/CodeCompletion/objc-message.mm =================================================================== --- cfe/trunk/test/CodeCompletion/objc-message.mm +++ cfe/trunk/test/CodeCompletion/objc-message.mm @@ -41,6 +41,6 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: categoryInstanceMethod : [#id#]categoryInstanceMethod // CHECK-CC1: instanceMethod1 : [#id#]instanceMethod1 -// CHECK-CC1: protocolInstanceMethod : [#id#]protocolInstanceMethod +// CHECK-CC1: protocolInstanceMethod (InBase) : [#id#]protocolInstanceMethod // RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:8 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: protocolInstanceMethod : [#id#]protocolInstanceMethod