[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
This commit is contained in:
Richard Smith 2014-12-06 03:21:08 +00:00
parent e7633631e1
commit 223d3f2e4d
10 changed files with 60 additions and 4 deletions

View 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">;

View 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 =

View File

@ -0,0 +1 @@
template<typename T> void f() { T::error; }

View File

@ -6,3 +6,4 @@ module malformed_b {
module b1 { header "b1.h" }
module b2 { header "b2.h" }
}
module c { header "c.h" }

View File

@ -0,0 +1,4 @@
module "relative-dep-gen" {
header "relative-dep-gen-1.h"
header "relative-dep-gen-2.h"
}

View 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)
@ -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

View File

@ -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

View 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