Index: Frontend/ASTUnit.cpp =================================================================== --- Frontend/ASTUnit.cpp +++ Frontend/ASTUnit.cpp @@ -1948,6 +1948,7 @@ case CodeCompletionContext::CCC_ObjCMessageReceiver: case CodeCompletionContext::CCC_DotMemberAccess: case CodeCompletionContext::CCC_ArrowMemberAccess: + case CodeCompletionContext::CCC_ClassOrStructScope: case CodeCompletionContext::CCC_ObjCPropertyAccess: case CodeCompletionContext::CCC_Namespace: case CodeCompletionContext::CCC_Type: Index: Sema/CodeCompleteConsumer.cpp =================================================================== --- Sema/CodeCompleteConsumer.cpp +++ Sema/CodeCompleteConsumer.cpp @@ -49,6 +49,7 @@ case CCC_Expression: case CCC_ObjCMessageReceiver: case CCC_ParenthesizedExpression: + case CCC_ClassOrStructScope: return true; case CCC_TopLevel: @@ -160,6 +161,8 @@ return "IncludedFile"; case CCKind::CCC_Recovery: return "Recovery"; + case CCKind::CCC_ClassOrStructScope: + return "ClassOrStructScope"; } llvm_unreachable("Invalid CodeCompletionContext::Kind!"); } Index: Sema/SemaCodeComplete.cpp =================================================================== --- Sema/SemaCodeComplete.cpp +++ Sema/SemaCodeComplete.cpp @@ -4727,9 +4727,22 @@ if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx)) return; + CodeCompletionContext CCContext = [&]() { + if (SS.getScopeRep() && + (SS.getScopeRep()->getKind() == NestedNameSpecifier::TypeSpec || + SS.getScopeRep()->getKind() == + NestedNameSpecifier::TypeSpecWithTemplate) && + SS.getScopeRep()->getAsType()) { + QualType BaseType = QualType(SS.getScopeRep()->getAsType(), 0); + return CodeCompletionContext( + CodeCompletionContext::CCC_ClassOrStructScope, BaseType); + } + + return CodeCompletionContext(CodeCompletionContext::CCC_Name); + }(); + ResultBuilder Results(*this, CodeCompleter->getAllocator(), - CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext::CCC_Name); + CodeCompleter->getCodeCompletionTUInfo(), CCContext); Results.EnterNewScope(); // The "template" keyword can follow "::" in the grammar, but only Index: clang/Sema/CodeCompleteConsumer.h =================================================================== --- clang/Sema/CodeCompleteConsumer.h +++ clang/Sema/CodeCompleteConsumer.h @@ -241,6 +241,14 @@ /// \c CodeCompletionContext::getType(). CCC_ArrowMemberAccess, + /// Code completion occurred on the right-hand side of a class or struct + /// name followed by double colon. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_ClassOrStructScope, + /// Code completion occurred on the right-hand side of an Objective-C /// property access expression. /// @@ -364,7 +372,7 @@ : CCKind(CCKind), SelIdents(SelIdents) { if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess || CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage || - CCKind == CCC_ObjCInstanceMessage) + CCKind == CCC_ObjCInstanceMessage || CCKind == CCC_ClassOrStructScope) BaseType = T; else PreferredType = T; Index: libclang/CIndexCodeCompletion.cpp =================================================================== --- libclang/CIndexCodeCompletion.cpp +++ libclang/CIndexCodeCompletion.cpp @@ -543,7 +543,8 @@ case CodeCompletionContext::CCC_MacroName: case CodeCompletionContext::CCC_PreprocessorExpression: case CodeCompletionContext::CCC_PreprocessorDirective: - case CodeCompletionContext::CCC_TypeQualifiers: { + case CodeCompletionContext::CCC_TypeQualifiers: + case CodeCompletionContext::CCC_ClassOrStructScope: { //Only Clang results should be accepted, so we'll set all of the other //context bits to 0 (i.e. the empty set) contexts = CXCompletionContext_Unexposed;