This reverts commit 40334b8632f6d065e6672ada1c4342d07ecce629. Unfortunately the revert breaks the build.
167 lines
7.0 KiB
C++
167 lines
7.0 KiB
C++
//===--- CreateASTUnitFromArgs.h - Create an ASTUnit from Args ------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Utility for creating an ASTUnit from a vector of command line arguments.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Driver/CreateASTUnitFromArgs.h"
|
|
#include "clang/Driver/CreateInvocationFromArgs.h"
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
|
#include "clang/Lex/PreprocessorOptions.h"
|
|
#include "clang/Serialization/ModuleCache.h"
|
|
#include "llvm/Support/CrashRecoveryContext.h"
|
|
|
|
using namespace clang;
|
|
|
|
/// Create an ASTUnit from a vector of command line arguments, which must
|
|
/// specify exactly one source file.
|
|
///
|
|
/// \param ArgBegin - The beginning of the argument vector.
|
|
///
|
|
/// \param ArgEnd - The end of the argument vector.
|
|
///
|
|
/// \param PCHContainerOps - The PCHContainerOperations to use for loading and
|
|
/// creating modules.
|
|
///
|
|
/// \param Diags - The diagnostics engine to use for reporting errors; its
|
|
/// lifetime is expected to extend past that of the returned ASTUnit.
|
|
///
|
|
/// \param ResourceFilesPath - The path to the compiler resource files.
|
|
///
|
|
/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
|
|
/// PCH are stored in temporary files.
|
|
///
|
|
/// \param PreambleStoragePath - The path to a directory, in which to create
|
|
/// temporary PCH files. If empty, the default system temporary directory is
|
|
/// used. This parameter is ignored if \p StorePreamblesInMemory is true.
|
|
///
|
|
/// \param ModuleFormat - If provided, uses the specific module format.
|
|
///
|
|
/// \param ErrAST - If non-null and parsing failed without any AST to return
|
|
/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
|
|
/// mainly to allow the caller to see the diagnostics.
|
|
///
|
|
/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
|
|
/// Note that preamble is saved to a temporary directory on a RealFileSystem,
|
|
/// so in order for it to be loaded correctly, VFS should have access to
|
|
/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
|
|
/// if \p VFS is nullptr.
|
|
///
|
|
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
|
|
// shouldn't need to specify them at construction time.
|
|
std::unique_ptr<ASTUnit> clang::CreateASTUnitFromCommandLine(
|
|
const char **ArgBegin, const char **ArgEnd,
|
|
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
|
std::shared_ptr<DiagnosticOptions> DiagOpts,
|
|
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
|
|
bool StorePreamblesInMemory, StringRef PreambleStoragePath,
|
|
bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
|
|
ArrayRef<ASTUnit::RemappedFile> RemappedFiles,
|
|
bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses,
|
|
TranslationUnitKind TUKind, bool CacheCodeCompletionResults,
|
|
bool IncludeBriefCommentsInCodeCompletion, bool AllowPCHWithCompilerErrors,
|
|
SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse,
|
|
bool UserFilesAreVolatile, bool ForSerialization,
|
|
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;
|
|
|
|
{
|
|
CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
|
|
&StoredDiagnostics, nullptr);
|
|
|
|
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;
|
|
}
|
|
|
|
// Override any files that need remapping
|
|
for (const auto &RemappedFile : RemappedFiles) {
|
|
CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
|
|
RemappedFile.second);
|
|
}
|
|
PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
|
|
PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
|
|
PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
|
|
PPOpts.SingleFileParseMode = SingleFileParse;
|
|
PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
|
|
|
|
// Override the resources path.
|
|
CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
|
|
|
|
CI->getFrontendOpts().SkipFunctionBodies =
|
|
SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile;
|
|
|
|
if (ModuleFormat)
|
|
CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
|
|
|
|
// Create the AST unit.
|
|
std::unique_ptr<ASTUnit> AST;
|
|
AST.reset(new ASTUnit(false));
|
|
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
|
|
AST->StoredDiagnostics.swap(StoredDiagnostics);
|
|
ASTUnit::ConfigureDiags(Diags, *AST, CaptureDiagnostics);
|
|
AST->DiagOpts = DiagOpts;
|
|
AST->Diagnostics = Diags;
|
|
AST->FileSystemOpts = CI->getFileSystemOpts();
|
|
AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
|
|
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
|
|
AST->FileMgr =
|
|
llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
|
|
AST->StorePreamblesInMemory = StorePreamblesInMemory;
|
|
AST->PreambleStoragePath = PreambleStoragePath;
|
|
AST->ModCache = createCrossProcessModuleCache();
|
|
AST->OnlyLocalDecls = OnlyLocalDecls;
|
|
AST->CaptureDiagnostics = CaptureDiagnostics;
|
|
AST->TUKind = TUKind;
|
|
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
|
|
AST->IncludeBriefCommentsInCodeCompletion =
|
|
IncludeBriefCommentsInCodeCompletion;
|
|
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
|
AST->Invocation = CI;
|
|
AST->SkipFunctionBodies = SkipFunctionBodies;
|
|
if (ForSerialization)
|
|
AST->WriterData.reset(
|
|
new ASTUnit::ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
|
|
// Zero out now to ease cleanup during crash recovery.
|
|
CI = nullptr;
|
|
Diags = nullptr;
|
|
|
|
// Recover resources if we crash before exiting this method.
|
|
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get());
|
|
|
|
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
|
|
PrecompilePreambleAfterNParses, VFS)) {
|
|
// Some error occurred, if caller wants to examine diagnostics, pass it the
|
|
// ASTUnit.
|
|
if (ErrAST) {
|
|
AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
|
|
ErrAST->swap(AST);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
return AST;
|
|
}
|