]> granicus.if.org Git - clang/commitdiff
[modules] If we import a module, and we've seen a module map that describes the
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 6 Dec 2014 03:21:08 +0000 (03:21 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 6 Dec 2014 03:21:08 +0000 (03:21 +0000)
module, use the path from the module map file in preference to the path from
the .pcm file when resolving relative paths in the .pcm file. This allows
diagnostics (and .d output) to give relative paths if the module was found via
a relative path.

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

include/clang/Basic/DiagnosticSerializationKinds.td
lib/Serialization/ASTReader.cpp
test/Modules/Inputs/malformed/c.h [new file with mode: 0644]
test/Modules/Inputs/malformed/module.map
test/Modules/Inputs/relative-dep-gen-1.h [new file with mode: 0644]
test/Modules/Inputs/relative-dep-gen-2.h [new file with mode: 0644]
test/Modules/Inputs/relative-dep-gen.modulemap [new file with mode: 0644]
test/Modules/malformed.cpp
test/Modules/relative-dep-gen.cpp [new file with mode: 0644]
test/Modules/resolution-change.m

index 5de2c6acba8033240ff0703261ba77ad38af1476..a685db0137f5842a52dc7333b9cb95c73eb1c0ca 100644 (file)
@@ -58,6 +58,9 @@ def err_imported_module_not_found : Error<
 def err_imported_module_modmap_changed : Error<
     "module '%0' imported by AST file '%1' found in a different module map file"
     " (%2) than when the importing AST file was built (%3)">, DefaultFatal;
+def err_imported_module_relocated : Error<
+    "module '%0' was built in directory '%1' but now resides in "
+    "directory '%2'">, DefaultFatal;
 def err_module_different_modmap : Error<
     "module '%0' %select{uses|does not use}1 additional module map '%2'"
     "%select{| not}1 used when the module was built">;
index e1c418b30c8fe6454ba07c2ae67486e9351deb2e..eea4ba84b0c30345dff0ac9dcb950dbd7b388668 100644 (file)
@@ -2508,9 +2508,31 @@ ASTReader::ReadControlBlock(ModuleFile &F,
         Listener->ReadModuleName(F.ModuleName);
       break;
 
-    case MODULE_DIRECTORY:
-      F.BaseDirectory = Blob;
+    case MODULE_DIRECTORY: {
+      assert(!F.ModuleName.empty() &&
+             "MODULE_DIRECTORY found before MODULE_NAME");
+      // If we've already loaded a module map file covering this module, we may
+      // have a better path for it (relative to the current build).
+      Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
+      if (M && M->Directory) {
+        // If we're implicitly loading a module, the base directory can't
+        // change between the build and use.
+        if (F.Kind != MK_ExplicitModule) {
+          const DirectoryEntry *BuildDir =
+              PP.getFileManager().getDirectory(Blob);
+          if (!BuildDir || BuildDir != M->Directory) {
+            if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+              Diag(diag::err_imported_module_relocated)
+                  << F.ModuleName << Blob << M->Directory->getName();
+            return OutOfDate;
+          }
+        }
+        F.BaseDirectory = M->Directory->getName();
+      } else {
+        F.BaseDirectory = Blob;
+      }
       break;
+    }
 
     case MODULE_MAP_FILE:
       if (ASTReadResult Result =
diff --git a/test/Modules/Inputs/malformed/c.h b/test/Modules/Inputs/malformed/c.h
new file mode 100644 (file)
index 0000000..2cce2ca
--- /dev/null
@@ -0,0 +1 @@
+template<typename T> void f() { T::error; }
index 5277ffa41edd0d8b8c1fecdb54c51bf579536877..3f088d1431d9020fb07b79b5cf189cd74eb03c8c 100644 (file)
@@ -6,3 +6,4 @@ module malformed_b {
   module b1 { header "b1.h" }
   module b2 { header "b2.h" }
 }
+module c { header "c.h" }
diff --git a/test/Modules/Inputs/relative-dep-gen-1.h b/test/Modules/Inputs/relative-dep-gen-1.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Modules/Inputs/relative-dep-gen-2.h b/test/Modules/Inputs/relative-dep-gen-2.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Modules/Inputs/relative-dep-gen.modulemap b/test/Modules/Inputs/relative-dep-gen.modulemap
new file mode 100644 (file)
index 0000000..4c821e1
--- /dev/null
@@ -0,0 +1,4 @@
+module "relative-dep-gen" {
+  header "relative-dep-gen-1.h"
+  header "relative-dep-gen-2.h"
+}
index 68d2cbd4279fcff81d7c1d686735e74cd9386ff4..2554c3a8729f8b02db49c72335e19490b7ff9ab9 100644 (file)
@@ -7,6 +7,7 @@
 // RUN: cd %S
 // RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="a1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-A
 // RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="b1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-B
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="c.h" malformed.cpp 2>&1 | FileCheck %s --check-prefix=CHECK-C
 
 #define STR2(x) #x
 #define STR(x) STR2(x)
 // CHECK-B: While building module 'malformed_b'
 // CHECK-B: {{^}}Inputs/malformed/b2.h:1:{{.*}} error: redefinition of 'g'
 // CHECK-B: {{^}}Inputs/malformed/b2.h:1:{{.*}} note: previous definition is here
+
+void test() { f<int>(); }
+// Test that we use relative paths to name files within an imported module.
+//
+// CHECK-C: In module 'c' imported from malformed.cpp:14:
+// CHECK-C: {{^}}Inputs/malformed/c.h:1:33: error: type 'int' cannot be used prior to '::'
+// CHECK-C: {{^}}malformed.cpp:[[@LINE-5]]:15: note: in instantiation of
diff --git a/test/Modules/relative-dep-gen.cpp b/test/Modules/relative-dep-gen.cpp
new file mode 100644 (file)
index 0000000..9a52f34
--- /dev/null
@@ -0,0 +1,17 @@
+// REQUIRES: shell
+//
+// RUN: cd %S
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: %clang_cc1 -cc1 -fmodule-name=relative-dep-gen -emit-module -x c++ Inputs/relative-dep-gen.modulemap -dependency-file %t/build.d -MT mod.pcm -o %t/mod.pcm
+// RUN: %clang_cc1 -cc1 -fmodule-map-file=Inputs/relative-dep-gen.modulemap -fmodule-file=%t/mod.pcm -dependency-file %t/use-explicit.d -MT use.o relative-dep-gen.cpp -fsyntax-only
+// RUN: %clang_cc1 -cc1 -fmodule-map-file=Inputs/relative-dep-gen.modulemap -dependency-file %t/use-implicit.d relative-dep-gen.cpp -MT use.o -fsyntax-only
+//
+// RUN: FileCheck --check-prefix=CHECK-BUILD %s < %t/build.d
+// RUN: FileCheck --check-prefix=CHECK-USE %s < %t/use-explicit.d
+// RUN: FileCheck --check-prefix=CHECK-USE %s < %t/use-implicit.d
+
+#include "Inputs/relative-dep-gen-1.h"
+
+// CHECK-BUILD: mod.pcm: Inputs/relative-dep-gen-1.h Inputs/relative-dep-gen-2.h
+// CHECK-USE: use.o: relative-dep-gen.cpp Inputs/relative-dep-gen-1.h
index b725a64acb4a62f4b7137330c708ffa7d5eb06a9..6882fe44c5cbf3cdef278cf0cd1c5a36867eef7d 100644 (file)
@@ -17,9 +17,9 @@
 // RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-NOA %s
 // CHECK-NOA: module 'A' in AST file '{{.*A.*pcm}}' (imported by AST file '{{.*DependsOnA.*pcm}}') is not defined in any loaded module map
 
-// Use the PCH and have it resolve the the other A
+// Use the PCH and have it resolve to the other A
 // RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-WRONGA %s
-// CHECK-WRONGA: module 'A' imported by AST file '{{.*DependsOnA.*pcm}}' found in a different module map file ({{.*path2.*}}) than when the importing AST file was built ({{.*path1.*}})
+// CHECK-WRONGA: module 'A' was built in directory '{{.*Inputs.modules-with-same-name.path1.A}}' but now resides in directory '{{.*Inputs.modules-with-same-name.path2.A}}'
 
 #ifndef HEADER
 #define HEADER