// Determine whether this macro definition is visible.
bool Hidden = false;
+ Module *Owner = 0;
if (SubModID) {
- if (Module *Owner = getSubmodule(SubModID)) {
+ if ((Owner = getSubmodule(SubModID))) {
if (Owner->NameVisibility == Module::Hidden) {
// The owning module is not visible, and this macro definition
// should not be, either.
}
if (!Hidden)
- installImportedMacro(II, MD);
+ installImportedMacro(II, MD, Owner);
}
void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
PP.setLoadedMacroDirective(II, Latest);
}
-void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD) {
+/// \brief For the given macro definitions, check if they are both in system
+/// modules and if one of the two is in the clang builtin headers.
+static bool isSystemAndClangMacro(MacroInfo *PrevMI, MacroInfo *NewMI,
+ Module *NewOwner, ASTReader &Reader) {
+ assert(PrevMI && NewMI);
+ if (!NewOwner)
+ return false;
+ Module *PrevOwner = 0;
+ if (SubmoduleID PrevModID = PrevMI->getOwningModuleID())
+ PrevOwner = Reader.getSubmodule(PrevModID);
+ if (!PrevOwner)
+ return false;
+ if (PrevOwner == NewOwner)
+ return false;
+ if (!PrevOwner->IsSystem || !NewOwner->IsSystem)
+ return false;
+
+ SourceManager &SM = Reader.getSourceManager();
+ FileID PrevFID = SM.getFileID(PrevMI->getDefinitionLoc());
+ FileID NewFID = SM.getFileID(NewMI->getDefinitionLoc());
+ const FileEntry *PrevFE = SM.getFileEntryForID(PrevFID);
+ const FileEntry *NewFE = SM.getFileEntryForID(NewFID);
+ if (PrevFE == 0 || NewFE == 0)
+ return false;
+
+ Preprocessor &PP = Reader.getPreprocessor();
+ ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
+ const DirectoryEntry *BuiltinDir = ModMap.getBuiltinIncludeDir();
+
+ return (PrevFE->getDir() == BuiltinDir) != (NewFE->getDir() == BuiltinDir);
+}
+
+void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
+ Module *Owner) {
assert(II && MD);
DefMacroDirective *DefMD = cast<DefMacroDirective>(MD);
MacroDirective *Prev = PP.getMacroDirective(II);
if (Prev) {
MacroDirective::DefInfo PrevDef = Prev->getDefinition();
- if (DefMD->getInfo() != PrevDef.getMacroInfo() &&
- !PrevDef.getMacroInfo()->isIdenticalTo(*DefMD->getInfo(), PP)) {
- PrevDef.getDirective()->setAmbiguous(true);
- DefMD->setAmbiguous(true);
+ MacroInfo *PrevMI = PrevDef.getMacroInfo();
+ MacroInfo *NewMI = DefMD->getInfo();
+ if (NewMI != PrevMI && !PrevMI->isIdenticalTo(*NewMI, PP)) {
+ // 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:
+ // #define LONG_MAX __LONG_MAX__ (clang's limits.h)
+ // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
+ // in which case don't mark them to avoid the "ambiguous macro expansion"
+ // warning.
+ // FIXME: This should go away if the system headers get "fixed" to use
+ // identical definitions.
+ if (!isSystemAndClangMacro(PrevMI, NewMI, Owner, *this)) {
+ PrevDef.getDirective()->setAmbiguous(true);
+ DefMD->setAmbiguous(true);
+ }
}
}
}
}
-void ASTReader::makeNamesVisible(const HiddenNames &Names) {
+void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) {
for (unsigned I = 0, N = Names.size(); I != N; ++I) {
switch (Names[I].getKind()) {
case HiddenName::Declaration: {
}
case HiddenName::MacroVisibility: {
std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
- installImportedMacro(Macro.first, Macro.second);
+ installImportedMacro(Macro.first, Macro.second, Owner);
break;
}
}
// mark them as visible.
HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod);
if (Hidden != HiddenNamesMap.end()) {
- makeNamesVisible(Hidden->second);
+ makeNamesVisible(Hidden->second, Hidden->first);
HiddenNamesMap.erase(Hidden);
}
for (HiddenNamesMapType::iterator Hidden = HiddenNamesMap.begin(),
HiddenEnd = HiddenNamesMap.end();
Hidden != HiddenEnd; ++Hidden) {
- makeNamesVisible(Hidden->second);
+ makeNamesVisible(Hidden->second, Hidden->first);
}
HiddenNamesMap.clear();
}