Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Frontend/CompilerInstance.cpp
Show First 20 Lines • Show All 1,123 Lines • ▼ Show 20 Lines | if (LangOpts.OpenCL) | ||||
return Language::OpenCL; | return Language::OpenCL; | ||||
if (LangOpts.CUDA) | if (LangOpts.CUDA) | ||||
return Language::CUDA; | return Language::CUDA; | ||||
if (LangOpts.ObjC) | if (LangOpts.ObjC) | ||||
return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC; | return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC; | ||||
return LangOpts.CPlusPlus ? Language::CXX : Language::C; | return LangOpts.CPlusPlus ? Language::CXX : Language::C; | ||||
} | } | ||||
class Translator { | |||||
CompilerInstance &A; | |||||
Preprocessor &APP; | |||||
SourceManager &ASM; | |||||
FileManager &AFM; | |||||
HeaderSearch &AHS; | |||||
const CompilerInstance &B; | |||||
const Preprocessor &BPP; | |||||
const SourceManager &BSM; | |||||
const FileManager &BFM; | |||||
HeaderSearch &BHS; | |||||
llvm::StringSet<> TranslatedModules; | |||||
public: | |||||
Translator(CompilerInstance &A, const CompilerInstance &B) | |||||
: A(A), APP(A.getPreprocessor()), ASM(A.getSourceManager()), | |||||
AFM(A.getFileManager()), AHS(A.getPreprocessor().getHeaderSearchInfo()), | |||||
B(B), BPP(B.getPreprocessor()), BSM(B.getSourceManager()), | |||||
BFM(B.getFileManager()), | |||||
BHS(B.getPreprocessor().getHeaderSearchInfo()) {} | |||||
template <class T> Optional<T> translate(const Optional<T> &BO) { | |||||
if (!BO) | |||||
return None; | |||||
return translate(*BO); | |||||
} | |||||
template <class T> const T *translate(const T *BP) { | |||||
if (!BP) | |||||
return nullptr; | |||||
return &translate(*BP); | |||||
} | |||||
template <class T> T *translate(T *BP) { | |||||
if (!BP) | |||||
return nullptr; | |||||
return &translate(*BP); | |||||
} | |||||
template <class T, class U> | |||||
llvm::PointerUnion<T, U> translate(llvm::PointerUnion<T, U> BPU) { | |||||
if (!BPU) | |||||
return nullptr; | |||||
if (BPU.template is<T>()) | |||||
return translate(BPU.template get<T>()); | |||||
return translate(BPU.template get<U>()); | |||||
} | |||||
template <class T, unsigned N> | |||||
SmallVector<T, N> translate(const SmallVector<T, N> &BV) { | |||||
SmallVector<T, N> AV; | |||||
AV.reserve(BV.size()); | |||||
for (const T &Entry : BV) | |||||
AV.push_back(translate(Entry)); | |||||
return AV; | |||||
} | |||||
template <class T, unsigned N> | |||||
llvm::SmallSetVector<T, N> translate(const llvm::SmallSetVector<T, N>& BSSV) { | |||||
llvm::SmallSetVector<T, N> ASSV; | |||||
for (const auto &Entry : BSSV) | |||||
ASSV.insert(translate(Entry)); | |||||
return ASSV; | |||||
} | |||||
const FileEntry &translate(const FileEntry &BFE) { | |||||
if (auto MaybeAFE = AFM.getFile(BFE.getName())) | |||||
return **MaybeAFE; | |||||
return *AFM.getVirtualFile(BFE.getName(), BFE.getSize(), | |||||
BFE.getModificationTime()); | |||||
} | |||||
FileEntryRef translate(FileEntryRef BFE) { | |||||
return *AFM.getOptionalFileRef(BFE.getName()); | |||||
} | |||||
const DirectoryEntry &translate(const DirectoryEntry &BDE) { | |||||
return **AFM.getDirectory(BDE.getName()); | |||||
} | |||||
SourceLocation translate(SourceLocation BLoc) { | |||||
if (BLoc.isInvalid()) | |||||
return {}; | |||||
auto BOffset = BSM.getFileOffset(BLoc); | |||||
auto AOffset = BOffset; | |||||
auto BFileID = BSM.getFileID(BLoc); | |||||
auto AFileID = [&]() { | |||||
if (BFileID == BPP.getPredefinesFileID()) | |||||
return APP.getPredefinesFileID(); | |||||
auto BFileCharacteristic = BSM.getFileCharacteristic(BLoc); | |||||
auto AFileCharacteristic = BFileCharacteristic; | |||||
auto *BFileEntry = BSM.getFileEntryForID(BFileID); | |||||
auto *AFileEntry = translate(BFileEntry); | |||||
return ASM.getOrCreateFileID(AFileEntry, AFileCharacteristic); | |||||
}(); | |||||
return ASM.getComposedLoc(AFileID, AOffset); | |||||
} | |||||
Module::Header translate(const Module::Header &BHeader) { | |||||
return Module::Header{BHeader.NameAsWritten, | |||||
BHeader.PathRelativeToRootModuleDirectory, | |||||
translate(BHeader.Entry)}; | |||||
} | |||||
std::vector<Module *> translate(Module::submodule_iterator Begin, | |||||
Module::submodule_iterator End) { | |||||
std::vector<Module *> ASubModules; | |||||
for (auto It = Begin; It != End; ++It) | |||||
ASubModules.push_back(translate(*It)); | |||||
return ASubModules; | |||||
} | |||||
Module::UnresolvedHeaderDirective | |||||
translate(const Module::UnresolvedHeaderDirective &BD) { | |||||
return {BD.Kind, // | |||||
translate(BD.FileNameLoc), | |||||
BD.FileName, | |||||
BD.IsUmbrella, | |||||
BD.HasBuiltinHeader, | |||||
BD.Size, | |||||
BD.ModTime}; | |||||
} | |||||
Module::ExportDecl translate(const Module::ExportDecl &BED) { | |||||
return {translate(BED.getPointer()), BED.getInt()}; | |||||
} | |||||
ModuleId translate(const ModuleId &BId) { | |||||
ModuleId Res; | |||||
for (const auto &Element : BId) | |||||
Res.push_back({Element.first, translate(Element.second)}); | |||||
return Res; | |||||
} | |||||
Module::UnresolvedExportDecl | |||||
translate(const Module::UnresolvedExportDecl &BUED) { | |||||
return {translate(BUED.ExportLoc), translate(BUED.Id), BUED.Wildcard}; | |||||
} | |||||
Module::LinkLibrary translate(const Module::LinkLibrary &X) { | |||||
return X; | |||||
} | |||||
Module::UnresolvedConflict translate(const Module::UnresolvedConflict &X) { | |||||
return {translate(X.Id), X.Message}; | |||||
} | |||||
Module::Conflict translate(const Module::Conflict &X) { | |||||
return {translate(X.Other), X.Message}; | |||||
} | |||||
const Module &translate(const Module &BMod) { | |||||
return translate(const_cast<Module &>(BMod)); | |||||
} | |||||
Module &translate(Module &BMod) { | |||||
auto &AModMap = AHS.getModuleMap(); | |||||
auto [AMod, New] = AModMap.findOrCreateModule( | |||||
BMod.Name, translate(BMod.Parent), | |||||
BMod.IsFramework, BMod.IsExplicit); | |||||
if (!TranslatedModules.insert(BMod.Name).second) | |||||
return *AMod; | |||||
AMod->Kind = BMod.Kind; | |||||
AMod->Directory = translate(BMod.Directory); | |||||
AMod->PresumedModuleMapFile = BMod.PresumedModuleMapFile; | |||||
AMod->DefinitionLoc = translate(BMod.DefinitionLoc); | |||||
AMod->Umbrella = translate(BMod.Umbrella); | |||||
AMod->UmbrellaAsWritten = BMod.UmbrellaAsWritten; | |||||
AMod->UmbrellaRelativeToRootModuleDirectory = | |||||
BMod.UmbrellaRelativeToRootModuleDirectory; | |||||
AMod->ExportAsModule = BMod.ExportAsModule; | |||||
for (Module *BSubMod : BMod.submodules()) | |||||
translate(BSubMod); | |||||
for (const FileEntry *BTopHeader : BMod.getTopHeaders(B.getFileManager())) | |||||
AMod->addTopHeader(translate(BTopHeader)); | |||||
// TODO: Propagate VisibilityID to other data structures. | |||||
for (auto Kind : {Module::HK_Normal, Module::HK_Textual, Module::HK_Private, | |||||
Module::HK_PrivateTextual, Module::HK_Excluded}) { | |||||
for (const auto &BH : BMod.Headers[Kind]) { | |||||
const auto &AH = translate(BH); | |||||
AModMap.addHeader(AMod, AH, ModuleMap::headerKindToRole(Kind), | |||||
BHS.getFileInfo(BH.Entry).isModuleHeader); | |||||
} | |||||
} | |||||
AMod->UnresolvedHeaders = translate(BMod.UnresolvedHeaders); | |||||
AMod->MissingHeaders = translate(BMod.MissingHeaders); | |||||
AMod->Requirements = BMod.Requirements; | |||||
AMod->ShadowingModule = translate(BMod.ShadowingModule); | |||||
AMod->IsUnimportable = BMod.IsUnimportable; | |||||
AMod->HasIncompatibleModuleFile = BMod.HasIncompatibleModuleFile; | |||||
AMod->IsAvailable = BMod.IsAvailable; | |||||
AMod->IsFromModuleFile = BMod.IsFromModuleFile; | |||||
AMod->IsFramework = BMod.IsFramework; | |||||
AMod->IsExplicit = BMod.IsExplicit; | |||||
AMod->IsSystem = BMod.IsSystem; | |||||
AMod->IsExternC = BMod.IsExternC; | |||||
// This is being dropped by PCM files and propagating it triggers asserts. | |||||
// AMod->IsInferred = BMod.IsInferred; | |||||
AMod->InferSubmodules = BMod.InferSubmodules; | |||||
AMod->InferExplicitSubmodules = BMod.InferExplicitSubmodules; | |||||
AMod->InferExportWildcard = BMod.InferExportWildcard; | |||||
AMod->ConfigMacrosExhaustive = BMod.ConfigMacrosExhaustive; | |||||
AMod->NoUndeclaredIncludes = BMod.NoUndeclaredIncludes; | |||||
AMod->ModuleMapIsPrivate = BMod.ModuleMapIsPrivate; | |||||
AMod->NameVisibility = BMod.NameVisibility; | |||||
AMod->InferredSubmoduleLoc = translate(BMod.InferredSubmoduleLoc); | |||||
AMod->Imports = translate(BMod.Imports); | |||||
AMod->Exports = translate(BMod.Exports); | |||||
AMod->AffectingClangModules = translate(BMod.AffectingClangModules); | |||||
AMod->UnresolvedExports = translate(BMod.UnresolvedExports); | |||||
AMod->DirectUses = translate(BMod.DirectUses); | |||||
AMod->UnresolvedDirectUses = translate(BMod.UnresolvedDirectUses); | |||||
AMod->UndeclaredUses = translate(BMod.UndeclaredUses); | |||||
AMod->LinkLibraries = translate(BMod.LinkLibraries); | |||||
AMod->UseExportAsModuleLinkName = BMod.UseExportAsModuleLinkName; | |||||
AMod->ConfigMacros = BMod.ConfigMacros; | |||||
AMod->UnresolvedConflicts = BMod.UnresolvedConflicts; | |||||
AMod->Conflicts = BMod.Conflicts; | |||||
return *AMod; | |||||
} | |||||
void translateModule(StringRef BName) { | |||||
translate(B.getPreprocessor().getHeaderSearchInfo().lookupModule(BName)); | |||||
} | |||||
IdentifierInfo &translate(IdentifierInfo &BII) { | |||||
auto &AII = APP.getIdentifierTable().getOwn(BII.getName()); | |||||
AII.setOutOfDate(false); | |||||
// TODO: Check if is interesting. | |||||
if (BII.hasRevertedTokenIDToIdentifier() && | |||||
BII.getTokenID() != tok::TokenKind::identifier) | |||||
AII.revertTokenIDToIdentifier(); | |||||
AII.setObjCOrBuiltinID(BII.getObjCOrBuiltinID()); | |||||
AII.setIsPoisoned(BII.isPoisoned()); | |||||
AII.setObjCKeywordID(BII.getObjCKeywordID()); | |||||
AII.setHasMacroDefinition(BII.hasMacroDefinition()); | |||||
return AII; | |||||
} | |||||
Token translate(const Token &BTok) { | |||||
Token ATok; | |||||
ATok.startToken(); | |||||
ATok.setLocation(translate(BTok.getLocation())); | |||||
ATok.setLength(BTok.getLength()); | |||||
ATok.setIdentifierInfo(translate(BTok.getIdentifierInfo())); | |||||
ATok.setKind(BTok.getKind()); | |||||
ATok.setFlags(BTok.getFlags()); | |||||
return ATok; | |||||
} | |||||
MacroInfo *translate(MacroInfo *BMI) { | |||||
auto BLoc = BMI->getDefinitionLoc(); | |||||
auto ALoc = translate(BLoc); | |||||
MacroInfo *AMI = APP.AllocateMacroInfo(ALoc); | |||||
AMI->setDefinitionEndLoc(BMI->getDefinitionEndLoc()); | |||||
AMI->setIsUsed(BMI->isUsed()); | |||||
AMI->setUsedForHeaderGuard(BMI->isUsedForHeaderGuard()); | |||||
if (BMI->isFunctionLike()) { | |||||
AMI->setIsFunctionLike(); | |||||
if (BMI->isC99Varargs()) | |||||
AMI->setIsC99Varargs(); | |||||
if (BMI->isGNUVarargs()) | |||||
AMI->setIsGNUVarargs(); | |||||
if (BMI->hasCommaPasting()) | |||||
AMI->setHasCommaPasting(); | |||||
std::vector<IdentifierInfo *> AParams; | |||||
for (const IdentifierInfo *BParam : BMI->params()) | |||||
AParams.push_back(translate(const_cast<IdentifierInfo *>(BParam))); | |||||
AMI->setParameterList(AParams, APP.getPreprocessorAllocator()); | |||||
} | |||||
// TODO: Complete preprocessing record. | |||||
std::vector<Token> AToks; | |||||
for (const Token &BTok : BMI->tokens()) | |||||
AToks.push_back(translate(BTok)); | |||||
AMI->setTokens(AToks, APP.getPreprocessorAllocator()); | |||||
return AMI; | |||||
} | |||||
void translatePreprocessor() { | |||||
for (const auto &Entry : BPP.getIdentifierTable()) { | |||||
IdentifierInfo *BII = Entry.getValue(); | |||||
if (!BII->hadMacroDefinition()) | |||||
continue; | |||||
// Macro directive history is not read for modules. | |||||
IdentifierInfo *BName = BII; | |||||
IdentifierInfo *AName = translate(BII); | |||||
if (BII->isOutOfDate()) { | |||||
// TODO: Investigate how out-of-date identifiers come to be. | |||||
BII->setOutOfDate(false); | |||||
} | |||||
auto BLeafs = BPP.getLeafModuleMacros(BName); | |||||
SmallVector<ModuleMacro *, 8> Worklist(BLeafs.begin(), BLeafs.end()); | |||||
llvm::DenseMap<ModuleMacro *, unsigned> Visits; | |||||
while (!Worklist.empty()) { | |||||
auto *BMacro = Worklist.pop_back_val(); | |||||
auto *AModule = translate(BMacro->getOwningModule()); | |||||
auto *AMacroInfo = translate(BMacro->getMacroInfo()); | |||||
std::vector<ModuleMacro *> AOverrides; | |||||
for (auto *BOverride : BMacro->overrides()) { | |||||
auto *AOverrideModule = translate(BOverride->getOwningModule()); | |||||
AOverrides.push_back(APP.getModuleMacro(AOverrideModule, AName)); | |||||
} | |||||
bool Inserted = false; | |||||
APP.addModuleMacro(AModule, AName, AMacroInfo, AOverrides, Inserted); | |||||
// Enqueue overridden macros once we've visited all their ancestors. | |||||
for (auto *BModuleMacro : BMacro->overrides()) | |||||
if (++Visits[BModuleMacro] == BModuleMacro->getNumOverridingMacros()) | |||||
Worklist.push_back(BModuleMacro); | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
// Copied from ASTWriter.cpp. | |||||
static std::set<const FileEntry *> | |||||
GetAffectingModuleMaps(const HeaderSearch &HS, Module *RootModule) { | |||||
std::set<const FileEntry *> ModuleMaps{}; | |||||
std::set<const Module *> ProcessedModules; | |||||
SmallVector<const Module *> ModulesToProcess{RootModule}; | |||||
SmallVector<const FileEntry *, 16> FilesByUID; | |||||
HS.getFileMgr().GetUniqueIDMapping(FilesByUID); | |||||
if (FilesByUID.size() > HS.header_file_size()) | |||||
FilesByUID.resize(HS.header_file_size()); | |||||
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) { | |||||
const FileEntry *File = FilesByUID[UID]; | |||||
if (!File) | |||||
continue; | |||||
const HeaderFileInfo *HFI = | |||||
HS.getExistingFileInfo(File, /*WantExternal*/ false); | |||||
if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader)) | |||||
continue; | |||||
for (const auto &KH : HS.findAllModulesForHeader(File)) { | |||||
if (!KH.getModule()) | |||||
continue; | |||||
ModulesToProcess.push_back(KH.getModule()); | |||||
} | |||||
} | |||||
while (!ModulesToProcess.empty()) { | |||||
auto *CurrentModule = ModulesToProcess.pop_back_val(); | |||||
ProcessedModules.insert(CurrentModule); | |||||
Optional<FileEntryRef> ModuleMapFile = | |||||
HS.getModuleMap().getModuleMapFileForUniquing(CurrentModule); | |||||
if (!ModuleMapFile) { | |||||
continue; | |||||
} | |||||
ModuleMaps.insert(*ModuleMapFile); | |||||
for (auto *ImportedModule : (CurrentModule)->Imports) { | |||||
if (!ImportedModule || | |||||
ProcessedModules.find(ImportedModule) != ProcessedModules.end()) { | |||||
continue; | |||||
} | |||||
ModulesToProcess.push_back(ImportedModule); | |||||
} | |||||
for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses) | |||||
if (UndeclaredModule && | |||||
ProcessedModules.find(UndeclaredModule) == ProcessedModules.end()) | |||||
ModulesToProcess.push_back(UndeclaredModule); | |||||
for (const Module *AffectingModule : CurrentModule->AffectingClangModules) | |||||
if (AffectingModule && ProcessedModules.find(AffectingModule) == ProcessedModules.end()) | |||||
ModulesToProcess.push_back(AffectingModule); | |||||
} | |||||
return ModuleMaps; | |||||
} | |||||
/// Compile a module file for the given module, using the options | /// Compile a module file for the given module, using the options | ||||
/// provided by the importing compiler instance. Returns true if the module | /// provided by the importing compiler instance. Returns true if the module | ||||
/// was built without errors. | /// was built without errors. | ||||
static bool | static bool | ||||
compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, | compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, | ||||
StringRef ModuleName, FrontendInputFile Input, | StringRef ModuleName, FrontendInputFile Input, | ||||
StringRef OriginalModuleMapFile, StringRef ModuleFileName, | StringRef OriginalModuleMapFile, StringRef ModuleFileName, | ||||
llvm::function_ref<void(CompilerInstance &)> PreBuildStep = | llvm::function_ref<void(CompilerInstance &)> PreBuildStep = | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, | ||||
PreBuildStep(Instance); | PreBuildStep(Instance); | ||||
// Execute the action to actually build the module in-place. Use a separate | // Execute the action to actually build the module in-place. Use a separate | ||||
// thread so that we get a stack large enough. | // thread so that we get a stack large enough. | ||||
bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread( | bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread( | ||||
[&]() { | [&]() { | ||||
GenerateModuleFromModuleMapAction Action; | GenerateModuleFromModuleMapAction Action; | ||||
Instance.ExecuteAction(Action); | Instance.ExecuteAction(Action); | ||||
if (!Instance.getPreprocessorOpts().ScanningMode) | |||||
return; | |||||
Translator T(ImportingInstance, Instance); | |||||
T.translateModule(ModuleName); | |||||
T.translatePreprocessor(); | |||||
for (const auto &X : Instance.SearchPathUsage) | |||||
if (!ImportingInstance.SearchPathUsage.count(X.getKey())) | |||||
ImportingInstance.SearchPathUsage[X.getKey()] = X.getValue(); | |||||
auto &HSUsage = ImportingInstance.SearchPathUsage[ModuleName]; | |||||
for (bool Used : Instance.getPreprocessor() | |||||
.getHeaderSearchInfo() | |||||
.computeUserEntryUsage()) | |||||
HSUsage.push_back(Used); | |||||
for (const auto &X : Instance.SortedFiles) | |||||
if (!ImportingInstance.SortedFiles.count(X.getKey())) { | |||||
ImportingInstance.SortedFiles[X.getKey()] = X.getValue(); | |||||
} | |||||
auto &SortedFiles = ImportingInstance.SortedFiles[ModuleName]; | |||||
std::vector<CompilerInstance::EntryStruct> UserFiles; | |||||
std::vector<CompilerInstance::EntryStruct> SystemFiles; | |||||
std::set<const FileEntry *> AffectingModuleMaps = | |||||
GetAffectingModuleMaps( | |||||
Instance.getPreprocessor().getHeaderSearchInfo(), | |||||
Instance.getPreprocessor().getHeaderSearchInfo().lookupModule( | |||||
ModuleName)); | |||||
SourceManager &SrcMgr = Instance.getPreprocessor().getSourceManager(); | |||||
unsigned N = SrcMgr.local_sloc_entry_size(); | |||||
for (unsigned I = 1; I != N; ++I) { | |||||
const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(I); | |||||
if (!SLoc->isFile()) | |||||
continue; | |||||
const SrcMgr::FileInfo &File = SLoc->getFile(); | |||||
const SrcMgr::ContentCache *Cache = &File.getContentCache(); | |||||
if (!Cache->OrigEntry) | |||||
continue; | |||||
if (!isModuleMap(File.getFileCharacteristic()) || | |||||
AffectingModuleMaps.empty() || | |||||
AffectingModuleMaps.find(Cache->OrigEntry) != | |||||
AffectingModuleMaps.end()) { | |||||
CompilerInstance::EntryStruct Entry{ | |||||
T.translate(Cache->OrigEntry), | |||||
isSystem(File.getFileCharacteristic()), | |||||
isModuleMap(File.getFileCharacteristic()) && | |||||
File.getIncludeLoc().isInvalid()}; | |||||
Entry.FE->getName(); | |||||
if (Entry.IsSystemFile) | |||||
SystemFiles.push_back(Entry); | |||||
else | |||||
UserFiles.push_back(Entry); | |||||
} | |||||
} | |||||
SortedFiles.insert(SortedFiles.end(), UserFiles.begin(), UserFiles.end()); | |||||
SortedFiles.insert(SortedFiles.end(), SystemFiles.begin(), SystemFiles.end()); | |||||
}, | }, | ||||
DesiredStackSize); | DesiredStackSize); | ||||
PostBuildStep(Instance); | PostBuildStep(Instance); | ||||
ImportingInstance.getDiagnostics().Report(ImportLoc, | ImportingInstance.getDiagnostics().Report(ImportLoc, | ||||
diag::remark_module_build_done) | diag::remark_module_build_done) | ||||
<< ModuleName; | << ModuleName; | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/// Read the AST right after compiling the module. | /// Read the AST right after compiling the module. | ||||
static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance, | static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance, | ||||
SourceLocation ImportLoc, | SourceLocation ImportLoc, | ||||
SourceLocation ModuleNameLoc, | SourceLocation ModuleNameLoc, | ||||
Module *Module, StringRef ModuleFileName, | Module *Module, StringRef ModuleFileName, | ||||
bool *OutOfDate) { | bool *OutOfDate) { | ||||
// Do not attempt to read the AST file. | |||||
if (ImportingInstance.getPreprocessorOpts().ScanningMode) | |||||
return true; | |||||
DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); | DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); | ||||
unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; | unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; | ||||
if (OutOfDate) | if (OutOfDate) | ||||
ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; | ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; | ||||
// Try to read the module file, now that we've compiled it. | // Try to read the module file, now that we've compiled it. | ||||
ASTReader::ASTReadResult ReadResult = | ASTReader::ASTReadResult ReadResult = | ||||
▲ Show 20 Lines • Show All 712 Lines • ▼ Show 20 Lines | for (unsigned I = 1, N = Path.size(); I != N; ++I) { | ||||
} | } | ||||
Module = Sub; | Module = Sub; | ||||
} | } | ||||
// Make the named module visible, if it's not already part of the module | // Make the named module visible, if it's not already part of the module | ||||
// we are parsing. | // we are parsing. | ||||
if (ModuleName != getLangOpts().CurrentModule) { | if (ModuleName != getLangOpts().CurrentModule) { | ||||
if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) { | if (!getPreprocessorOpts().ScanningMode && !Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) { | ||||
// We have an umbrella header or directory that doesn't actually include | // We have an umbrella header or directory that doesn't actually include | ||||
// all of the headers within the directory it covers. Complain about | // all of the headers within the directory it covers. Complain about | ||||
// this missing submodule and recover by forgetting that we ever saw | // this missing submodule and recover by forgetting that we ever saw | ||||
// this submodule. | // this submodule. | ||||
// FIXME: Should we detect this at module load time? It seems fairly | // FIXME: Should we detect this at module load time? It seems fairly | ||||
// expensive (and rare). | // expensive (and rare). | ||||
getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) | getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) | ||||
<< Module->getFullModuleName() | << Module->getFullModuleName() | ||||
▲ Show 20 Lines • Show All 198 Lines • Show Last 20 Lines |