diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 055008fd44ce65d6a02e88c51d81330ce4c62c02..737a1526505d0376e472f4aa548d1eb0aaeee9ab 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -254,6 +254,15 @@ class Preprocessor : public RefCountedBase { /// 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 DelayedMacroExpandsCallbacks; + /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping /// to the actual definition of the macro. llvm::DenseMap Macros; diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 50388687dcccf94843b8c1f38cd51d0c3144662d..9cb9ed60612472d40837fae3b97e6f471786d5a0 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -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. diff --git a/clang/test/Preprocessor/pp-record.c b/clang/test/Preprocessor/pp-record.c index f098683eeaa89e58ab66803fb1a40525392f8c71..dd958d0e56d1966b2bf8fd5ef0b55b8e2320ebe7 100644 --- a/clang/test/Preprocessor/pp-record.c +++ b/clang/test/Preprocessor/pp-record.c @@ -10,3 +10,14 @@ #include STRINGIZE(INC) CAKE; + +#define DIR 1 +#define FNM(x) x + +FNM( +#if DIR + int a; +#else + int b; +#endif +)