<rdar://problem/13037793> Allow the names of modules to differ from the name of their subdirectory in the include path.

llvm-svn: 177621
This commit is contained in:
Douglas Gregor 2013-03-21 01:08:50 +00:00
parent 4ab769f4b3
commit 0339a64a40
9 changed files with 71 additions and 17 deletions

View File

@ -56,6 +56,10 @@ private:
/// \brief Whether this is a header map used when building a framework.
unsigned IsIndexHeaderMap : 1;
/// \brief Whether we've performed an exhaustive search for module maps
/// within the subdirectories of this directory.
unsigned SearchedAllModuleMaps : 1;
public:
/// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
@ -64,7 +68,7 @@ public:
bool isFramework)
: DirCharacteristic(DT),
LookupType(isFramework ? LT_Framework : LT_NormalDir),
IsIndexHeaderMap(false) {
IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
u.Dir = dir;
}
@ -73,7 +77,7 @@ public:
DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
bool isIndexHeaderMap)
: DirCharacteristic(DT), LookupType(LT_HeaderMap),
IsIndexHeaderMap(isIndexHeaderMap) {
IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
u.Map = map;
}
@ -109,6 +113,16 @@ public:
/// isHeaderMap - Return true if this is a header map, not a normal directory.
bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
/// \brief Determine whether we have already searched this entire
/// directory for module maps.
bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
/// \brief Specify whether we have already searched all of the subdirectories
/// for module maps.
void setSearchedAllModuleMaps(bool SAMM) {
SearchedAllModuleMaps = SAMM;
}
/// DirCharacteristic - The type of directory this is, one of the DirType enum
/// values.
SrcMgr::CharacteristicKind getDirCharacteristic() const {

View File

@ -505,7 +505,11 @@ private:
Module *loadFrameworkModule(StringRef Name,
const DirectoryEntry *Dir,
bool IsSystem);
/// \brief Load all of the module maps within the immediate subdirectories
/// of the given search directory.
void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
public:
/// \brief Retrieve the module map.
ModuleMap &getModuleMap() { return ModMap; }

View File

@ -181,8 +181,22 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
if (Module)
break;
}
// If we've already performed the exhaustive search for module maps in this
// search directory, don't do it again.
if (SearchDirs[Idx].haveSearchedAllModuleMaps())
continue;
// Load all module maps in the immediate subdirectories of this search
// directory.
loadSubdirectoryModuleMaps(SearchDirs[Idx]);
// Look again for the module.
Module = ModMap.findModule(ModuleName);
if (Module)
break;
}
return Module;
}
@ -1126,13 +1140,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
// Try to load module map files for immediate subdirectories of this search
// directory.
llvm::error_code EC;
SmallString<128> DirNative;
llvm::sys::path::native(SearchDirs[Idx].getDir()->getName(), DirNative);
for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
loadModuleMapFile(Dir->path());
}
loadSubdirectoryModuleMaps(SearchDirs[Idx]);
}
// Populate the list of modules.
@ -1142,3 +1150,18 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
Modules.push_back(M->getValue());
}
}
void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
if (SearchDir.haveSearchedAllModuleMaps())
return;
llvm::error_code EC;
SmallString<128> DirNative;
llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
loadModuleMapFile(Dir->path());
}
SearchDir.setSearchedAllModuleMaps(true);
}

View File

@ -1,3 +1,3 @@
@import A;
@import ModA;
int getB();

View File

@ -1,5 +1,5 @@
module A { header "A.h" }
module B {
module ModA { header "A.h" }
module ModB {
header "B.h"
export *
}

View File

@ -0,0 +1,4 @@
module NewName {
header "new_name.h"
export *
}

View File

@ -0,0 +1 @@
int same_api;

View File

@ -11,9 +11,9 @@
// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
// RUN: echo 'int getA(); int getA2();' > %t/include/A.h
// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
// RUN: rm %t/cache/A.pcm
// RUN: rm %t/cache/ModA.pcm
// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
// RUN: touch %t/cache/A.pcm
// RUN: touch %t/cache/ModA.pcm
// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
// expected-no-diagnostics
@ -21,7 +21,7 @@
// FIXME: It is intended to suppress this on win32.
// REQUIRES: ansi-escape-sequences
@import B;
@import ModB;
int getValue() { return getA() + getB(); }

View File

@ -0,0 +1,8 @@
@import NewName;
int f() { return same_api; }
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -I %S/Inputs -fmodules-cache-path=%t %s -verify
// expected-no-diagnostics