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.cpp103
1 files changed, 50 insertions, 53 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp
index 57d025b7c32e..e7a87dc6b23c 100644
--- a/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp
+++ b/contrib/llvm-project/clang/lib/Frontend/ASTUnit.cpp
@@ -69,6 +69,7 @@
#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"
@@ -757,9 +758,8 @@ 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, ArrayRef<RemappedFile> RemappedFiles,
- CaptureDiagsKind CaptureDiagnostics, bool AllowPCHWithCompilerErrors,
- bool UserFilesAreVolatile) {
+ bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
+ bool AllowASTWithCompilerErrors, bool UserFilesAreVolatile) {
std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
// Recover resources if we crash before exiting this method.
@@ -792,9 +792,6 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
/*Target=*/nullptr));
AST->PPOpts = std::make_shared<PreprocessorOptions>();
- for (const auto &RemappedFile : RemappedFiles)
- AST->PPOpts->addRemappedFile(RemappedFile.first, RemappedFile.second);
-
// Gather Info for preprocessor construction later on.
HeaderSearch &HeaderInfo = *AST->HeaderInfo;
@@ -812,13 +809,14 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
PP.getIdentifierTable(), PP.getSelectorTable(),
PP.getBuiltinInfo());
- bool disableValid = false;
+ DisableValidationForModuleKind disableValid =
+ DisableValidationForModuleKind::None;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
- disableValid = true;
+ disableValid = DisableValidationForModuleKind::All;
AST->Reader = new ASTReader(
PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
/*isysroot=*/"",
- /*DisableValidation=*/disableValid, AllowPCHWithCompilerErrors);
+ /*DisableValidation=*/disableValid, AllowASTWithCompilerErrors);
AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
*AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
@@ -1118,6 +1116,19 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
std::unique_ptr<CompilerInstance> Clang(
new CompilerInstance(std::move(PCHContainerOps)));
+ // Clean up on error, disengage it if the function returns successfully.
+ auto CleanOnError = llvm::make_scope_exit([&]() {
+ // Remove the overridden buffer we used for the preamble.
+ SavedMainFileBuffer = nullptr;
+
+ // Keep the ownership of the data in the ASTUnit because the client may
+ // want to see the diagnostics.
+ transferASTDataFromCompilerInstance(*Clang);
+ FailedParseDiagnostics.swap(StoredDiagnostics);
+ StoredDiagnostics.clear();
+ NumStoredDiagnosticsFromDriver = 0;
+ });
+
// Ensure that Clang has a FileManager with the right VFS, which may have
// changed above in AddImplicitPreamble. If VFS is nullptr, rely on
// createFileManager to create one.
@@ -1172,9 +1183,6 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
TopLevelDeclsInPreamble.clear();
}
- // Create a file manager object to provide access to and cache the filesystem.
- Clang->setFileManager(&getFileManager());
-
// Create the source manager.
Clang->setSourceManager(&getSourceManager());
@@ -1200,7 +1208,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
ActCleanup(Act.get());
if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
- goto error;
+ return true;
if (SavedMainFileBuffer)
TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
@@ -1210,7 +1218,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
if (llvm::Error Err = Act->Execute()) {
consumeError(std::move(Err)); // FIXME this drops errors on the floor.
- goto error;
+ return true;
}
transferASTDataFromCompilerInstance(*Clang);
@@ -1219,19 +1227,9 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
FailedParseDiagnostics.clear();
- return false;
-
-error:
- // Remove the overridden buffer we used for the preamble.
- SavedMainFileBuffer = nullptr;
+ CleanOnError.release();
- // Keep the ownership of the data in the ASTUnit because the client may
- // want to see the diagnostics.
- transferASTDataFromCompilerInstance(*Clang);
- FailedParseDiagnostics.swap(StoredDiagnostics);
- StoredDiagnostics.clear();
- NumStoredDiagnosticsFromDriver = 0;
- return true;
+ return false;
}
static std::pair<unsigned, unsigned>
@@ -1313,15 +1311,14 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
if (!MainFileBuffer)
return nullptr;
- PreambleBounds Bounds =
- ComputePreambleBounds(*PreambleInvocationIn.getLangOpts(),
- MainFileBuffer.get(), MaxLines);
+ PreambleBounds Bounds = ComputePreambleBounds(
+ *PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines);
if (!Bounds.Size)
return nullptr;
if (Preamble) {
- if (Preamble->CanReuse(PreambleInvocationIn, MainFileBuffer.get(), Bounds,
- VFS.get())) {
+ if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
+ *VFS)) {
// Okay! We can re-use the precompiled preamble.
// Set the state of the diagnostic object to mimic its state
@@ -1468,7 +1465,7 @@ StringRef ASTUnit::getMainFileName() const {
if (Input.isFile())
return Input.getFile();
else
- return Input.getBuffer()->getBufferIdentifier();
+ return Input.getBuffer().getBufferIdentifier();
}
if (SourceMgr) {
@@ -1517,8 +1514,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
- bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile,
- std::unique_ptr<ASTUnit> *ErrAST) {
+ bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
assert(CI && "A CompilerInvocation is required");
std::unique_ptr<ASTUnit> OwnAST;
@@ -1541,8 +1537,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
- AST->IncludeBriefCommentsInCodeCompletion
- = IncludeBriefCommentsInCodeCompletion;
+ AST->IncludeBriefCommentsInCodeCompletion = false;
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -2239,28 +2234,30 @@ void ASTUnit::CodeComplete(
= new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
Clang->setCodeCompletionConsumer(AugmentedConsumer);
+ auto getUniqueID =
+ [&FileMgr](StringRef Filename) -> Optional<llvm::sys::fs::UniqueID> {
+ if (auto Status = FileMgr.getVirtualFileSystem().status(Filename))
+ return Status->getUniqueID();
+ return None;
+ };
+
+ auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
+ if (LHS == RHS)
+ return true;
+ if (auto LHSID = getUniqueID(LHS))
+ if (auto RHSID = getUniqueID(RHS))
+ return *LHSID == *RHSID;
+ return false;
+ };
+
// If we have a precompiled preamble, try to use it. We only allow
// the use of the precompiled preamble if we're if the completion
// point is within the main file, after the end of the precompiled
// preamble.
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
- if (Preamble) {
- std::string CompleteFilePath(File);
-
- auto &VFS = FileMgr.getVirtualFileSystem();
- auto CompleteFileStatus = VFS.status(CompleteFilePath);
- if (CompleteFileStatus) {
- llvm::sys::fs::UniqueID CompleteFileID = CompleteFileStatus->getUniqueID();
-
- std::string MainPath(OriginalSourceFile);
- auto MainStatus = VFS.status(MainPath);
- if (MainStatus) {
- llvm::sys::fs::UniqueID MainID = MainStatus->getUniqueID();
- if (CompleteFileID == MainID && Line > 1)
- OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
- PCHContainerOps, Inv, &VFS, false, Line - 1);
- }
- }
+ if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
+ OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
+ PCHContainerOps, Inv, &FileMgr.getVirtualFileSystem(), false, Line - 1);
}
// If the main file has been overridden due to the use of a preamble,