diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-06 03:21:08 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-06 03:21:08 +0000 |
commit | 223d3f2e4d49c52b0b5516f001d1827c6e55d44b (patch) | |
tree | 6dd167c06ef5d45dfde2115046f74e9f3c353d5b | |
parent | e7633631e1f10de34484d65a009256217bbb5cc8 (diff) | |
download | llvm-223d3f2e4d49c52b0b5516f001d1827c6e55d44b.zip llvm-223d3f2e4d49c52b0b5516f001d1827c6e55d44b.tar.gz llvm-223d3f2e4d49c52b0b5516f001d1827c6e55d44b.tar.bz2 |
[modules] If we import a module, and we've seen a module map that describes the
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.
llvm-svn: 223577
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSerializationKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 26 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/malformed/c.h | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/malformed/module.map | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/relative-dep-gen-1.h | 0 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/relative-dep-gen-2.h | 0 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/relative-dep-gen.modulemap | 4 | ||||
-rw-r--r-- | clang/test/Modules/malformed.cpp | 8 | ||||
-rw-r--r-- | clang/test/Modules/relative-dep-gen.cpp | 17 | ||||
-rw-r--r-- | clang/test/Modules/resolution-change.m | 4 |
10 files changed, 60 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index 5de2c6a..a685db0 100644 --- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -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">; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index e1c418b..eea4ba8 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -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/clang/test/Modules/Inputs/malformed/c.h b/clang/test/Modules/Inputs/malformed/c.h new file mode 100644 index 0000000..2cce2ca --- /dev/null +++ b/clang/test/Modules/Inputs/malformed/c.h @@ -0,0 +1 @@ +template<typename T> void f() { T::error; } diff --git a/clang/test/Modules/Inputs/malformed/module.map b/clang/test/Modules/Inputs/malformed/module.map index 5277ffa..3f088d1 100644 --- a/clang/test/Modules/Inputs/malformed/module.map +++ b/clang/test/Modules/Inputs/malformed/module.map @@ -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/clang/test/Modules/Inputs/relative-dep-gen-1.h b/clang/test/Modules/Inputs/relative-dep-gen-1.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Modules/Inputs/relative-dep-gen-1.h diff --git a/clang/test/Modules/Inputs/relative-dep-gen-2.h b/clang/test/Modules/Inputs/relative-dep-gen-2.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/clang/test/Modules/Inputs/relative-dep-gen-2.h diff --git a/clang/test/Modules/Inputs/relative-dep-gen.modulemap b/clang/test/Modules/Inputs/relative-dep-gen.modulemap new file mode 100644 index 0000000..4c821e1 --- /dev/null +++ b/clang/test/Modules/Inputs/relative-dep-gen.modulemap @@ -0,0 +1,4 @@ +module "relative-dep-gen" { + header "relative-dep-gen-1.h" + header "relative-dep-gen-2.h" +} diff --git a/clang/test/Modules/malformed.cpp b/clang/test/Modules/malformed.cpp index 68d2cbd..2554c3a 100644 --- a/clang/test/Modules/malformed.cpp +++ b/clang/test/Modules/malformed.cpp @@ -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) @@ -27,3 +28,10 @@ // 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/clang/test/Modules/relative-dep-gen.cpp b/clang/test/Modules/relative-dep-gen.cpp new file mode 100644 index 0000000..9a52f34 --- /dev/null +++ b/clang/test/Modules/relative-dep-gen.cpp @@ -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 diff --git a/clang/test/Modules/resolution-change.m b/clang/test/Modules/resolution-change.m index b725a64..6882fe4 100644 --- a/clang/test/Modules/resolution-change.m +++ b/clang/test/Modules/resolution-change.m @@ -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 |