aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp171
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 {