[cfe-commits] r170980 - in /cfe/trunk: lib/Lex/PPLexerChange.cpp lib/Lex/PPMacroExpansion.cpp test/Index/complete-macro-args.c

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Dec 21 20:48:11 PST 2012


Author: akirtzidis
Date: Fri Dec 21 22:48:10 2012
New Revision: 170980

URL: http://llvm.org/viewvc/llvm-project?rev=170980&view=rev
Log:
[libclang] Fix crash when code-completing a macro invocation that
reached EOF and did not expand the argument into the source context.

Modified:
    cfe/trunk/lib/Lex/PPLexerChange.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/test/Index/complete-macro-args.c

Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=170980&r1=170979&r2=170980&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Fri Dec 21 22:48:10 2012
@@ -158,15 +158,17 @@
 /// tokens from it instead of the current buffer.
 void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd,
                               MacroInfo *Macro, MacroArgs *Args) {
-  PushIncludeMacroStack();
-  CurDirLookup = 0;
-
+  TokenLexer *TokLexer;
   if (NumCachedTokenLexers == 0) {
-    CurTokenLexer.reset(new TokenLexer(Tok, ILEnd, Macro, Args, *this));
+    TokLexer = new TokenLexer(Tok, ILEnd, Macro, Args, *this);
   } else {
-    CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
-    CurTokenLexer->Init(Tok, ILEnd, Macro, Args);
+    TokLexer = TokenLexerCache[--NumCachedTokenLexers];
+    TokLexer->Init(Tok, ILEnd, Macro, Args);
   }
+
+  PushIncludeMacroStack();
+  CurDirLookup = 0;
+  CurTokenLexer.reset(TokLexer);
   if (CurLexerKind != CLK_LexAfterModuleImport)
     CurLexerKind = CLK_TokenLexer;
 }
@@ -186,18 +188,20 @@
 void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,
                                     bool DisableMacroExpansion,
                                     bool OwnsTokens) {
-  // Save our current state.
-  PushIncludeMacroStack();
-  CurDirLookup = 0;
-
   // Create a macro expander to expand from the specified token stream.
+  TokenLexer *TokLexer;
   if (NumCachedTokenLexers == 0) {
-    CurTokenLexer.reset(new TokenLexer(Toks, NumToks, DisableMacroExpansion,
-                                       OwnsTokens, *this));
+    TokLexer = new TokenLexer(Toks, NumToks, DisableMacroExpansion,
+                              OwnsTokens, *this);
   } else {
-    CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
-    CurTokenLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
+    TokLexer = TokenLexerCache[--NumCachedTokenLexers];
+    TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
   }
+
+  // Save our current state.
+  PushIncludeMacroStack();
+  CurDirLookup = 0;
+  CurTokenLexer.reset(TokLexer);
   if (CurLexerKind != CLK_LexAfterModuleImport)
     CurLexerKind = CLK_TokenLexer;
 }
@@ -328,6 +332,17 @@
     CurLexer->BufferPtr = EndPos;
     CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);
 
+    if (isCodeCompletionEnabled()) {
+      // Inserting the code-completion point increases the source buffer by 1,
+      // but the main FileID was created before inserting the point.
+      // Compensate by reducing the EOF location by 1, otherwise the location
+      // will point to the next FileID.
+      // FIXME: This is hacky, the code-completion point should probably be
+      // inserted before the main FileID is created.
+      if (CurLexer->getFileLoc() == CodeCompletionFileLoc)
+        Result.setLocation(Result.getLocation().getLocWithOffset(-1));
+    }
+
     if (!isIncrementalProcessingEnabled())
       // We're done with lexing.
       CurLexer.reset();

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=170980&r1=170979&r2=170980&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Dec 21 22:48:10 2012
@@ -528,6 +528,10 @@
           MacroName = Tok;
           return 0;
         } else {
+          // Do not lose the EOF/EOD.
+          Token *Toks = new Token[1];
+          Toks[0] = Tok;
+          EnterTokenStream(Toks, 1, true, true);
           break;
         }
       } else if (Tok.is(tok::r_paren)) {

Modified: cfe/trunk/test/Index/complete-macro-args.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-macro-args.c?rev=170980&r1=170979&r2=170980&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-macro-args.c (original)
+++ cfe/trunk/test/Index/complete-macro-args.c Fri Dec 21 22:48:10 2012
@@ -14,11 +14,25 @@
 
 #define MACRO3(x,y,z) x;y;z
 
-void test(struct Point *p) {
+void test2(struct Point *p) {
   MACRO3(p->x);
   MACRO3(p->x
 }
 
+#define VGM(...) 0
+#define VGM2(...) __VA_ARGS__
+
+// These need to be last, to test proper handling of EOF.
+#ifdef EOF_TEST1
+void test3(struct Point *p) {
+  VGM(1,2, p->x
+
+#elif EOF_TEST2
+void test3(struct Point *p) {
+  VGM2(VGM(1,2, p->x
+
+#endif
+
 // 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
 // RUN: c-index-test -code-completion-at=%s:18:13 %s | FileCheck %s
@@ -29,3 +43,10 @@
 // CHECK-NEXT: Completion contexts:
 // CHECK-NEXT: Arrow member access
 // CHECK-NEXT: Container Kind: StructDecl
+
+// With these, code-completion is unknown because the macro argument (and the
+// completion point) is not expanded by the macro definition.
+// RUN: c-index-test -code-completion-at=%s:28:15 %s -DEOF_TEST1 | FileCheck %s -check-prefix=CHECK-EOF
+// RUN: c-index-test -code-completion-at=%s:32:20 %s -DEOF_TEST2 | FileCheck %s -check-prefix=CHECK-EOF
+// CHECK-EOF: Completion contexts:
+// CHECK-EOF: Unknown





More information about the cfe-commits mailing list