[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
This commit is contained in:
Argyrios Kyrtzidis 2012-05-10 18:57:19 +00:00
Родитель 4abe3d3700
Коммит 66c44e700f
3 изменённых файлов: 40 добавлений и 2 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -242,9 +242,27 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// Remember where the token is expanded.
SourceLocation ExpandLoc = Identifier.getLocation();
SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
if (Callbacks) Callbacks->MacroExpands(Identifier, MI,
SourceRange(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.

Просмотреть файл

@ -10,3 +10,14 @@
#include STRINGIZE(INC)
CAKE;
#define DIR 1
#define FNM(x) x
FNM(
#if DIR
int a;
#else
int b;
#endif
)