diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 3 | ||||
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 36 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 4 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 3 |
4 files changed, 32 insertions, 14 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index b27c06a19c..fce3d33780 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -991,7 +991,8 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, // If the current macro definition is the same as the predefined macro // definition, it's okay. if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() || - LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP)) + LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP, + /*Syntactically=*/true)) return; // The macro definitions differ. diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index dc091f625b..5abafe1cb7 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -61,11 +61,17 @@ unsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const { return DefinitionLength; } -// isIdenticalTo - Return true if the specified macro definition is equal to -// this macro in spelling, arguments, and whitespace. This is used to emit -// duplicate definition warnings. This implements the rules in C99 6.10.3. -// -bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const { +/// \brief Return true if the specified macro definition is equal to +/// this macro in spelling, arguments, and whitespace. +/// +/// \param Syntactically if true, the macro definitions can be identical even +/// if they use different identifiers for the function macro parameters. +/// Otherwise the comparison is lexical and this implements the rules in +/// C99 6.10.3. +bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, + bool Syntactically) const { + bool Lexically = !Syntactically; + // Check # tokens in replacement, number of args, and various flags all match. if (ReplacementTokens.size() != Other.ReplacementTokens.size() || getNumArgs() != Other.getNumArgs() || @@ -74,10 +80,12 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const { isGNUVarargs() != Other.isGNUVarargs()) return false; - // Check arguments. - for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end(); - I != E; ++I, ++OI) - if (*I != *OI) return false; + if (Lexically) { + // Check arguments. + for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end(); + I != E; ++I, ++OI) + if (*I != *OI) return false; + } // Check all the tokens. for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) { @@ -95,7 +103,15 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const { // If this is an identifier, it is easy. if (A.getIdentifierInfo() || B.getIdentifierInfo()) { - if (A.getIdentifierInfo() != B.getIdentifierInfo()) + if (A.getIdentifierInfo() == B.getIdentifierInfo()) + continue; + if (Lexically) + return false; + // With syntactic equivalence the parameter names can be different as long + // as they are used in the same place. + int AArgNum = getArgumentNum(A.getIdentifierInfo()); + int BArgNum = Other.getArgumentNum(B.getIdentifierInfo()); + if (AArgNum == -1 || AArgNum != BArgNum) return false; continue; } diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 3fc19e41f8..07c1867010 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -1949,9 +1949,9 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { if (OtherMI->isBuiltinMacro()) Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro); // Macros must be identical. This means all tokens and whitespace - // separation must be the same. C99 6.10.3.2. + // separation must be the same. C99 6.10.3p2. else if (!OtherMI->isAllowRedefinitionsWithoutWarning() && - !MI->isIdenticalTo(*OtherMI, *this)) { + !MI->isIdenticalTo(*OtherMI, *this, /*Syntactic=*/LangOpts.MicrosoftExt)) { Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef) << MacroNameTok.getIdentifierInfo(); Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 4c2d2197e4..4c4277c30f 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1604,7 +1604,8 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD, MacroDirective::DefInfo PrevDef = Prev->getDefinition(); MacroInfo *PrevMI = PrevDef.getMacroInfo(); MacroInfo *NewMI = DefMD->getInfo(); - if (NewMI != PrevMI && !PrevMI->isIdenticalTo(*NewMI, PP)) { + if (NewMI != PrevMI && !PrevMI->isIdenticalTo(*NewMI, PP, + /*Syntactically=*/true)) { // Before marking the macros as ambiguous, check if this is a case where // the system macro uses a not identical definition compared to a macro // from the clang headers. For example: |