]> granicus.if.org Git - clang/commitdiff
[modules] If we have a choice between including a file textually and importing
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 13 Feb 2015 23:50:20 +0000 (23:50 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 13 Feb 2015 23:50:20 +0000 (23:50 +0000)
a prebuilt form from a module, prefer the modular form, all else being equal.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@229188 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/ModuleMap.cpp
test/Modules/Inputs/header-in-multiple-maps/a.h [new file with mode: 0644]
test/Modules/Inputs/header-in-multiple-maps/map1 [new file with mode: 0644]
test/Modules/Inputs/header-in-multiple-maps/map2 [new file with mode: 0644]
test/Modules/Inputs/header-in-multiple-maps/map3 [new file with mode: 0644]
test/Modules/header-in-multiple-maps.cpp [new file with mode: 0644]

index ef322d8cdc4c1191faad8ce1c3dd6b7ab4a20238..529c971ff528bbbeb2dd5ec9cf46a0810f829012 100644 (file)
@@ -314,6 +314,22 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
   }
 }
 
+static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
+                                const ModuleMap::KnownHeader &Old) {
+  // Prefer a public header over a private header.
+  if ((New.getRole() & ModuleMap::PrivateHeader) !=
+      (Old.getRole() & ModuleMap::PrivateHeader))
+    return !(New.getRole() & ModuleMap::PrivateHeader);
+
+  // Prefer a non-textual header over a textual header.
+  if ((New.getRole() & ModuleMap::TextualHeader) !=
+      (Old.getRole() & ModuleMap::TextualHeader))
+    return !(New.getRole() & ModuleMap::TextualHeader);
+
+  // Don't have a reason to choose between these. Just keep the first one.
+  return false;
+}
+
 ModuleMap::KnownHeader
 ModuleMap::findModuleForHeader(const FileEntry *File,
                                Module *RequestingModule,
@@ -348,8 +364,7 @@ ModuleMap::findModuleForHeader(const FileEntry *File,
           !directlyUses(RequestingModule, I->getModule()))
         continue;
 
-      // Prefer a public header over a private header.
-      if (!Result || (Result.getRole() & ModuleMap::PrivateHeader))
+      if (!Result || isBetterKnownHeader(*I, Result))
         Result = *I;
     }
     return MakeResult(Result);
diff --git a/test/Modules/Inputs/header-in-multiple-maps/a.h b/test/Modules/Inputs/header-in-multiple-maps/a.h
new file mode 100644 (file)
index 0000000..4c5cd94
--- /dev/null
@@ -0,0 +1 @@
+struct A {};
diff --git a/test/Modules/Inputs/header-in-multiple-maps/map1 b/test/Modules/Inputs/header-in-multiple-maps/map1
new file mode 100644 (file)
index 0000000..ba9baac
--- /dev/null
@@ -0,0 +1,3 @@
+module a { header "a.h" }
+module b { header "a.h" }
+module c { textual header "a.h" }
diff --git a/test/Modules/Inputs/header-in-multiple-maps/map2 b/test/Modules/Inputs/header-in-multiple-maps/map2
new file mode 100644 (file)
index 0000000..67e0df3
--- /dev/null
@@ -0,0 +1,3 @@
+module a { textual header "a.h" }
+module b { header "a.h" }
+module c { header "a.h" }
diff --git a/test/Modules/Inputs/header-in-multiple-maps/map3 b/test/Modules/Inputs/header-in-multiple-maps/map3
new file mode 100644 (file)
index 0000000..c859fd7
--- /dev/null
@@ -0,0 +1,3 @@
+module a { header "a.h" }
+module b { textual header "a.h" }
+module c { header "a.h" }
diff --git a/test/Modules/header-in-multiple-maps.cpp b/test/Modules/header-in-multiple-maps.cpp
new file mode 100644 (file)
index 0000000..a9c0c80
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/header-in-multiple-maps -fmodule-map-file=%S/Inputs/header-in-multiple-maps/map1 -verify %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/header-in-multiple-maps -fmodule-map-file=%S/Inputs/header-in-multiple-maps/map2 -verify %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/header-in-multiple-maps -fmodule-map-file=%S/Inputs/header-in-multiple-maps/map3 -verify %s
+// expected-no-diagnostics
+
+#include "a.h"
+#include "a.h"
+A *p;