diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-05-10 18:57:19 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-05-10 18:57:19 +0000 |
commit | 66c44e700fb3f244b2c443bfbd6a05b5f1843ec0 (patch) | |
tree | 6a664593073ac1cefe450e010748337f97cfc0ec | |
parent | 4abe3d370050d73c3f7f4bff0d70154f53e619b5 (diff) |
[preprocessor] Make sure that MacroExpands callbacks are always in source order.
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
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 9 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 24 | ||||
-rw-r--r-- | test/Preprocessor/pp-record.c | 11 |
3 files changed, 41 insertions, 3 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 055008fd44..737a152650 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -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; diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 50388687dc..9cb9ed6061 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/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/test/Preprocessor/pp-record.c b/test/Preprocessor/pp-record.c index f098683eea..dd958d0e56 100644 --- a/test/Preprocessor/pp-record.c +++ b/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 +) |