aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Lex/MacroInfo.cpp6
-rw-r--r--lib/Lex/PPMacroExpansion.cpp36
-rw-r--r--lib/Serialization/ASTReader.cpp23
3 files changed, 56 insertions, 9 deletions
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 7e538fabf4..904f04e4f8 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -32,7 +32,8 @@ MacroInfo::MacroInfo(SourceLocation DefLoc)
IsAllowRedefinitionsWithoutWarning(false),
IsWarnIfUnused(false),
IsPublic(true),
- IsHidden(false) {
+ IsHidden(false),
+ IsAmbiguous(false) {
}
MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator)
@@ -56,7 +57,8 @@ MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator)
IsAllowRedefinitionsWithoutWarning(MI.IsAllowRedefinitionsWithoutWarning),
IsWarnIfUnused(MI.IsWarnIfUnused),
IsPublic(MI.IsPublic),
- IsHidden(MI.IsHidden) {
+ IsHidden(MI.IsHidden),
+ IsAmbiguous(MI.IsAmbiguous) {
setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator);
}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index c717816650..dc3a45652a 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -89,15 +89,25 @@ void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI,
// Find the end of the definition chain.
MacroInfo *Prev = StoredMI;
MacroInfo *PrevPrev;
- bool Ambiguous = false;
+ bool Ambiguous = StoredMI->isAmbiguous();
+ bool MatchedOther = false;
do {
// If the macros are not identical, we have an ambiguity.
- if (!Prev->isIdenticalTo(*MI, *this))
- Ambiguous = true;
+ if (!Prev->isIdenticalTo(*MI, *this)) {
+ if (!Ambiguous) {
+ Ambiguous = true;
+ StoredMI->setAmbiguous(true);
+ }
+ } else {
+ MatchedOther = true;
+ }
} while ((PrevPrev = Prev->getPreviousDefinition()) &&
PrevPrev->isDefined());
- // FIXME: Actually use the ambiguity information for something.
+ // If there are ambiguous definitions, and we didn't match any other
+ // definition, then mark us as ambiguous.
+ if (Ambiguous && !MatchedOther)
+ MI->setAmbiguous(true);
// Wire this macro information into the chain.
MI->setPreviousDefinition(Prev->getPreviousDefinition());
@@ -360,7 +370,23 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
}
}
}
-
+
+ // If the macro definition is ambiguous, complain.
+ if (MI->isAmbiguous()) {
+ Diag(Identifier, diag::warn_pp_ambiguous_macro)
+ << Identifier.getIdentifierInfo();
+ Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen)
+ << Identifier.getIdentifierInfo();
+ for (MacroInfo *PrevMI = MI->getPreviousDefinition();
+ PrevMI && PrevMI->isDefined();
+ PrevMI = PrevMI->getPreviousDefinition()) {
+ if (PrevMI->isAmbiguous()) {
+ Diag(PrevMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other)
+ << Identifier.getIdentifierInfo();
+ }
+ }
+ }
+
// If we started lexing a macro, enter the macro expansion body.
// If this macro expands to no tokens, don't bother to push it onto the
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 5657ee23bc..8f18eb8465 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1254,6 +1254,24 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset,
SmallVector<IdentifierInfo*, 16> MacroArgs;
MacroInfo *Macro = 0;
+ // RAII object to add the loaded macro information once we're done
+ // adding tokens.
+ struct AddLoadedMacroInfoRAII {
+ Preprocessor &PP;
+ MacroInfo *Hint;
+ MacroInfo *MI;
+ IdentifierInfo *II;
+
+ AddLoadedMacroInfoRAII(Preprocessor &PP, MacroInfo *Hint)
+ : PP(PP), Hint(Hint), MI(), II() { }
+ ~AddLoadedMacroInfoRAII( ) {
+ if (MI) {
+ // Finally, install the macro.
+ PP.addLoadedMacroInfo(II, MI, Hint);
+ }
+ }
+ } AddLoadedMacroInfo(PP, Hint);
+
while (true) {
unsigned Code = Stream.ReadCode();
switch (Code) {
@@ -1370,8 +1388,9 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset,
}
MI->setHidden(Hidden);
- // Finally, install the macro.
- PP.addLoadedMacroInfo(II, MI, Hint);
+ // Make sure we install the macro once we're done.
+ AddLoadedMacroInfo.MI = MI;
+ AddLoadedMacroInfo.II = II;
// Remember that we saw this macro last so that we add the tokens that
// form its body to it.