]> granicus.if.org Git - clang/commitdiff
Fix assertion failures on annot_* tokens in clang -E
authorBen Langmuir <blangmuir@apple.com>
Thu, 30 Jan 2014 18:09:55 +0000 (18:09 +0000)
committerBen Langmuir <blangmuir@apple.com>
Thu, 30 Jan 2014 18:09:55 +0000 (18:09 +0000)
In particular, #pragma clang __debug, and #include implicitly changed
into @import were causing assertion failures.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200475 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/PrintPreprocessedOutput.cpp
lib/Lex/TokenConcatenation.cpp
test/Preprocessor/Inputs/a.h [new file with mode: 0644]
test/Preprocessor/Inputs/module.map [new file with mode: 0644]
test/Preprocessor/annot-tokens.m [new file with mode: 0644]

index f3393bfe51ce49fa103aee17fb1ef4d5d6551af6..834e5262c638e918650acfe4ffbdcf3b8625368e 100644 (file)
@@ -342,6 +342,7 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
     OS << "@import " << Imported->getFullModuleName() << ";"
        << " /* clang -E: implicit import for \"" << File->getName() << "\" */";
     EmittedTokensOnThisLine = true;
+    setEmittedDirectiveOnThisLine();
   }
 }
 
@@ -657,11 +658,9 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
       // -traditional-cpp the lexer keeps /all/ whitespace, including comments.
       SourceLocation StartLoc = Tok.getLocation();
       Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
-    } else if (Tok.is(tok::annot_module_include) ||
-               Tok.is(tok::annot_module_begin) ||
-               Tok.is(tok::annot_module_end)) {
-      // PrintPPOutputPPCallbacks::InclusionDirective handles producing
-      // appropriate output here. Ignore this token entirely.
+    } else if (Tok.isAnnotation()) {
+      // PrintPPOutputPPCallbacks handles producing appropriate output here.
+      // Ignore this token entirely.
       PP.Lex(Tok);
       continue;
     } else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
index 0a66bba91fcd8717b9dab598c45e2d87abdf5eae..9de28a875e774f9aa576ee2e90907f66d1ea1025 100644 (file)
@@ -163,8 +163,8 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
     return false;
 
   tok::TokenKind PrevKind = PrevTok.getKind();
-  if (PrevTok.getIdentifierInfo())  // Language keyword or named operator.
-    PrevKind = tok::identifier;
+  if (!PrevTok.isAnnotation() && PrevTok.getIdentifierInfo())
+    PrevKind = tok::identifier; // Language keyword or named operator.
 
   // Look up information on when we should avoid concatenation with prevtok.
   unsigned ConcatInfo = TokenInfo[PrevKind];
@@ -212,7 +212,7 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
 
     // In C++11, a string or character literal followed by an identifier is a
     // single token.
-    if (Tok.getIdentifierInfo())
+    if (!Tok.isAnnotation() && Tok.getIdentifierInfo())
       return true;
 
     // A ud-suffix is an identifier. If the previous token ends with one, treat
@@ -225,6 +225,9 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
     if (Tok.is(tok::numeric_constant))
       return GetFirstChar(PP, Tok) != '.';
 
+    if (Tok.isAnnotation()) // token will be put on its own line.
+      return false;
+
     if (Tok.getIdentifierInfo() || Tok.is(tok::wide_string_literal) ||
         Tok.is(tok::utf8_string_literal) || Tok.is(tok::utf16_string_literal) ||
         Tok.is(tok::utf32_string_literal) || Tok.is(tok::wide_char_constant) ||
diff --git a/test/Preprocessor/Inputs/a.h b/test/Preprocessor/Inputs/a.h
new file mode 100644 (file)
index 0000000..8b1a393
--- /dev/null
@@ -0,0 +1 @@
+// empty
diff --git a/test/Preprocessor/Inputs/module.map b/test/Preprocessor/Inputs/module.map
new file mode 100644 (file)
index 0000000..a967657
--- /dev/null
@@ -0,0 +1,4 @@
+module a {
+  header "a.h"
+  export *
+}
diff --git a/test/Preprocessor/annot-tokens.m b/test/Preprocessor/annot-tokens.m
new file mode 100644 (file)
index 0000000..c5312ee
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -E %s -fmodules -fmodules-cache-path=%t -I%S/Inputs | FileCheck %s
+// CHECK: @import a; /* clang -E: implicit import
+#include "a.h"
+// CHECK: #pragma clang __debug parser_crash
+#pragma clang __debug parser_crash