aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-08-11 21:23:17 +0000
committerDouglas Gregor <dgregor@apple.com>2010-08-11 21:23:17 +0000
commite6b1bb6e7fe906d164637ca33503b8fafdbc99e5 (patch)
tree04d46dcc8dbdba7495c573d0ff6c373e754e6ce9
parent741c362a1cb4f3644d5a4e6b8eb9244799e4ade6 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110858 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Parse/Action.h28
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h91
-rw-r--r--lib/Parse/ParseDecl.cpp10
-rw-r--r--lib/Parse/ParseExpr.cpp4
-rw-r--r--lib/Parse/ParseExprCXX.cpp2
-rw-r--r--lib/Parse/ParseObjc.cpp6
-rw-r--r--lib/Parse/ParseStmt.cpp6
-rw-r--r--lib/Parse/Parser.cpp10
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp2
-rw-r--r--lib/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaCodeComplete.cpp301
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp4
12 files changed, 331 insertions, 135 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 9d8c5b1d1f..263dacb43d 100644
--- a/include/clang/Parse/Action.h
+++ b/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/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 1c679ebf86..5310b63477 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/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 <memory>
@@ -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/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 65b4fb77ad..b0d9da5845 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/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/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index ec92f0869e..844dd3f873 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/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/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 29f6bb9484..f5ade8a8fb 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/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/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index a7e08562d0..00df5a2c5a 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/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/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 1136be006f..a83aff182d 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/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/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index d0158871a9..4e0ae87234 100644
--- a/lib/Parse/Parser.cpp
+++ b/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/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 62e4abbbbb..a7eca6a804 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/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/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 6167668b86..02761ac234 100644
--- a/lib/Sema/Sema.h
+++ b/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/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 52ac8dd649..9a03caa688 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/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<ValueDecl>(D.getAs<Decl>());
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<Expr *>(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,
+ CodeCompletionConte