diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp index cb6de9962956d..c989b4ad3859e 100644 --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp @@ -164,7 +164,7 @@ void ExpandModularHeadersPPCallbacks::InclusionDirective( if (ModuleImported) { serialization::ModuleFile *MF = Compiler.getASTReader()->getModuleManager().lookup( - *SuggestedModule->getASTFile()); + *SuggestedModule->getASTFileKey()); handleModuleFile(MF); } parseToLocation(DirectiveLoc); diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e1adaba4be7fc..129518ab2d018 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -499,6 +499,7 @@ libclang - Visit constraints of `auto` type to properly visit concept usages (#GH166580) - Visit switch initializer statements (https://bugs.kde.org/show_bug.cgi?id=415537#c2) - Fix crash in clang_getBinaryOperatorKindSpelling and clang_getUnaryOperatorKindSpelling +- The clang_Module_getASTFile API is deprecated and now always returns nullptr Code Completion --------------- diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 203634c80d82a..ca15fbafaac3e 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -4651,6 +4651,8 @@ CINDEX_LINKAGE CXModule clang_getModuleForFile(CXTranslationUnit, CXFile); * \param Module a module object. * * \returns the module file where the provided module object came from. + * + * @deprecated: module files are longer guaranteed to be loaded from a CXFile */ CINDEX_LINKAGE CXFile clang_Module_getASTFile(CXModule Module); diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index d2aea2f09353b..016cc2ce684b8 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -365,9 +365,10 @@ class alignas(8) Module { /// \c SubModules vector at which that submodule resides. mutable llvm::StringMap SubModuleIndex; - /// The AST file if this is a top-level module which has a + /// The AST file name and key if this is a top-level module which has a /// corresponding serialized AST file, or null otherwise. - OptionalFileEntryRef ASTFile; + std::optional ASTFileName; + std::optional ASTFileKey; /// The top-level headers associated with this module. llvm::SmallSetVector TopHeaders; @@ -840,15 +841,26 @@ class alignas(8) Module { return getTopLevelModule()->Name; } - /// The serialized AST file for this module, if one was created. - OptionalFileEntryRef getASTFile() const { - return getTopLevelModule()->ASTFile; + /// The serialized AST file name for this module, if one was created. + const ModuleFileName *getASTFileName() const { + const Module *TopLevel = getTopLevelModule(); + return TopLevel->ASTFileName ? &*TopLevel->ASTFileName : nullptr; } - /// Set the serialized AST file for the top-level module of this module. - void setASTFile(OptionalFileEntryRef File) { - assert((!getASTFile() || getASTFile() == File) && "file path changed"); - getTopLevelModule()->ASTFile = File; + /// The serialized AST file key for this module, if one was created. + const ModuleFileKey *getASTFileKey() const { + const Module *TopLevel = getTopLevelModule(); + return TopLevel->ASTFileKey ? &*TopLevel->ASTFileKey : nullptr; + } + + /// Set the serialized module file for the top-level module of this module. + void setASTFileNameAndKey(ModuleFileName NewName, ModuleFileKey NewKey) { + assert(((!getASTFileName() && !getASTFileKey()) || + *getASTFileKey() == NewKey) && + "file path changed"); + Module *TopLevel = getTopLevelModule(); + TopLevel->ASTFileName = NewName; + TopLevel->ASTFileKey = NewKey; } /// Retrieve the umbrella directory as written. diff --git a/clang/include/clang/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/DependencyScanning/ModuleDepCollector.h index 52035dde4a757..bbb0f5b4d659b 100644 --- a/clang/include/clang/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/DependencyScanning/ModuleDepCollector.h @@ -42,7 +42,7 @@ struct PrebuiltModuleDep { explicit PrebuiltModuleDep(const Module *M) : ModuleName(M->getTopLevelModuleName()), - PCMFile(M->getASTFile()->getName()), + PCMFile(M->getASTFileName()->str()), ModuleMapFile(M->PresumedModuleMapFile) {} }; diff --git a/clang/lib/Basic/ASTSourceDescriptor.cpp b/clang/lib/Basic/ASTSourceDescriptor.cpp index 8072c08a51d3a..933e79613992c 100644 --- a/clang/lib/Basic/ASTSourceDescriptor.cpp +++ b/clang/lib/Basic/ASTSourceDescriptor.cpp @@ -19,8 +19,8 @@ ASTSourceDescriptor::ASTSourceDescriptor(Module &M) : Signature(M.Signature), ClangModule(&M) { if (M.Directory) Path = M.Directory->getName(); - if (auto File = M.getASTFile()) - ASTFile = File->getName(); + if (auto FileKey = M.getASTFileName()) + ASTFile = FileKey->str(); } std::string ASTSourceDescriptor::getModuleName() const { diff --git a/clang/lib/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/DependencyScanning/ModuleDepCollector.cpp index 812881b23b0bd..35c9ee64c262f 100644 --- a/clang/lib/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp @@ -682,7 +682,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { // -fmodule-name is used to compile a translation unit that imports this // module. In that case it can be skipped. The appropriate header // dependencies will still be reported as expected. - if (!M->getASTFile()) + if (!M->getASTFileKey()) return {}; // If this module has been handled already, just return its ID. @@ -716,7 +716,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) { serialization::ModuleFile *MF = MDC.ScanInstance.getASTReader()->getModuleManager().lookup( - *M->getASTFile()); + *M->getASTFileKey()); llvm::SmallString<256> Storage; MD.FileDepsBaseDir = @@ -938,7 +938,7 @@ bool ModuleDepCollector::isPrebuiltModule(const Module *M) { if (PrebuiltModuleFileIt == PrebuiltModuleFiles.end()) return false; assert("Prebuilt module came from the expected AST file" && - PrebuiltModuleFileIt->second == M->getASTFile()->getName()); + PrebuiltModuleFileIt->second == M->getASTFileName()->str()); return true; } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index ca0bcd2dc2ee3..33919bc1c4634 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1883,10 +1883,9 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( M = HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective); // Check whether M refers to the file in the prebuilt module path. - if (M && M->getASTFile()) - if (auto ModuleFile = FileMgr->getOptionalFileRef(ModuleFilename)) - if (*ModuleFile == M->getASTFile()) - return M; + if (M && M->getASTFileKey() && + *M->getASTFileKey() == ModuleFilename.makeKey(*FileMgr)) + return M; getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) << ModuleName; @@ -2295,8 +2294,7 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) { Module *TheModule = I->second; - OptionalFileEntryRef Entry = TheModule->getASTFile(); - if (!Entry) { + if (!TheModule->getASTFileKey()) { SmallVector Path; Path.emplace_back(TriggerLoc, getPreprocessor().getIdentifierInfo(TheModule->Name)); diff --git a/clang/lib/Index/IndexingAction.cpp b/clang/lib/Index/IndexingAction.cpp index 8118ceda9cd23..1d98179111e78 100644 --- a/clang/lib/Index/IndexingAction.cpp +++ b/clang/lib/Index/IndexingAction.cpp @@ -254,7 +254,8 @@ static void indexPreprocessorModuleMacros(Preprocessor &PP, if (M.second.getLatest() == nullptr) { for (auto *MM : PP.getLeafModuleMacros(M.first)) { auto *OwningMod = MM->getOwningModule(); - if (OwningMod && OwningMod->getASTFile() == Mod.File) { + if (OwningMod && OwningMod->getASTFileKey() && + *OwningMod->getASTFileKey() == Mod.FileKey) { if (auto *MI = MM->getMacroInfo()) { indexPreprocessorMacro(M.first, MI, MacroDirective::MD_Define, MI->getDefinitionLoc(), DataConsumer); diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index 8fc3464ed3e0c..581163b9f0d56 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -386,9 +386,9 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, Diag(Path[0].getLoc(), diag::err_module_redefinition) << ModuleName; if (M->DefinitionLoc.isValid()) Diag(M->DefinitionLoc, diag::note_prev_module_definition); - else if (OptionalFileEntryRef FE = M->getASTFile()) + else if (const ModuleFileName *FileName = M->getASTFileName()) Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file) - << FE->getName(); + << *FileName; Mod = M; break; } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index e9c4ff3a75801..03b1b02859b81 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4652,10 +4652,10 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, << F.ModuleName << F.BaseDirectory << M->Directory->getName(); if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) { - if (auto ASTFE = M ? M->getASTFile() : std::nullopt) { + if (auto ASTFileName = M ? M->getASTFileName() : nullptr) { // This module was defined by an imported (explicit) module. - Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName - << ASTFE->getName(); + Diag(diag::err_module_file_conflict) + << F.ModuleName << F.FileName << *ASTFileName; // TODO: Add a note with the module map paths if they differ. } else { // This module was built with a different module map. @@ -6339,15 +6339,16 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, "too many submodules"); if (!ParentModule) { - if (OptionalFileEntryRef CurFile = CurrentModule->getASTFile()) { + if (const ModuleFileKey *CurFileKey = CurrentModule->getASTFileKey()) { // Don't emit module relocation error if we have -fno-validate-pch if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation & DisableValidationForModuleKind::Module)) { - assert(CurFile != F.File && "ModuleManager did not de-duplicate"); + assert(*CurFileKey != F.FileKey && + "ModuleManager did not de-duplicate"); Diag(diag::err_module_file_conflict) - << CurrentModule->getTopLevelModuleName() << CurFile->getName() - << F.File.getName(); + << CurrentModule->getTopLevelModuleName() + << *CurrentModule->getASTFileName() << F.FileName; auto CurModMapFile = ModMap.getContainingModuleMapFile(CurrentModule); @@ -6361,7 +6362,7 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, } F.DidReadTopLevelSubmodule = true; - CurrentModule->setASTFile(F.File); + CurrentModule->setASTFileNameAndKey(F.FileName, F.FileKey); CurrentModule->PresumedModuleMapFile = F.ModuleMapPath; } diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index d0bf4bc74e8ab..abb5b7955c8fa 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -51,8 +51,8 @@ ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const { ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const { if (const Module *Mod = HeaderSearchInfo.getModuleMap().findModule(Name)) - if (OptionalFileEntryRef File = Mod->getASTFile()) - return lookup(*File); + if (const ModuleFileName *FileName = Mod->getASTFileName()) + return lookupByFileName(*FileName); return nullptr; } @@ -299,10 +299,8 @@ void ModuleManager::removeModules(ModuleIterator First) { } // Delete the modules. - for (ModuleIterator victim = First; victim != Last; ++victim) { - Modules.erase(ModuleFileKey(victim->File)); + for (ModuleIterator victim = First; victim != Last; ++victim) Modules.erase(victim->FileKey); - } Chain.erase(Chain.begin() + (First - begin()), Chain.end()); } diff --git a/clang/test/Index/annotate-module.m b/clang/test/Index/annotate-module.m index 24dce3f290bfe..c8b719550d030 100644 --- a/clang/test/Index/annotate-module.m +++ b/clang/test/Index/annotate-module.m @@ -46,6 +46,6 @@ // RUN: c-index-test -cursor-at=%s:3:11 %s -fmodules-cache-path=%t.cache -fmodules -F %S/../Modules/Inputs \ // RUN: | FileCheck %s -check-prefix=CHECK-CURSOR -// CHECK-CURSOR: 3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule-{{[^.]*}}.pcm) system=0 Headers(2): +// CHECK-CURSOR: 3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule system=0 Headers(2): // CHECK-CURSOR-NEXT: {{.*}}other.h // CHECK-CURSOR-NEXT: {{.*}}DependsOnModule.h diff --git a/clang/test/Modules/DebugInfoSubmoduleImport.c b/clang/test/Modules/DebugInfoSubmoduleImport.c index 9b00a9a95c537..91cb11ef5958a 100644 --- a/clang/test/Modules/DebugInfoSubmoduleImport.c +++ b/clang/test/Modules/DebugInfoSubmoduleImport.c @@ -5,7 +5,7 @@ // RUN: %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s // // RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \ -// RUN: -fimplicit-module-maps -x c -fmodules-cache-path=%t -I %S/Inputs \ +// RUN: -fimplicit-module-maps -x c -fmodules-cache-path=%t/cache -I %S/Inputs \ // RUN: -fmodules-local-submodule-visibility \ // RUN: %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s #include "DebugSubmoduleA.h" diff --git a/clang/test/Modules/DebugInfoTransitiveImport.m b/clang/test/Modules/DebugInfoTransitiveImport.m index 4e4ba1eeafe68..425ae0001507d 100644 --- a/clang/test/Modules/DebugInfoTransitiveImport.m +++ b/clang/test/Modules/DebugInfoTransitiveImport.m @@ -1,7 +1,7 @@ // UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}} // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \ -// RUN: -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs \ +// RUN: -fimplicit-module-maps -fmodules-cache-path=%t/cache -I %S/Inputs \ // RUN: %s -mllvm -debug-only=pchcontainer -debugger-tuning=lldb 2>&1 | FileCheck %s // REQUIRES: asserts diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index cb3245756a394..4b3e105aa7aff 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -3099,19 +3099,14 @@ static void inspect_print_cursor(CXCursor Cursor) { { CXModule mod = clang_Cursor_getModule(Cursor); - CXFile astFile; - CXString name, astFilename; + CXString name; unsigned i, numHeaders; if (mod) { - astFile = clang_Module_getASTFile(mod); - astFilename = clang_getFileName(astFile); name = clang_Module_getFullName(mod); numHeaders = clang_Module_getNumTopLevelHeaders(TU, mod); - printf(" ModuleName=%s (%s) system=%d Headers(%d):", - clang_getCString(name), clang_getCString(astFilename), + printf(" ModuleName=%s system=%d Headers(%d):", clang_getCString(name), clang_Module_isSystem(mod), numHeaders); clang_disposeString(name); - clang_disposeString(astFilename); for (i = 0; i < numHeaders; ++i) { CXFile file = clang_Module_getTopLevelHeader(TU, mod, i); CXString filename = clang_getFileName(file); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 31b6a3222d916..3ee37ed2dfc27 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -9396,12 +9396,7 @@ CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) { return Header.getModule(); } -CXFile clang_Module_getASTFile(CXModule CXMod) { - if (!CXMod) - return nullptr; - Module *Mod = static_cast(CXMod); - return cxfile::makeCXFile(Mod->getASTFile()); -} +CXFile clang_Module_getASTFile(CXModule CXMod) { return nullptr; } CXModule clang_Module_getParent(CXModule CXMod) { if (!CXMod) diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp index c97aefaf87a8e..265d5876ee7a6 100644 --- a/clang/tools/libclang/CXIndexDataConsumer.cpp +++ b/clang/tools/libclang/CXIndexDataConsumer.cpp @@ -505,7 +505,11 @@ void CXIndexDataConsumer::importedModule(const ImportDecl *ImportD) { if (SrcMod->getTopLevelModule() == Mod->getTopLevelModule()) return; - OptionalFileEntryRef FE = Mod->getASTFile(); + OptionalFileEntryRef FE; + if (const ModuleFileName *ASTFileName = Mod->getASTFileName()) { + FileManager &FileMgr = cxtu::getASTUnit(CXTU)->getFileManager(); + FE = FileMgr.getOptionalFileRef(*ASTFileName); + } CXIdxImportedASTFileInfo Info = {cxfile::makeCXFile(FE), Mod, getIndexLoc(ImportD->getLocation()), ImportD->isImplicit()};