summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-03 17:39:30 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-03 17:39:30 +0000
commit0c2f30b9d3cd040f943ba444954d0f626ac3f16d (patch)
tree1b8b761ac1ec67289024315f43fd81a9667ca35f /clang/lib
parent04e213b6b6fb14b8b20b83bf7fd4a4cddbbcb91c (diff)
downloadbcm5719-llvm-0c2f30b9d3cd040f943ba444954d0f626ac3f16d.tar.gz
bcm5719-llvm-0c2f30b9d3cd040f943ba444954d0f626ac3f16d.zip
[preprocessor] Allow comparing two macro definitions syntactically instead of only lexically.
Syntactically means the function macro parameter names do not need to use the same identifiers in order for the definitions to be considered identical. Syntactic equivalence is a microsoft extension for macro redefinitions and we'll also use this kind of comparison to check for ambiguous macros coming from modules. rdar://13562254 llvm-svn: 178671
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp3
-rw-r--r--clang/lib/Lex/MacroInfo.cpp36
-rw-r--r--clang/lib/Lex/PPDirectives.cpp4
-rw-r--r--clang/lib/Serialization/ASTReader.cpp3
4 files changed, 32 insertions, 14 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index b27c06a19c3..fce3d33780b 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/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/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp
index dc091f625b5..5abafe1cb76 100644
--- a/clang/lib/Lex/MacroInfo.cpp
+++ b/clang/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/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 3fc19e41f81..07c18670100 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/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/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 4c2d2197e49..4c4277c30fd 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/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:
OpenPOWER on IntegriCloud