From 00c37ef0216518f404953eb90f8cf70c5a8644f9 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 11 Aug 2010 21:23:17 +0000 Subject: [PATCH] Once code completion has completed, pass a "completion context" on to the code-completion consumer. The consumer can use this information to augument, filter, or display the code-completion results. llvm-svn: 110858 --- clang/include/clang/Parse/Action.h | 28 +- .../include/clang/Sema/CodeCompleteConsumer.h | 91 +++++- clang/lib/Parse/ParseDecl.cpp | 10 +- clang/lib/Parse/ParseExpr.cpp | 4 +- clang/lib/Parse/ParseExprCXX.cpp | 2 +- clang/lib/Parse/ParseObjc.cpp | 6 +- clang/lib/Parse/ParseStmt.cpp | 6 +- clang/lib/Parse/Parser.cpp | 10 +- clang/lib/Sema/CodeCompleteConsumer.cpp | 2 + clang/lib/Sema/Sema.h | 2 +- clang/lib/Sema/SemaCodeComplete.cpp | 301 ++++++++++++------ clang/tools/libclang/CIndexCodeCompletion.cpp | 4 +- 12 files changed, 331 insertions(+), 135 deletions(-) diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 9d8c5b1d1fb5..263dacb43d24 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -2776,41 +2776,41 @@ public: //@{ /// \brief Describes the context in which code completion occurs. - enum CodeCompletionContext { + enum ParserCompletionContext { /// \brief Code completion occurs at top-level or namespace context. - CCC_Namespace, + PCC_Namespace, /// \brief Code completion occurs within a class, struct, or union. - CCC_Class, + PCC_Class, /// \brief Code completion occurs within an Objective-C interface, protocol, /// or category. - CCC_ObjCInterface, + PCC_ObjCInterface, /// \brief Code completion occurs within an Objective-C implementation or /// category implementation - CCC_ObjCImplementation, + PCC_ObjCImplementation, /// \brief Code completion occurs within the list of instance variables /// in an Objective-C interface, protocol, category, or implementation. - CCC_ObjCInstanceVariableList, + PCC_ObjCInstanceVariableList, /// \brief Code completion occurs following one or more template /// headers. - CCC_Template, + PCC_Template, /// \brief Code completion occurs following one or more template /// headers within a class. - CCC_MemberTemplate, + PCC_MemberTemplate, /// \brief Code completion occurs within an expression. - CCC_Expression, + PCC_Expression, /// \brief Code completion occurs within a statement, which may /// also be an expression or a declaration. - CCC_Statement, + PCC_Statement, /// \brief Code completion occurs at the beginning of the /// initialization statement (or expression) in a for loop. - CCC_ForInit, + PCC_ForInit, /// \brief Code completion occurs within the condition of an if, /// while, switch, or for statement. - CCC_Condition, + PCC_Condition, /// \brief Code completion occurs within the body of a function on a /// recovery path, where we do not have a specific handle on our position /// in the grammar. - CCC_RecoveryInFunction + PCC_RecoveryInFunction }; /// \brief Code completion for an ordinary name that occurs within the given @@ -2821,7 +2821,7 @@ public: /// \param CompletionContext the context in which code completion /// occurs. virtual void CodeCompleteOrdinaryName(Scope *S, - CodeCompletionContext CompletionContext) { } + ParserCompletionContext CompletionContext) { } /// \brief Code completion for a member access expression. /// diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h index 1c679ebf8608..5310b63477a7 100644 --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H #define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H +#include "clang/AST/Type.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include @@ -79,6 +80,84 @@ class NamedDecl; class NestedNameSpecifier; class Sema; +/// \brief The context in which code completion occurred, so that the +/// code-completion consumer can process the results accordingly. +class CodeCompletionContext { +public: + enum Kind { + /// \brief An unspecified code-completion context. + CCC_Other, + /// \brief Code completion occurred within a "top-level" completion context, + /// e.g., at namespace or global scope. + CCC_TopLevel, + /// \brief Code completion occurred within an Objective-C interface, + /// protocol, or category interface. + CCC_ObjCInterface, + /// \brief Code completion occurred within an Objective-C implementation + /// or category implementation. + CCC_ObjCImplementation, + /// \brief Code completion occurred within the instance variable list of + /// an Objective-C interface, implementation, or category implementation. + CCC_ObjCIvarList, + /// \brief Code completion occurred within a class, struct, or union. + CCC_ClassStructUnion, + /// \brief Code completion occurred where a statement (or declaration) is + /// expected in a function, method, or block. + CCC_Statement, + /// \brief Code completion occurred where an expression is expected. + CCC_Expression, + /// \brief Code completion occurred where an Objective-C message receiver + /// is expected. + CCC_ObjCMessageReceiver, + /// \brief Code completion occurred on the right-hand side of a member + /// access expression. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_MemberAccess, + /// \brief Code completion occurred after the "enum" keyword, to indicate + /// an enumeration name. + CCC_EnumTag, + /// \brief Code completion occurred after the "union" keyword, to indicate + /// a union name. + CCC_UnionTag, + /// \brief Code completion occurred after the "struct" or "class" keyword, + /// to indicate a struct or class name. + CCC_ClassOrStructTag, + /// \brief Code completion occurred where a protocol name is expected. + CCC_ObjCProtocolName + }; + +private: + enum Kind Kind; + + /// \brief The type of the base object in a member access expression. + QualType Type; + +public: + /// \brief Construct a new code-completion context of the given kind. + CodeCompletionContext(enum Kind Kind) : Kind(Kind) { + assert(Kind != CCC_MemberAccess && "Member access requires a type"); + } + + /// \brief Construct a new code-completion context of the given kind. + CodeCompletionContext(enum Kind Kind, QualType T) : Kind(Kind), Type(T) { + assert(Kind == CCC_MemberAccess && "Only member access has a type"); + } + + /// \brief Retrieve the kind of code-completion context. + enum Kind getKind() const { return Kind; } + + /// \brief Retrieve the type of the base object in a member-access + /// expression. + QualType getType() const { + assert(Kind == CCC_MemberAccess && "Only member access has a type"); + return Type; + } +}; + + /// \brief A "string" used to describe how code completion can /// be performed for an entity. /// @@ -514,7 +593,9 @@ public: /// \name Code-completion callbacks //@{ /// \brief Process the finalized code-completion results. - virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, + virtual void ProcessCodeCompleteResults(Sema &S, + CodeCompletionContext Context, + Result *Results, unsigned NumResults) { } /// \param S the semantic-analyzer object for which code-completion is being @@ -545,7 +626,9 @@ public: : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, false), OS(OS) {} /// \brief Prints the finalized code-completion results. - virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, + virtual void ProcessCodeCompleteResults(Sema &S, + CodeCompletionContext Context, + Result *Results, unsigned NumResults); virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, @@ -568,7 +651,9 @@ public: : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, true), OS(OS) {} /// \brief Prints the finalized code-completion results. - virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, + virtual void ProcessCodeCompleteResults(Sema &S, + CodeCompletionContext Context, + Result *Results, unsigned NumResults); virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 65b4fb77adc0..b0d9da584579 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -853,14 +853,14 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext) { if (Tok.is(tok::code_completion)) { - Action::CodeCompletionContext CCC = Action::CCC_Namespace; + Action::ParserCompletionContext CCC = Action::PCC_Namespace; if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) - CCC = DSContext == DSC_class? Action::CCC_MemberTemplate - : Action::CCC_Template; + CCC = DSContext == DSC_class? Action::PCC_MemberTemplate + : Action::PCC_Template; else if (DSContext == DSC_class) - CCC = Action::CCC_Class; + CCC = Action::PCC_Class; else if (ObjCImpDecl) - CCC = Action::CCC_ObjCImplementation; + CCC = Action::PCC_ObjCImplementation; Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); ConsumeCodeCompletionToken(); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index ec92f0869e5f..844dd3f873bb 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -220,7 +220,7 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { /// Parser::OwningExprResult Parser::ParseAssignmentExpression() { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Expression); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_Expression); ConsumeCodeCompletionToken(); } @@ -918,7 +918,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::caret: return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression()); case tok::code_completion: - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Expression); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_Expression); ConsumeCodeCompletionToken(); return ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, TypeOfCast); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 29f6bb94840d..f5ade8a8fb5e 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -734,7 +734,7 @@ bool Parser::ParseCXXCondition(OwningExprResult &ExprResult, SourceLocation Loc, bool ConvertToBoolean) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Condition); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_Condition); ConsumeCodeCompletionToken(); } diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index a7e08562d02a..00df5a2c5aba 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -348,8 +348,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, // Code completion within an Objective-C interface. if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), - ObjCImpDecl? Action::CCC_ObjCImplementation - : Action::CCC_ObjCInterface); + ObjCImpDecl? Action::PCC_ObjCImplementation + : Action::PCC_ObjCInterface); ConsumeCodeCompletionToken(); } @@ -1071,7 +1071,7 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), - Action::CCC_ObjCInstanceVariableList); + Action::PCC_ObjCInstanceVariableList); ConsumeCodeCompletionToken(); } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 1136be006ffe..a83aff182d30 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -98,7 +98,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } case tok::code_completion: - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Statement); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_Statement); ConsumeCodeCompletionToken(); return ParseStatementOrDeclaration(OnlyStatement); @@ -994,8 +994,8 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), - C99orCXXorObjC? Action::CCC_ForInit - : Action::CCC_Expression); + C99orCXXorObjC? Action::PCC_ForInit + : Action::PCC_Expression); ConsumeCodeCompletionToken(); } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index d0158871a9aa..4e0ae8723459 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -463,8 +463,8 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) break; case tok::code_completion: Actions.CodeCompleteOrdinaryName(getCurScope(), - ObjCImpDecl? Action::CCC_ObjCImplementation - : Action::CCC_Namespace); + ObjCImpDecl? Action::PCC_ObjCImplementation + : Action::PCC_Namespace); ConsumeCodeCompletionToken(); return ParseExternalDeclaration(Attr); case tok::kw_using: @@ -1101,17 +1101,17 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { void Parser::CodeCompletionRecovery() { for (Scope *S = getCurScope(); S; S = S->getParent()) { if (S->getFlags() & Scope::FnScope) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_RecoveryInFunction); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_RecoveryInFunction); return; } if (S->getFlags() & Scope::ClassScope) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Class); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_Class); return; } } - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Namespace); + Actions.CodeCompleteOrdinaryName(getCurScope(), Action::PCC_Namespace); } // Anchor the Parser::FieldCallback vtable to this translation unit. diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 62e4abbbbb3a..a7eca6a80418 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -438,6 +438,7 @@ CodeCompleteConsumer::~CodeCompleteConsumer() { } void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, + CodeCompletionContext Context, Result *Results, unsigned NumResults) { // Print the results. @@ -589,6 +590,7 @@ namespace clang { void CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, + CodeCompletionContext Context, Result *Results, unsigned NumResults) { // Print the results. diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 6167668b861f..02761ac234e5 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -4619,7 +4619,7 @@ public: /// \name Code completion //@{ virtual void CodeCompleteOrdinaryName(Scope *S, - CodeCompletionContext CompletionContext); + ParserCompletionContext CompletionContext); virtual void CodeCompleteExpression(Scope *S, QualType T, bool IntegralConstantExpression = false); virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base, diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 52ac8dd64987..9a03caa688cb 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1058,7 +1058,7 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, } } -static void AddStorageSpecifiers(Action::CodeCompletionContext CCC, +static void AddStorageSpecifiers(Action::ParserCompletionContext CCC, const LangOptions &LangOpts, ResultBuilder &Results) { typedef CodeCompleteConsumer::Result Result; @@ -1069,13 +1069,13 @@ static void AddStorageSpecifiers(Action::CodeCompletionContext CCC, Results.AddResult(Result("static")); } -static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC, +static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC, const LangOptions &LangOpts, ResultBuilder &Results) { typedef CodeCompleteConsumer::Result Result; switch (CCC) { - case Action::CCC_Class: - case Action::CCC_MemberTemplate: + case Action::PCC_Class: + case Action::PCC_MemberTemplate: if (LangOpts.CPlusPlus) { Results.AddResult(Result("explicit")); Results.AddResult(Result("friend")); @@ -1084,20 +1084,20 @@ static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC, } // Fall through - case Action::CCC_ObjCInterface: - case Action::CCC_ObjCImplementation: - case Action::CCC_Namespace: - case Action::CCC_Template: + case Action::PCC_ObjCInterface: + case Action::PCC_ObjCImplementation: + case Action::PCC_Namespace: + case Action::PCC_Template: if (LangOpts.CPlusPlus || LangOpts.C99) Results.AddResult(Result("inline")); break; - case Action::CCC_ObjCInstanceVariableList: - case Action::CCC_Expression: - case Action::CCC_Statement: - case Action::CCC_ForInit: - case Action::CCC_Condition: - case Action::CCC_RecoveryInFunction: + case Action::PCC_ObjCInstanceVariableList: + case Action::PCC_Expression: + case Action::PCC_Statement: + case Action::PCC_ForInit: + case Action::PCC_Condition: + case Action::PCC_RecoveryInFunction: break; } } @@ -1125,28 +1125,28 @@ static void AddTypedefResult(ResultBuilder &Results) { Results.AddResult(CodeCompleteConsumer::Result(Pattern)); } -static bool WantTypesInContext(Action::CodeCompletionContext CCC, +static bool WantTypesInContext(Action::ParserCompletionContext CCC, const LangOptions &LangOpts) { if (LangOpts.CPlusPlus) return true; switch (CCC) { - case Action::CCC_Namespace: - case Action::CCC_Class: - case Action::CCC_ObjCInstanceVariableList: - case Action::CCC_Template: - case Action::CCC_MemberTemplate: - case Action::CCC_Statement: - case Action::CCC_RecoveryInFunction: + case Action::PCC_Namespace: + case Action::PCC_Class: + case Action::PCC_ObjCInstanceVariableList: + case Action::PCC_Template: + case Action::PCC_MemberTemplate: + case Action::PCC_Statement: + case Action::PCC_RecoveryInFunction: return true; - case Action::CCC_ObjCInterface: - case Action::CCC_ObjCImplementation: - case Action::CCC_Expression: - case Action::CCC_Condition: + case Action::PCC_ObjCInterface: + case Action::PCC_ObjCImplementation: + case Action::PCC_Expression: + case Action::PCC_Condition: return false; - case Action::CCC_ForInit: + case Action::PCC_ForInit: return LangOpts.ObjC1 || LangOpts.C99; } @@ -1154,13 +1154,13 @@ static bool WantTypesInContext(Action::CodeCompletionContext CCC, } /// \brief Add language constructs that show up for "ordinary" names. -static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, +static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC, Scope *S, Sema &SemaRef, ResultBuilder &Results) { typedef CodeCompleteConsumer::Result Result; switch (CCC) { - case Action::CCC_Namespace: + case Action::PCC_Namespace: if (SemaRef.getLangOptions().CPlusPlus) { CodeCompletionString *Pattern = 0; @@ -1219,7 +1219,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, AddTypedefResult(Results); // Fall through - case Action::CCC_Class: + case Action::PCC_Class: if (SemaRef.getLangOptions().CPlusPlus) { // Using declaration CodeCompletionString *Pattern = new CodeCompletionString; @@ -1243,7 +1243,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, Results.AddResult(Result(Pattern)); } - if (CCC == Action::CCC_Class) { + if (CCC == Action::PCC_Class) { AddTypedefResult(Results); // public: @@ -1267,8 +1267,8 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, } // Fall through - case Action::CCC_Template: - case Action::CCC_MemberTemplate: + case Action::PCC_Template: + case Action::PCC_MemberTemplate: if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) { // template < parameters > CodeCompletionString *Pattern = new CodeCompletionString; @@ -1283,24 +1283,24 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results); break; - case Action::CCC_ObjCInterface: + case Action::PCC_ObjCInterface: AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true); AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results); break; - case Action::CCC_ObjCImplementation: + case Action::PCC_ObjCImplementation: AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true); AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results); break; - case Action::CCC_ObjCInstanceVariableList: + case Action::PCC_ObjCInstanceVariableList: AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true); break; - case Action::CCC_RecoveryInFunction: - case Action::CCC_Statement: { + case Action::PCC_RecoveryInFunction: + case Action::PCC_Statement: { AddTypedefResult(Results); CodeCompletionString *Pattern = 0; @@ -1472,12 +1472,12 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC, } // Fall through (for statement expressions). - case Action::CCC_ForInit: - case Action::CCC_Condition: + case Action::PCC_ForInit: + case Action::PCC_Condition: AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); // Fall through: conditions and statements can have expressions. - case Action::CCC_Expression: { + case Action::PCC_Expression: { CodeCompletionString *Pattern = 0; if (SemaRef.getLangOptions().CPlusPlus) { // 'this', if we're in a non-static member function. @@ -2226,19 +2226,55 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, static void HandleCodeCompleteResults(Sema *S, CodeCompleteConsumer *CodeCompleter, - CodeCompleteConsumer::Result *Results, - unsigned NumResults) { + CodeCompletionContext Context, + CodeCompleteConsumer::Result *Results, + unsigned NumResults) { std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult()); if (CodeCompleter) - CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults); + CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); for (unsigned I = 0; I != NumResults; ++I) Results[I].Destroy(); } +static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, + Sema::ParserCompletionContext PCC) { + switch (PCC) { + case Action::PCC_Namespace: + return CodeCompletionContext::CCC_TopLevel; + + case Action::PCC_Class: + return CodeCompletionContext::CCC_ClassStructUnion; + + case Action::PCC_ObjCInterface: + return CodeCompletionContext::CCC_ObjCInterface; + + case Action::PCC_ObjCImplementation: + return CodeCompletionContext::CCC_ObjCImplementation; + + case Action::PCC_ObjCInstanceVariableList: + return CodeCompletionContext::CCC_ObjCIvarList; + + case Action::PCC_Template: + case Action::PCC_MemberTemplate: + case Action::PCC_RecoveryInFunction: + return CodeCompletionContext::CCC_Other; + + case Action::PCC_Expression: + case Action::PCC_ForInit: + case Action::PCC_Condition: + return CodeCompletionContext::CCC_Expression; + + case Action::PCC_Statement: + return CodeCompletionContext::CCC_Statement; + } + + return CodeCompletionContext::CCC_Other; +} + void Sema::CodeCompleteOrdinaryName(Scope *S, - CodeCompletionContext CompletionContext) { + ParserCompletionContext CompletionContext) { typedef CodeCompleteConsumer::Result Result; ResultBuilder Results(*this); @@ -2246,27 +2282,27 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, // values (functions, enumerators, function templates, etc.) are // only allowed where we can have an expression. switch (CompletionContext) { - case CCC_Namespace: - case CCC_Class: - case CCC_ObjCInterface: - case CCC_ObjCImplementation: - case CCC_ObjCInstanceVariableList: - case CCC_Template: - case CCC_MemberTemplate: + case PCC_Namespace: + case PCC_Class: + case PCC_ObjCInterface: + case PCC_ObjCImplementation: + case PCC_ObjCInstanceVariableList: + case PCC_Template: + case PCC_MemberTemplate: Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); break; - case CCC_Expression: - case CCC_Statement: - case CCC_ForInit: - case CCC_Condition: + case PCC_Expression: + case PCC_Statement: + case PCC_ForInit: + case PCC_Condition: if (WantTypesInContext(CompletionContext, getLangOptions())) Results.setFilter(&ResultBuilder::IsOrdinaryName); else Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); break; - case CCC_RecoveryInFunction: + case PCC_RecoveryInFunction: // Unfiltered break; } @@ -2280,7 +2316,9 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, if (CodeCompleter->includeMacros()) AddMacroResults(PP, Results); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + mapCodeCompletionContext(*this, CompletionContext), + Results.data(),Results.size()); } /// \brief Perform code-completion in an expression context when we know what @@ -2295,7 +2333,7 @@ void Sema::CodeCompleteExpression(Scope *S, QualType T, if (IntegralConstantExpression) Results.setFilter(&ResultBuilder::IsIntegralConstantValue); - else if (WantTypesInContext(CCC_Expression, getLangOptions())) + else if (WantTypesInContext(PCC_Expression, getLangOptions())) Results.setFilter(&ResultBuilder::IsOrdinaryName); else Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); @@ -2305,7 +2343,7 @@ void Sema::CodeCompleteExpression(Scope *S, QualType T, LookupVisibleDecls(S, LookupOrdinaryName, Consumer); Results.EnterNewScope(); - AddOrdinaryNameResults(CCC_Expression, S, *this, Results); + AddOrdinaryNameResults(PCC_Expression, S, *this, Results); Results.ExitScope(); bool PreferredTypeIsPointer = false; @@ -2315,7 +2353,9 @@ void Sema::CodeCompleteExpression(Scope *S, QualType T, if (CodeCompleter->includeMacros()) AddMacroResults(PP, Results, PreferredTypeIsPointer); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Expression, + Results.data(),Results.size()); } @@ -2449,7 +2489,10 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE, Results.ExitScope(); // Hand off the results found for code completion. - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess, + BaseType), + Results.data(),Results.size()); } void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { @@ -2458,18 +2501,23 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { typedef CodeCompleteConsumer::Result Result; ResultBuilder::LookupFilter Filter = 0; + enum CodeCompletionContext::Kind ContextKind + = CodeCompletionContext::CCC_Other; switch ((DeclSpec::TST)TagSpec) { case DeclSpec::TST_enum: Filter = &ResultBuilder::IsEnum; + ContextKind = CodeCompletionContext::CCC_EnumTag; break; case DeclSpec::TST_union: Filter = &ResultBuilder::IsUnion; + ContextKind = CodeCompletionContext::CCC_UnionTag; break; case DeclSpec::TST_struct: case DeclSpec::TST_class: Filter = &ResultBuilder::IsClassOrStruct; + ContextKind = CodeCompletionContext::CCC_ClassOrStructTag; break; default: @@ -2488,7 +2536,8 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { Results.setFilter(&ResultBuilder::IsNestedNameSpecifier); LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, ContextKind, + Results.data(),Results.size()); } void Sema::CodeCompleteCase(Scope *S) { @@ -2570,7 +2619,9 @@ void Sema::CodeCompleteCase(Scope *S) { if (CodeCompleter->includeMacros()) AddMacroResults(PP, Results); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Expression, + Results.data(),Results.size()); } namespace { @@ -2616,7 +2667,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, // Ignore type-dependent call expressions entirely. if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) || Expr::hasAnyTypeDependentArguments(Args, NumArgs)) { - CodeCompleteOrdinaryName(S, CCC_Expression); + CodeCompleteOrdinaryName(S, PCC_Expression); return; } @@ -2700,7 +2751,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, } if (ParamType.isNull()) - CodeCompleteOrdinaryName(S, CCC_Expression); + CodeCompleteOrdinaryName(S, PCC_Expression); else CodeCompleteExpression(S, ParamType); @@ -2712,7 +2763,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) { ValueDecl *VD = dyn_cast_or_null(D.getAs()); if (!VD) { - CodeCompleteOrdinaryName(S, CCC_Expression); + CodeCompleteOrdinaryName(S, PCC_Expression); return; } @@ -2730,7 +2781,7 @@ void Sema::CodeCompleteReturn(Scope *S) { ResultType = Method->getResultType(); if (ResultType.isNull()) - CodeCompleteOrdinaryName(S, CCC_Expression); + CodeCompleteOrdinaryName(S, PCC_Expression); else CodeCompleteExpression(S, ResultType); } @@ -2739,7 +2790,7 @@ void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) { if (LHS) CodeCompleteExpression(S, static_cast(LHS)->getType()); else - CodeCompleteOrdinaryName(S, CCC_Expression); + CodeCompleteOrdinaryName(S, PCC_Expression); } void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, @@ -2766,7 +2817,9 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, if (!Results.empty() && NNS->isDependent()) Results.AddResult("template"); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteUsing(Scope *S) { @@ -2786,7 +2839,9 @@ void Sema::CodeCompleteUsing(Scope *S) { LookupVisibleDecls(S, LookupOrdinaryName, Consumer); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteUsingDirective(Scope *S) { @@ -2800,7 +2855,9 @@ void Sema::CodeCompleteUsingDirective(Scope *S) { CodeCompletionDeclConsumer Consumer(Results, CurContext); LookupVisibleDecls(S, LookupOrdinaryName, Consumer); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteNamespaceDecl(Scope *S) { @@ -2834,7 +2891,9 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) { Results.ExitScope(); } - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { @@ -2845,7 +2904,9 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias); CodeCompletionDeclConsumer Consumer(Results, CurContext); LookupVisibleDecls(S, LookupOrdinaryName, Consumer); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteOperatorName(Scope *S) { @@ -2871,7 +2932,9 @@ void Sema::CodeCompleteOperatorName(Scope *S) { AddTypeSpecifierResults(getLangOptions(), Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } // Macro that expands to @Keyword or Keyword, depending on whether NeedAt is @@ -2980,7 +3043,9 @@ void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl, else AddObjCTopLevelResults(Results, false); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { @@ -3076,7 +3141,9 @@ void Sema::CodeCompleteObjCAtVisibility(Scope *S) { Results.EnterNewScope(); AddObjCVisibilityResults(getLangOptions(), Results, false); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCAtStatement(Scope *S) { @@ -3085,7 +3152,9 @@ void Sema::CodeCompleteObjCAtStatement(Scope *S) { AddObjCStatementResults(Results, false); AddObjCExpressionResults(Results, false); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCAtExpression(Scope *S) { @@ -3093,7 +3162,9 @@ void Sema::CodeCompleteObjCAtExpression(Scope *S) { Results.EnterNewScope(); AddObjCExpressionResults(Results, false); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } /// \brief Determine whether the addition of the given flag to an Objective-C @@ -3162,7 +3233,9 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { Results.AddResult(CodeCompleteConsumer::Result(Getter)); } Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } /// \brief Descripts the kind of Objective-C method that we want to find @@ -3316,7 +3389,9 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl, AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl, @@ -3356,7 +3431,9 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl, AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } /// \brief When we have an expression with type "id", we may assume @@ -3450,7 +3527,9 @@ void Sema::CodeCompleteObjCMessageReceiver(Scope *S) { if (CodeCompleter->includeMacros()) AddMacroResults(PP, Results); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_ObjCMessageReceiver, + Results.data(), Results.size()); } @@ -3575,7 +3654,9 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver, } Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, @@ -3674,7 +3755,9 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, } Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } /// \brief Add all of the protocol declarations that we find in the given @@ -3722,7 +3805,9 @@ void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_ObjCProtocolName, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCProtocolDecl(Scope *) { @@ -3734,7 +3819,9 @@ void Sema::CodeCompleteObjCProtocolDecl(Scope *) { Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_ObjCProtocolName, + Results.data(),Results.size()); } /// \brief Add all of the Objective-C interface declarations that we find in @@ -3775,7 +3862,9 @@ void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { false, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, @@ -3794,7 +3883,9 @@ void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, false, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { @@ -3806,7 +3897,9 @@ void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { true, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, @@ -3837,7 +3930,9 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, Results.AddResult(Result(Category, 0), CurContext, 0, false); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCImplementationCategory(Scope *S, @@ -3874,7 +3969,9 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S, } Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) { @@ -3907,7 +4004,9 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) { false, CurContext, Results); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, @@ -3945,7 +4044,9 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, } Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } typedef llvm::DenseMap KnownMethodsMap; @@ -4059,7 +4160,9 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, } if (!SearchDecl || !CurrentDecl) { - HandleCodeCompleteResults(this, CodeCompleter, 0, 0); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + 0, 0); return; } @@ -4163,7 +4266,9 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, @@ -4227,5 +4332,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, } Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, + CodeCompletionContext::CCC_Other, + Results.data(),Results.size()); } diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp index c0a072760e13..813f82a4ccc2 100644 --- a/clang/tools/libclang/CIndexCodeCompletion.cpp +++ b/clang/tools/libclang/CIndexCodeCompletion.cpp @@ -557,7 +557,9 @@ namespace { explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results) : CodeCompleteConsumer(true, false, false), AllocatedResults(Results) { } - virtual void ProcessCodeCompleteResults(Sema &S, Result *Results, + virtual void ProcessCodeCompleteResults(Sema &S, + CodeCompletionContext Context, + Result *Results, unsigned NumResults) { AllocatedResults.Results = new CXCompletionResult [NumResults]; AllocatedResults.NumResults = NumResults;