]> granicus.if.org Git - clang/commitdiff
[libclang] Support code-completion inside macro arguments.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 18 Aug 2011 19:41:28 +0000 (19:41 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 18 Aug 2011 19:41:28 +0000 (19:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137973 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/CodeCompletionHandler.h
lib/Lex/PPMacroExpansion.cpp
lib/Sema/SemaCodeComplete.cpp
test/Index/complete-macro-args.c [new file with mode: 0644]

index d28a3aa7d6309d1e108c10503f73ead18501e8fe..d876776c927c11adb1cba31b6b64b8da767e417d 100644 (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) { }
index eaab73edc444dc296c28612f966de6254035bd12..fd5b4c2efa28a552efee66fc69e93743c72db87b 100644 (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"
index cff9d6b4a94061d94afec65a6712face81bc4b38..858a001d439d00a13cd5d050dd7bff475e64287a 100644 (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() {
diff --git a/test/Index/complete-macro-args.c b/test/Index/complete-macro-args.c
new file mode 100644 (file)
index 0000000..ca36af1
--- /dev/null
@@ -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