]> granicus.if.org Git - clang/commitdiff
[preprocessor] Make sure that MacroExpands callbacks are always in source order.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 10 May 2012 18:57:19 +0000 (18:57 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 10 May 2012 18:57:19 +0000 (18:57 +0000)
Fixes assertion hit in the preprocessing record. rdar://11426523

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

include/clang/Lex/Preprocessor.h
lib/Lex/PPMacroExpansion.cpp
test/Preprocessor/pp-record.c

index 055008fd44ce65d6a02e88c51d81330ce4c62c02..737a1526505d0376e472f4aa548d1eb0aaeee9ab 100644 (file)
@@ -254,6 +254,15 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
   /// encountered (e.g. a file is #included, etc).
   PPCallbacks *Callbacks;
 
+  struct MacroExpandsInfo {
+    Token Tok;
+    MacroInfo *MI;
+    SourceRange Range;
+    MacroExpandsInfo(Token Tok, MacroInfo *MI, SourceRange Range)
+      : Tok(Tok), MI(MI), Range(Range) { }
+  };
+  SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
+
   /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping
   /// to the actual definition of the macro.
   llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
index 50388687dcccf94843b8c1f38cd51d0c3144662d..9cb9ed60612472d40837fae3b97e6f471786d5a0 100644 (file)
@@ -242,9 +242,27 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
 
   // Remember where the token is expanded.
   SourceLocation ExpandLoc = Identifier.getLocation();
-
-  if (Callbacks) Callbacks->MacroExpands(Identifier, MI,
-                                         SourceRange(ExpandLoc, ExpansionEnd));
+  SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
+
+  if (Callbacks) {
+    if (InMacroArgs) {
+      // We can have macro expansion inside a conditional directive while
+      // reading the function macro arguments. To ensure, in that case, that
+      // MacroExpands callbacks still happen in source order, queue this
+      // callback to have it happen after the function macro callback.
+      DelayedMacroExpandsCallbacks.push_back(
+                              MacroExpandsInfo(Identifier, MI, ExpansionRange));
+    } else {
+      Callbacks->MacroExpands(Identifier, MI, ExpansionRange);
+      if (!DelayedMacroExpandsCallbacks.empty()) {
+        for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
+          MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
+          Callbacks->MacroExpands(Info.Tok, Info.MI, Info.Range);
+        }
+        DelayedMacroExpandsCallbacks.clear();
+      }
+    }
+  }
   
   // If we started lexing a macro, enter the macro expansion body.
 
index f098683eeaa89e58ab66803fb1a40525392f8c71..dd958d0e56d1966b2bf8fd5ef0b55b8e2320ebe7 100644 (file)
 #include STRINGIZE(INC)
 
 CAKE;
+
+#define DIR 1
+#define FNM(x) x
+
+FNM(
+#if DIR
+    int a;
+#else
+    int b;
+#endif
+)