[modules] Before marking the module imported 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 (these come from different modules):
   \#define LONG_MAX __LONG_MAX__ (clang's limits.h)
   \#define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
in which case don't mark them ambiguous to avoid the "ambiguous macro expansion" warning.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178109 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 649b4fc..55e333a 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1481,8 +1481,9 @@
 
   // 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.
@@ -1496,7 +1497,7 @@
   }
 
   if (!Hidden)
-    installImportedMacro(II, MD);
+    installImportedMacro(II, MD, Owner);
 }
 
 void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
@@ -1561,17 +1562,62 @@
   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);
+      }
     }
   }
   
@@ -2718,7 +2764,7 @@
   }
 }
 
-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: {
@@ -2735,7 +2781,7 @@
     }
     case HiddenName::MacroVisibility: {
       std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
-      installImportedMacro(Macro.first, Macro.second);
+      installImportedMacro(Macro.first, Macro.second, Owner);
       break;
     }
     }
@@ -2771,7 +2817,7 @@
     // 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);
     }
     
@@ -3266,7 +3312,7 @@
   for (HiddenNamesMapType::iterator Hidden = HiddenNamesMap.begin(),
                                  HiddenEnd = HiddenNamesMap.end();
        Hidden != HiddenEnd; ++Hidden) {
-    makeNamesVisible(Hidden->second);
+    makeNamesVisible(Hidden->second, Hidden->first);
   }
   HiddenNamesMap.clear();
 }