brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · ea31a8e Raw
167 lines · cpp
1//===--- CreateASTUnitFromArgs.h - Create an ASTUnit from Args ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Utility for creating an ASTUnit from a vector of command line arguments.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Driver/CreateASTUnitFromArgs.h"14#include "clang/Driver/CreateInvocationFromArgs.h"15#include "clang/Frontend/CompilerInvocation.h"16#include "clang/Lex/PreprocessorOptions.h"17#include "clang/Serialization/ModuleCache.h"18#include "llvm/Support/CrashRecoveryContext.h"19 20using namespace clang;21 22/// Create an ASTUnit from a vector of command line arguments, which must23/// specify exactly one source file.24///25/// \param ArgBegin - The beginning of the argument vector.26///27/// \param ArgEnd - The end of the argument vector.28///29/// \param PCHContainerOps - The PCHContainerOperations to use for loading and30/// creating modules.31///32/// \param Diags - The diagnostics engine to use for reporting errors; its33/// lifetime is expected to extend past that of the returned ASTUnit.34///35/// \param ResourceFilesPath - The path to the compiler resource files.36///37/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,38/// PCH are stored in temporary files.39///40/// \param PreambleStoragePath - The path to a directory, in which to create41/// temporary PCH files. If empty, the default system temporary directory is42/// used. This parameter is ignored if \p StorePreamblesInMemory is true.43///44/// \param ModuleFormat - If provided, uses the specific module format.45///46/// \param ErrAST - If non-null and parsing failed without any AST to return47/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit48/// mainly to allow the caller to see the diagnostics.49///50/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.51/// Note that preamble is saved to a temporary directory on a RealFileSystem,52/// so in order for it to be loaded correctly, VFS should have access to53/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used54/// if \p VFS is nullptr.55///56// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we57// shouldn't need to specify them at construction time.58std::unique_ptr<ASTUnit> clang::CreateASTUnitFromCommandLine(59    const char **ArgBegin, const char **ArgEnd,60    std::shared_ptr<PCHContainerOperations> PCHContainerOps,61    std::shared_ptr<DiagnosticOptions> DiagOpts,62    IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,63    bool StorePreamblesInMemory, StringRef PreambleStoragePath,64    bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,65    ArrayRef<ASTUnit::RemappedFile> RemappedFiles,66    bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses,67    TranslationUnitKind TUKind, bool CacheCodeCompletionResults,68    bool IncludeBriefCommentsInCodeCompletion, bool AllowPCHWithCompilerErrors,69    SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse,70    bool UserFilesAreVolatile, bool ForSerialization,71    bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,72    std::unique_ptr<ASTUnit> *ErrAST,73    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {74  assert(Diags.get() && "no DiagnosticsEngine was provided");75 76  // If no VFS was provided, create one that tracks the physical file system.77  // If '-working-directory' was passed as an argument, 'createInvocation' will78  // set this as the current working directory of the VFS.79  if (!VFS)80    VFS = llvm::vfs::createPhysicalFileSystem();81 82  SmallVector<StoredDiagnostic, 4> StoredDiagnostics;83 84  std::shared_ptr<CompilerInvocation> CI;85 86  {87    CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,88                                      &StoredDiagnostics, nullptr);89 90    CreateInvocationOptions CIOpts;91    CIOpts.VFS = VFS;92    CIOpts.Diags = Diags;93    CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?94    CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));95    if (!CI)96      return nullptr;97  }98 99  // Override any files that need remapping100  for (const auto &RemappedFile : RemappedFiles) {101    CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,102                                              RemappedFile.second);103  }104  PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();105  PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;106  PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;107  PPOpts.SingleFileParseMode = SingleFileParse;108  PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;109 110  // Override the resources path.111  CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);112 113  CI->getFrontendOpts().SkipFunctionBodies =114      SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile;115 116  if (ModuleFormat)117    CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);118 119  // Create the AST unit.120  std::unique_ptr<ASTUnit> AST;121  AST.reset(new ASTUnit(false));122  AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();123  AST->StoredDiagnostics.swap(StoredDiagnostics);124  ASTUnit::ConfigureDiags(Diags, *AST, CaptureDiagnostics);125  AST->DiagOpts = DiagOpts;126  AST->Diagnostics = Diags;127  AST->FileSystemOpts = CI->getFileSystemOpts();128  AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());129  VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);130  AST->FileMgr =131      llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);132  AST->StorePreamblesInMemory = StorePreamblesInMemory;133  AST->PreambleStoragePath = PreambleStoragePath;134  AST->ModCache = createCrossProcessModuleCache();135  AST->OnlyLocalDecls = OnlyLocalDecls;136  AST->CaptureDiagnostics = CaptureDiagnostics;137  AST->TUKind = TUKind;138  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;139  AST->IncludeBriefCommentsInCodeCompletion =140      IncludeBriefCommentsInCodeCompletion;141  AST->UserFilesAreVolatile = UserFilesAreVolatile;142  AST->Invocation = CI;143  AST->SkipFunctionBodies = SkipFunctionBodies;144  if (ForSerialization)145    AST->WriterData.reset(146        new ASTUnit::ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));147  // Zero out now to ease cleanup during crash recovery.148  CI = nullptr;149  Diags = nullptr;150 151  // Recover resources if we crash before exiting this method.152  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get());153 154  if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),155                                      PrecompilePreambleAfterNParses, VFS)) {156    // Some error occurred, if caller wants to examine diagnostics, pass it the157    // ASTUnit.158    if (ErrAST) {159      AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);160      ErrAST->swap(AST);161    }162    return nullptr;163  }164 165  return AST;166}167