forked from OSchip/llvm-project
Code completion for ordinary names when we're starting a declaration, expression, or statement
llvm-svn: 82481
This commit is contained in:
parent
a74039426d
commit
9d64c5e3a5
|
@ -2192,9 +2192,19 @@ public:
|
|||
/// found at a point in the grammar where the Action implementation is
|
||||
/// likely to be able to provide a list of possible completions, e.g.,
|
||||
/// after the "." or "->" of a member access expression.
|
||||
///
|
||||
///
|
||||
/// \todo Code completion for designated field initializers
|
||||
/// \todo Code completion for call arguments after a function template-id
|
||||
/// \todo Code completion within a call expression, object construction, etc.
|
||||
/// \todo Code completion within a template argument list.
|
||||
//@{
|
||||
|
||||
/// \brief Code completion for an ordinary name that occurs within the given
|
||||
/// scope.
|
||||
///
|
||||
/// \param S the scope in which the name occurs.
|
||||
virtual void CodeCompleteOrdinaryName(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for a member access expression.
|
||||
///
|
||||
/// This code completion action is invoked when the code-completion token
|
||||
|
|
|
@ -710,6 +710,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
const ParsedTemplateInfo &TemplateInfo,
|
||||
AccessSpecifier AS,
|
||||
DeclSpecContext DSContext) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteOrdinaryName(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
DS.SetRangeStart(Tok.getLocation());
|
||||
while (1) {
|
||||
bool isInvalid = false;
|
||||
|
|
|
@ -200,6 +200,11 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
|
|||
/// expression ',' assignment-expression
|
||||
///
|
||||
Parser::OwningExprResult Parser::ParseExpression() {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteOrdinaryName(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
OwningExprResult LHS(ParseAssignmentExpression());
|
||||
if (LHS.isInvalid()) return move(LHS);
|
||||
|
||||
|
|
|
@ -90,6 +90,11 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
|||
return ParseObjCAtStatement(AtLoc);
|
||||
}
|
||||
|
||||
case tok::code_completion:
|
||||
Actions.CodeCompleteOrdinaryName(CurScope);
|
||||
ConsumeToken();
|
||||
return ParseStatementOrDeclaration(OnlyStatement);
|
||||
|
||||
case tok::identifier:
|
||||
if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
|
||||
// identifier ':' statement
|
||||
|
@ -918,6 +923,11 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
|
|||
OwningStmtResult FirstPart(Actions);
|
||||
OwningExprResult SecondPart(Actions), ThirdPart(Actions);
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteOrdinaryName(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
// Parse the first part of the for specifier.
|
||||
if (Tok.is(tok::semi)) { // for (;
|
||||
// no first part, eat the ';'.
|
||||
|
|
|
@ -442,6 +442,10 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() {
|
|||
}
|
||||
SingleDecl = ParseObjCMethodDefinition();
|
||||
break;
|
||||
case tok::code_completion:
|
||||
Actions.CodeCompleteOrdinaryName(CurScope);
|
||||
ConsumeToken();
|
||||
return ParseExternalDeclaration();
|
||||
case tok::kw_using:
|
||||
case tok::kw_namespace:
|
||||
case tok::kw_typedef:
|
||||
|
|
|
@ -3629,6 +3629,7 @@ public:
|
|||
/// \name Code completion
|
||||
//@{
|
||||
void setCodeCompleteConsumer(CodeCompleteConsumer *CCC);
|
||||
virtual void CodeCompleteOrdinaryName(Scope *S);
|
||||
virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
|
||||
SourceLocation OpLoc,
|
||||
bool IsArrow);
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace {
|
|||
/// results of name lookup. All of the predicates have the same type, so that
|
||||
///
|
||||
//@{
|
||||
bool IsOrdinaryName(NamedDecl *ND) const;
|
||||
bool IsNestedNameSpecifier(NamedDecl *ND) const;
|
||||
bool IsEnum(NamedDecl *ND) const;
|
||||
bool IsClassOrStruct(NamedDecl *ND) const;
|
||||
|
@ -316,6 +317,16 @@ void ResultBuilder::ExitScope() {
|
|||
ShadowMaps.pop_back();
|
||||
}
|
||||
|
||||
/// \brief Determines whether this given declaration will be found by
|
||||
/// ordinary name lookup.
|
||||
bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
|
||||
unsigned IDNS = Decl::IDNS_Ordinary;
|
||||
if (SemaRef.getLangOptions().CPlusPlus)
|
||||
IDNS |= Decl::IDNS_Tag;
|
||||
|
||||
return ND->getIdentifierNamespace() & IDNS;
|
||||
}
|
||||
|
||||
/// \brief Determines whether the given declaration is suitable as the
|
||||
/// start of a C++ nested-name-specifier, e.g., a class or namespace.
|
||||
bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
|
||||
|
@ -874,6 +885,13 @@ static void HandleCodeCompleteResults(CodeCompleteConsumer *CodeCompleter,
|
|||
CodeCompleter->ProcessCodeCompleteResults(Results, NumResults);
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteOrdinaryName(Scope *S) {
|
||||
ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
|
||||
CollectLookupResults(S, Context.getTranslationUnitDecl(), 0, CurContext,
|
||||
Results);
|
||||
HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
|
||||
SourceLocation OpLoc,
|
||||
bool IsArrow) {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
|
||||
// RUN: true
|
||||
|
||||
struct X { int x; };
|
||||
|
||||
typedef struct X TYPEDEF;
|
||||
|
||||
void foo() {
|
||||
int y;
|
||||
// CHECK-CC1: y : 0
|
||||
// CHECK-NEXT-CC1: TYPEDEF : 2
|
||||
// CHECK-NEXT-CC1: foo : 2
|
Loading…
Reference in New Issue