зеркало из https://github.com/microsoft/clang-1.git
Keep track of import dependencies between submodules within the module
that's currently being built. This is important for supporting transitive dependencies ("export *" in the module map) completely. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146156 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
53a75c07db
Коммит
5e3f9223db
|
@ -142,15 +142,12 @@ public:
|
|||
/// SearchPath at which the file was found. This only differs from the
|
||||
/// Filename for framework includes.
|
||||
///
|
||||
/// \param BuildingModule The name of the module we're currently building.
|
||||
///
|
||||
/// \param SuggestedModule If non-null, and the file found is semantically
|
||||
/// part of a known module, this will be set to the module that should
|
||||
/// be imported instead of preprocessing/parsing the file found.
|
||||
const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
|
||||
SmallVectorImpl<char> *SearchPath,
|
||||
SmallVectorImpl<char> *RelativePath,
|
||||
StringRef BuildingModule,
|
||||
Module **SuggestedModule) const;
|
||||
|
||||
private:
|
||||
|
@ -158,7 +155,6 @@ private:
|
|||
StringRef Filename, HeaderSearch &HS,
|
||||
SmallVectorImpl<char> *SearchPath,
|
||||
SmallVectorImpl<char> *RelativePath,
|
||||
StringRef BuildingModule,
|
||||
Module **SuggestedModule) const;
|
||||
|
||||
};
|
||||
|
|
|
@ -135,9 +135,6 @@ class HeaderSearch {
|
|||
/// \brief The path to the module cache.
|
||||
std::string ModuleCachePath;
|
||||
|
||||
/// \brief The name of the module we're building.
|
||||
std::string BuildingModule;
|
||||
|
||||
/// FileInfo - This contains all of the preprocessor-specific data about files
|
||||
/// that are included. The vector is indexed by the FileEntry's UID.
|
||||
///
|
||||
|
@ -216,11 +213,9 @@ public:
|
|||
SystemDirIdx++;
|
||||
}
|
||||
|
||||
/// \brief Set the path to the module cache and the name of the module
|
||||
/// we're building
|
||||
void configureModules(StringRef CachePath, StringRef BuildingModule) {
|
||||
/// \brief Set the path to the module cache.
|
||||
void setModuleCachePath(StringRef CachePath) {
|
||||
ModuleCachePath = CachePath;
|
||||
this->BuildingModule = BuildingModule;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the path to the module cache.
|
||||
|
|
|
@ -278,8 +278,7 @@ void CompilerInstance::createPreprocessor() {
|
|||
if (!getHeaderSearchOpts().DisableModuleHash)
|
||||
llvm::sys::path::append(SpecificModuleCache,
|
||||
getInvocation().getModuleHash());
|
||||
PP->getHeaderSearchInfo().configureModules(SpecificModuleCache,
|
||||
getLangOpts().CurrentModule);
|
||||
PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
|
||||
|
||||
// Handle generating dependencies, if requested.
|
||||
const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
|
||||
|
@ -1105,7 +1104,14 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
|
|||
// If we don't already have information on this module, load the module now.
|
||||
llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
|
||||
= KnownModules.find(Path[0].first);
|
||||
if (Known == KnownModules.end()) {
|
||||
if (Known != KnownModules.end()) {
|
||||
// Retrieve the cached top-level module.
|
||||
Module = Known->second;
|
||||
} else if (ModuleName == getLangOpts().CurrentModule) {
|
||||
// This is the module we're building.
|
||||
Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName);
|
||||
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
|
||||
} else {
|
||||
// Search for a module with the given name.
|
||||
std::string ModuleFileName;
|
||||
ModuleFile
|
||||
|
@ -1204,9 +1210,6 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
|
|||
|
||||
// Cache the result of this top-level module lookup for later.
|
||||
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
|
||||
} else {
|
||||
// Retrieve the cached top-level module.
|
||||
Module = Known->second;
|
||||
}
|
||||
|
||||
// If we never found the module, fail.
|
||||
|
@ -1265,8 +1268,10 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
|
|||
}
|
||||
}
|
||||
|
||||
// Make the named module visible.
|
||||
ModuleManager->makeModuleVisible(Module, Visibility);
|
||||
// Make the named module visible, if it's not already part of the module
|
||||
// we are parsing.
|
||||
if (ModuleName != getLangOpts().CurrentModule)
|
||||
ModuleManager->makeModuleVisible(Module, Visibility);
|
||||
|
||||
// If this module import was due to an inclusion directive, create an
|
||||
// implicit import declaration to capture it in the AST.
|
||||
|
|
|
@ -197,7 +197,6 @@ const FileEntry *DirectoryLookup::LookupFile(
|
|||
HeaderSearch &HS,
|
||||
SmallVectorImpl<char> *SearchPath,
|
||||
SmallVectorImpl<char> *RelativePath,
|
||||
StringRef BuildingModule,
|
||||
Module **SuggestedModule) const {
|
||||
llvm::SmallString<1024> TmpDir;
|
||||
if (isNormalDir()) {
|
||||
|
@ -224,10 +223,7 @@ const FileEntry *DirectoryLookup::LookupFile(
|
|||
|
||||
// If there is a module that corresponds to this header,
|
||||
// suggest it.
|
||||
Module *Module = HS.findModuleForHeader(File);
|
||||
if (Module && Module->getTopLevelModuleName() != BuildingModule)
|
||||
*SuggestedModule = Module;
|
||||
|
||||
*SuggestedModule = HS.findModuleForHeader(File);
|
||||
return File;
|
||||
}
|
||||
|
||||
|
@ -236,7 +232,7 @@ const FileEntry *DirectoryLookup::LookupFile(
|
|||
|
||||
if (isFramework())
|
||||
return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
|
||||
BuildingModule, SuggestedModule);
|
||||
SuggestedModule);
|
||||
|
||||
assert(isHeaderMap() && "Unknown directory lookup");
|
||||
const FileEntry * const Result = getHeaderMap()->LookupFile(
|
||||
|
@ -263,7 +259,6 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
|
|||
HeaderSearch &HS,
|
||||
SmallVectorImpl<char> *SearchPath,
|
||||
SmallVectorImpl<char> *RelativePath,
|
||||
StringRef BuildingModule,
|
||||
Module **SuggestedModule) const
|
||||
{
|
||||
FileManager &FileMgr = HS.getFileMgr();
|
||||
|
@ -322,11 +317,8 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
|
|||
Module *Module = 0;
|
||||
if (SuggestedModule) {
|
||||
if (const DirectoryEntry *FrameworkDir
|
||||
= FileMgr.getDirectory(FrameworkName)) {
|
||||
if ((Module = HS.getFrameworkModule(ModuleName, FrameworkDir)) &&
|
||||
Module->Name == BuildingModule)
|
||||
Module = 0;
|
||||
}
|
||||
= FileMgr.getDirectory(FrameworkName))
|
||||
Module = HS.getFrameworkModule(ModuleName, FrameworkDir);
|
||||
}
|
||||
|
||||
// Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
|
||||
|
@ -475,7 +467,7 @@ const FileEntry *HeaderSearch::LookupFile(
|
|||
for (; i != SearchDirs.size(); ++i) {
|
||||
const FileEntry *FE =
|
||||
SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
|
||||
BuildingModule, SuggestedModule);
|
||||
SuggestedModule);
|
||||
if (!FE) continue;
|
||||
|
||||
CurDir = &SearchDirs[i];
|
||||
|
|
|
@ -1352,12 +1352,21 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
break;
|
||||
}
|
||||
|
||||
CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd),
|
||||
/*IsTokenRange=*/false);
|
||||
Diag(HashLoc, diag::warn_auto_module_import)
|
||||
<< IncludeKind << PathString
|
||||
<< FixItHint::CreateReplacement(ReplaceRange,
|
||||
"__import_module__ " + PathString.str().str() + ";");
|
||||
// Determine whether we are actually building the module that this
|
||||
// include directive maps to.
|
||||
bool BuildingImportedModule
|
||||
= Path[0].first->getName() == getLangOptions().CurrentModule;
|
||||
|
||||
if (!BuildingImportedModule) {
|
||||
// If we're not building the imported module, warn that we're going
|
||||
// to automatically turn this inclusion directive into a module import.
|
||||
CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd),
|
||||
/*IsTokenRange=*/false);
|
||||
Diag(HashLoc, diag::warn_auto_module_import)
|
||||
<< IncludeKind << PathString
|
||||
<< FixItHint::CreateReplacement(ReplaceRange,
|
||||
"__import_module__ " + PathString.str().str() + ";");
|
||||
}
|
||||
|
||||
// Load the module.
|
||||
// If this was an #__include_macros directive, only make macros visible.
|
||||
|
@ -1365,7 +1374,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
= (IncludeKind == 3)? Module::MacrosVisible : Module::AllVisible;
|
||||
TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,
|
||||
/*IsIncludeDirective=*/true);
|
||||
return;
|
||||
|
||||
// If this header isn't part of the module we're building, we're done.
|
||||
if (!BuildingImportedModule)
|
||||
return;
|
||||
}
|
||||
|
||||
// The #included file will be considered to be a system header if either it is
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
#include <Module/Sub2.h>
|
||||
int *Module_Sub;
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
int *Module_Sub2;
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodule-cache-path %t -fauto-module-import -F %S/Inputs %s -verify
|
||||
|
||||
// Note: transitively imports Module.Sub2.
|
||||
__import_module__ Module.Sub;
|
||||
|
||||
int getValue() {
|
||||
return *Module_Sub + *Module_Sub2;
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче