diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 36 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 23 |
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. |