From 7b316696cffa952d8fdf8291021f470c38adf797 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 6 Dec 2014 03:21:08 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223577 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Basic/DiagnosticSerializationKinds.td | 3 +++ lib/Serialization/ASTReader.cpp | 26 +++++++++++++++++-- test/Modules/Inputs/malformed/c.h | 1 + test/Modules/Inputs/malformed/module.map | 1 + test/Modules/Inputs/relative-dep-gen-1.h | 0 test/Modules/Inputs/relative-dep-gen-2.h | 0 .../Modules/Inputs/relative-dep-gen.modulemap | 4 +++ test/Modules/malformed.cpp | 8 ++++++ test/Modules/relative-dep-gen.cpp | 17 ++++++++++++ test/Modules/resolution-change.m | 4 +-- 10 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 test/Modules/Inputs/malformed/c.h create mode 100644 test/Modules/Inputs/relative-dep-gen-1.h create mode 100644 test/Modules/Inputs/relative-dep-gen-2.h create mode 100644 test/Modules/Inputs/relative-dep-gen.modulemap create mode 100644 test/Modules/relative-dep-gen.cpp diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index 5de2c6acba..a685db0137 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/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/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index e1c418b30c..eea4ba84b0 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/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/test/Modules/Inputs/malformed/c.h b/test/Modules/Inputs/malformed/c.h new file mode 100644 index 0000000000..2cce2ca9ca --- /dev/null +++ b/test/Modules/Inputs/malformed/c.h @@ -0,0 +1 @@ +template void f() { T::error; } diff --git a/test/Modules/Inputs/malformed/module.map b/test/Modules/Inputs/malformed/module.map index 5277ffa41e..3f088d1431 100644 --- a/test/Modules/Inputs/malformed/module.map +++ b/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/test/Modules/Inputs/relative-dep-gen-1.h b/test/Modules/Inputs/relative-dep-gen-1.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Modules/Inputs/relative-dep-gen-2.h b/test/Modules/Inputs/relative-dep-gen-2.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Modules/Inputs/relative-dep-gen.modulemap b/test/Modules/Inputs/relative-dep-gen.modulemap new file mode 100644 index 0000000000..4c821e19ae --- /dev/null +++ b/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/test/Modules/malformed.cpp b/test/Modules/malformed.cpp index 68d2cbd427..2554c3a872 100644 --- a/test/Modules/malformed.cpp +++ b/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(); } +// 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 index 0000000000..9a52f34a01 --- /dev/null +++ b/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/test/Modules/resolution-change.m b/test/Modules/resolution-change.m index b725a64acb..6882fe44c5 100644 --- a/test/Modules/resolution-change.m +++ b/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 -- 2.40.0