diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp | 171 |
1 files changed, 104 insertions, 67 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp index 996783aa9cf4..f09a01b5dd4a 100644 --- a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp @@ -66,11 +66,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -85,8 +82,8 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/FileUtilities.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/Timer.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" @@ -98,6 +95,7 @@ #include <cstdlib> #include <memory> #include <mutex> +#include <optional> #include <string> #include <tuple> #include <utility> @@ -322,6 +320,7 @@ static uint64_t getDeclShowContexts(const NamedDecl *ND, if (ID->getDefinition()) Contexts |= (1LL << CodeCompletionContext::CCC_Expression); Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName); + Contexts |= (1LL << CodeCompletionContext::CCC_ObjCClassForwardDecl); } // Deal with tag names. @@ -524,6 +523,7 @@ class ASTInfoCollector : public ASTReaderListener { IntrusiveRefCntPtr<TargetInfo> &Target; unsigned &Counter; bool InitializedLanguage = false; + bool InitializedHeaderSearchPaths = false; public: ASTInfoCollector(Preprocessor &PP, ASTContext *Context, @@ -550,11 +550,43 @@ public: bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, bool Complain) override { + // llvm::SaveAndRestore doesn't support bit field. + auto ForceCheckCXX20ModulesInputFiles = + this->HSOpts.ForceCheckCXX20ModulesInputFiles; + llvm::SaveAndRestore X(this->HSOpts.UserEntries); + llvm::SaveAndRestore Y(this->HSOpts.SystemHeaderPrefixes); + llvm::SaveAndRestore Z(this->HSOpts.VFSOverlayFiles); + this->HSOpts = HSOpts; + this->HSOpts.ForceCheckCXX20ModulesInputFiles = + ForceCheckCXX20ModulesInputFiles; + return false; } - bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, + bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts, + bool Complain) override { + if (InitializedHeaderSearchPaths) + return false; + + this->HSOpts.UserEntries = HSOpts.UserEntries; + this->HSOpts.SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes; + this->HSOpts.VFSOverlayFiles = HSOpts.VFSOverlayFiles; + + // Initialize the FileManager. We can't do this in update(), since that + // performs the initialization too late (once both target and language + // options are read). + PP.getFileManager().setVirtualFileSystem(createVFSFromOverlayFiles( + HSOpts.VFSOverlayFiles, PP.getDiagnostics(), + PP.getFileManager().getVirtualFileSystemPtr())); + + InitializedHeaderSearchPaths = true; + + return false; + } + + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool ReadMacros, bool Complain, std::string &SuggestedPredefines) override { this->PPOpts = PPOpts; return false; @@ -705,10 +737,10 @@ void FilterAndStoreDiagnosticConsumer::HandleDiagnostic( } if (StandaloneDiags) { - llvm::Optional<StoredDiagnostic> StoredDiag = None; + std::optional<StoredDiagnostic> StoredDiag; if (!ResultDiag) { StoredDiag.emplace(Level, Info); - ResultDiag = StoredDiag.getPointer(); + ResultDiag = &*StoredDiag; } StandaloneDiags->push_back( makeStandaloneDiagnostic(*LangOpts, *ResultDiag)); @@ -757,9 +789,10 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( const std::string &Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - const FileSystemOptions &FileSystemOpts, bool UseDebugInfo, - bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics, - bool AllowASTWithCompilerErrors, bool UserFilesAreVolatile) { + const FileSystemOptions &FileSystemOpts, + std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls, + CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors, + bool UserFilesAreVolatile, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { std::unique_ptr<ASTUnit> AST(new ASTUnit(true)); // Recover resources if we crash before exiting this method. @@ -775,16 +808,14 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->Diagnostics = Diags; - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = - llvm::vfs::getRealFileSystem(); AST->FileMgr = new FileManager(FileSystemOpts, VFS); AST->UserFilesAreVolatile = UserFilesAreVolatile; AST->SourceMgr = new SourceManager(AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile); AST->ModuleCache = new InMemoryModuleCache; - AST->HSOpts = std::make_shared<HeaderSearchOptions>(); - AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormat()); + AST->HSOpts = HSOpts ? HSOpts : std::make_shared<HeaderSearchOptions>(); + AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front()); AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, AST->getSourceManager(), AST->getDiagnostics(), @@ -795,7 +826,6 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( // Gather Info for preprocessor construction later on. HeaderSearch &HeaderInfo = *AST->HeaderInfo; - unsigned Counter; AST->PP = std::make_shared<Preprocessor>( AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts, @@ -817,8 +847,9 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( AST->Reader = new ASTReader( PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {}, /*isysroot=*/"", - /*DisableValidation=*/disableValid, AllowASTWithCompilerErrors); + /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors); + unsigned Counter = 0; AST->Reader->setListener(std::make_unique<ASTInfoCollector>( *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts, AST->TargetOpts, AST->Target, Counter)); @@ -832,7 +863,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( AST->Ctx->setExternalSource(AST->Reader); switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile, - SourceLocation(), ASTReader::ARR_None)) { + SourceLocation(), ASTReader::ARR_None)) { case ASTReader::Success: break; @@ -850,6 +881,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( PP.setCounterValue(Counter); + Module *M = HeaderInfo.lookupModule(AST->getLangOpts().CurrentModule); + if (M && AST->getLangOpts().isCompilingModule() && M->isNamedModule()) + AST->Ctx->setCurrentNamedModule(M); + // Create an AST consumer, even though it isn't used. if (ToLoad >= LoadASTOnly) AST->Consumer.reset(new ASTConsumer); @@ -1069,9 +1104,7 @@ static void checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &StoredDiags) { // Get rid of stored diagnostics except the ones from the driver which do not // have a source location. - StoredDiags.erase( - std::remove_if(StoredDiags.begin(), StoredDiags.end(), isNonDriverDiag), - StoredDiags.end()); + llvm::erase_if(StoredDiags, isNonDriverDiag); } static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & @@ -1116,6 +1149,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, // Create the compiler instance to use for building the AST. std::unique_ptr<CompilerInstance> Clang( new CompilerInstance(std::move(PCHContainerOps))); + Clang->setInvocation(CCInvocation); // Clean up on error, disengage it if the function returns successfully. auto CleanOnError = llvm::make_scope_exit([&]() { @@ -1142,7 +1176,6 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup(Clang.get()); - Clang->setInvocation(CCInvocation); OriginalSourceFile = std::string(Clang->getFrontendOpts().Inputs[0].getFile()); @@ -1305,7 +1338,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( return nullptr; PreambleBounds Bounds = ComputePreambleBounds( - *PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines); + PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines); if (!Bounds.Size) return nullptr; @@ -1352,7 +1385,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( SmallVector<StoredDiagnostic, 4> NewPreambleDiags; ASTUnitPreambleCallbacks Callbacks; { - llvm::Optional<CaptureDroppedDiagnostics> Capture; + std::optional<CaptureDroppedDiagnostics> Capture; if (CaptureDiagnostics != CaptureDiagsKind::None) Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags, &NewPreambleDiagsStandalone); @@ -1368,7 +1401,8 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build( PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS, - PCHContainerOps, /*StoreInMemory=*/false, Callbacks); + PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath, + Callbacks); PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = PreviousSkipFunctionBodies; @@ -1462,8 +1496,8 @@ StringRef ASTUnit::getMainFileName() const { } if (SourceMgr) { - if (const FileEntry * - FE = SourceMgr->getFileEntryForID(SourceMgr->getMainFileID())) + if (OptionalFileEntryRef FE = + SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID())) return FE->getName(); } @@ -1708,21 +1742,28 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( return AST; } -ASTUnit *ASTUnit::LoadFromCommandLine( +std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine( const char **ArgBegin, const char **ArgEnd, std::shared_ptr<PCHContainerOperations> PCHContainerOps, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, + bool StorePreamblesInMemory, StringRef PreambleStoragePath, bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics, ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind, bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion, bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization, - bool RetainExcludedConditionalBlocks, - llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST, + bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat, + std::unique_ptr<ASTUnit> *ErrAST, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { assert(Diags.get() && "no DiagnosticsEngine was provided"); + // If no VFS was provided, create one that tracks the physical file system. + // If '-working-directory' was passed as an argument, 'createInvocation' will + // set this as the current working directory of the VFS. + if (!VFS) + VFS = llvm::vfs::createPhysicalFileSystem(); + SmallVector<StoredDiagnostic, 4> StoredDiagnostics; std::shared_ptr<CompilerInvocation> CI; @@ -1731,8 +1772,11 @@ ASTUnit *ASTUnit::LoadFromCommandLine( CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, &StoredDiagnostics, nullptr); - CI = createInvocationFromCommandLine( - llvm::makeArrayRef(ArgBegin, ArgEnd), Diags, VFS); + CreateInvocationOptions CIOpts; + CIOpts.VFS = VFS; + CIOpts.Diags = Diags; + CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed? + CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts)); if (!CI) return nullptr; } @@ -1755,8 +1799,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile; if (ModuleFormat) - CI->getHeaderSearchOpts().ModuleFormat = - std::string(ModuleFormat.getValue()); + CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat); // Create the AST unit. std::unique_ptr<ASTUnit> AST; @@ -1766,10 +1809,10 @@ ASTUnit *ASTUnit::LoadFromCommandLine( ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; AST->FileSystemOpts = CI->getFileSystemOpts(); - if (!VFS) - VFS = llvm::vfs::getRealFileSystem(); VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS); AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); + AST->StorePreamblesInMemory = StorePreamblesInMemory; + AST->PreambleStoragePath = PreambleStoragePath; AST->ModuleCache = new InMemoryModuleCache; AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; @@ -1802,7 +1845,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( return nullptr; } - return AST.release(); + return AST; } bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, @@ -1924,9 +1967,10 @@ namespace { void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, unsigned NumCandidates, - SourceLocation OpenParLoc) override { + SourceLocation OpenParLoc, + bool Braced) override { Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates, - OpenParLoc); + OpenParLoc, Braced); } CodeCompletionAllocator &getAllocator() override { @@ -1967,7 +2011,8 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context, case CodeCompletionContext::CCC_SymbolOrNewName: case CodeCompletionContext::CCC_ParenthesizedExpression: case CodeCompletionContext::CCC_ObjCInterfaceName: - break; + case CodeCompletionContext::CCC_TopLevelOrExpression: + break; case CodeCompletionContext::CCC_EnumTag: case CodeCompletionContext::CCC_UnionTag: @@ -1989,7 +2034,9 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context, case CodeCompletionContext::CCC_ObjCClassMessage: case CodeCompletionContext::CCC_ObjCCategoryName: case CodeCompletionContext::CCC_IncludedFile: + case CodeCompletionContext::CCC_Attribute: case CodeCompletionContext::CCC_NewName: + case CodeCompletionContext::CCC_ObjCClassForwardDecl: // We're looking for nothing, or we're looking for names that cannot // be hidden. return; @@ -2124,7 +2171,8 @@ void ASTUnit::CodeComplete( std::shared_ptr<PCHContainerOperations> PCHContainerOps, DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr, FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, - SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { + SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers, + std::unique_ptr<SyntaxOnlyAction> Act) { if (!Invocation) return; @@ -2153,7 +2201,7 @@ void ASTUnit::CodeComplete( FrontendOpts.CodeCompletionAt.Column = Column; // Set the language options appropriately. - LangOpts = *CCInvocation->getLangOpts(); + LangOpts = CCInvocation->getLangOpts(); // Spell-checking and warnings are wasteful during code-completion. LangOpts.SpellChecking = false; @@ -2212,10 +2260,10 @@ void ASTUnit::CodeComplete( Clang->setCodeCompletionConsumer(AugmentedConsumer); auto getUniqueID = - [&FileMgr](StringRef Filename) -> Optional<llvm::sys::fs::UniqueID> { + [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> { if (auto Status = FileMgr.getVirtualFileSystem().status(Filename)) return Status->getUniqueID(); - return None; + return std::nullopt; }; auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) { @@ -2261,8 +2309,9 @@ void ASTUnit::CodeComplete( if (!Clang->getLangOpts().Modules) PreprocessorOpts.DetailedRecord = false; - std::unique_ptr<SyntaxOnlyAction> Act; - Act.reset(new SyntaxOnlyAction); + if (!Act) + Act.reset(new SyntaxOnlyAction); + if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { if (llvm::Error Err = Act->Execute()) { consumeError(std::move(Err)); // FIXME this drops errors on the floor. @@ -2275,16 +2324,11 @@ bool ASTUnit::Save(StringRef File) { if (HadModuleLoaderFatalFailure) return true; - // Write to a temporary file and later rename it to the actual file, to avoid - // possible race conditions. - SmallString<128> TempPath; - TempPath = File; - TempPath += "-%%%%%%%%"; // FIXME: Can we somehow regenerate the stat cache here, or do we need to // unconditionally create a stat cache when we parse the file? - if (llvm::Error Err = llvm::writeFileAtomically( - TempPath, File, [this](llvm::raw_ostream &Out) { + if (llvm::Error Err = llvm::writeToOutput( + File, [this](llvm::raw_ostream &Out) { return serialize(Out) ? llvm::make_error<llvm::StringError>( "ASTUnit serialization failed", llvm::inconvertibleErrorCode()) @@ -2296,12 +2340,9 @@ bool ASTUnit::Save(StringRef File) { return false; } -static bool serializeUnit(ASTWriter &Writer, - SmallVectorImpl<char> &Buffer, - Sema &S, - bool hasErrors, - raw_ostream &OS) { - Writer.WriteAST(S, std::string(), nullptr, "", hasErrors); +static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer, + Sema &S, raw_ostream &OS) { + Writer.WriteAST(S, std::string(), nullptr, ""); // Write the generated bitstream to "Out". if (!Buffer.empty()) @@ -2311,18 +2352,14 @@ static bool serializeUnit(ASTWriter &Writer, } bool ASTUnit::serialize(raw_ostream &OS) { - // For serialization we are lenient if the errors were only warn-as-error kind. - bool hasErrors = getDiagnostics().hasUncompilableErrorOccurred(); - if (WriterData) - return serializeUnit(WriterData->Writer, WriterData->Buffer, - getSema(), hasErrors, OS); + return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS); SmallString<128> Buffer; llvm::BitstreamWriter Stream(Buffer); InMemoryModuleCache ModuleCache; ASTWriter Writer(Stream, Buffer, ModuleCache, {}); - return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS); + return serializeUnit(Writer, Buffer, getSema(), OS); } using SLocRemap = ContinuousRangeMap<unsigned, int, 2>; @@ -2607,9 +2644,9 @@ bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) { return true; } -const FileEntry *ASTUnit::getPCHFile() { +OptionalFileEntryRef ASTUnit::getPCHFile() { if (!Reader) - return nullptr; + return std::nullopt; serialization::ModuleFile *Mod = nullptr; Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) { @@ -2632,7 +2669,7 @@ const FileEntry *ASTUnit::getPCHFile() { if (Mod) return Mod->File; - return nullptr; + return std::nullopt; } bool ASTUnit::isModuleFile() const { |