[libclang] Support code-completion inside macro arguments.

llvm-svn: 137973
This commit is contained in:
Argyrios Kyrtzidis 2011-08-18 19:41:28 +00:00
parent 74acf9f501
commit 75f6cd2b79
4 changed files with 45 additions and 4 deletions

View File

@ -52,6 +52,10 @@ public:
/// \brief Callback invoked when performing code completion inside a
/// function-like macro argument.
///
/// There will be another callback invocation after the macro arguments are
/// parsed, so this callback should generally be used to note that the next
/// callback is invoked inside a macro argument.
virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
MacroInfo *MacroInfo,
unsigned ArgumentIndex) { }

View File

@ -358,7 +358,23 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
if (CodeComplete)
CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),
MI, NumActuals);
LexUnexpandedToken(Tok);
// Add the code-completion token and finish the lexing normally so that
// normal code-completion occurs again with the expanded tokens.
ArgTokens.push_back(Tok);
// Add a marker EOF token to the end of the token list.
Token EOFTok;
EOFTok.startToken();
EOFTok.setKind(tok::eof);
EOFTok.setLocation(Tok.getLocation());
EOFTok.setLength(0);
ArgTokens.push_back(EOFTok);
++NumActuals;
// "Fill out" the other arguments.
for (; NumActuals < MI->getNumArgs(); ++NumActuals)
ArgTokens.push_back(EOFTok);
return MacroArgs::create(MI, ArgTokens.data(), ArgTokens.size(),
/*isVarargsElided=*/false, *this);
}
if (Tok.is(tok::eof) || Tok.is(tok::eod)) { // "#if f(<eof>" & "#if f(\n"

View File

@ -6857,9 +6857,8 @@ void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
// FIXME: In the future, we could provide "overload" results, much like we
// do for function calls.
CodeCompleteOrdinaryName(S,
S->getFnParent()? Sema::PCC_RecoveryInFunction
: Sema::PCC_Namespace);
// Now just ignore this. There will be another code-completion callback
// for the expanded tokens.
}
void Sema::CodeCompleteNaturalLanguage() {

View File

@ -0,0 +1,22 @@
struct Point {
float x;
float y;
float z;
};
#define MACRO2(x) x
#define MACRO(x) MACRO2(x)
void test(struct Point *p) {
p->x;
MACRO(p->x);
}
// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck %s
// RUN: c-index-test -code-completion-at=%s:12:12 %s | FileCheck %s
// CHECK: FieldDecl:{ResultType float}{TypedText x} (35)
// CHECK-NEXT: FieldDecl:{ResultType float}{TypedText y} (35)
// CHECK-NEXT: FieldDecl:{ResultType float}{TypedText z} (35)
// CHECK-NEXT: Completion contexts:
// CHECK-NEXT: Arrow member access
// CHECK-NEXT: Container Kind: StructDecl