clang 22.0.0git
CreateASTUnitFromArgs.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Utility for creating an ASTUnit from a vector of command line arguments.
10//
11//===----------------------------------------------------------------------===//
12
18#include "llvm/Support/CrashRecoveryContext.h"
19
20using namespace clang;
21
22/// Create an ASTUnit from a vector of command line arguments, which must
23/// 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 and
30/// creating modules.
31///
32/// \param Diags - The diagnostics engine to use for reporting errors; its
33/// 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 create
41/// temporary PCH files. If empty, the default system temporary directory is
42/// 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 return
47/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
48/// 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 to
53/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
54/// if \p VFS is nullptr.
55///
56// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
57// 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,
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,
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' will
78 // 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
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 remapping
100 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 =
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 the
157 // ASTUnit.
158 if (ErrAST) {
159 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
160 ErrAST->swap(AST);
161 }
162 return nullptr;
163 }
164
165 return AST;
166}
Utility class for loading a ASTContext from an AST file.
Definition ASTUnit.h:93
RAII object that optionally captures and filters diagnostics, if there is no diagnostic client to cap...
Definition ASTUnit.h:935
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
bool RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
bool SingleFileParseMode
When enabled, preprocessor is in a mode for parsing a single file only.
bool RetainExcludedConditionalBlocks
When enabled, excluded conditional blocks retain in the main file.
bool AllowPCHWithCompilerErrors
When true, a PCH with compiler errors will not be rejected.
The JSON file list parser is used to communicate input to InstallAPI.
std::unique_ptr< ASTUnit > CreateASTUnitFromCommandLine(const char **ArgBegin, const char **ArgEnd, std::shared_ptr< PCHContainerOperations > PCHContainerOps, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, StringRef ResourceFilesPath, bool StorePreamblesInMemory=false, StringRef PreambleStoragePath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, ArrayRef< ASTUnit::RemappedFile > RemappedFiles={}, bool RemappedFilesKeepOriginalName=true, unsigned PrecompilePreambleAfterNParses=0, TranslationUnitKind TUKind=TU_Complete, bool CacheCodeCompletionResults=false, bool IncludeBriefCommentsInCodeCompletion=false, bool AllowPCHWithCompilerErrors=false, SkipFunctionBodiesScope SkipFunctionBodies=SkipFunctionBodiesScope::None, bool SingleFileParse=false, bool UserFilesAreVolatile=false, bool ForSerialization=false, bool RetainExcludedConditionalBlocks=false, std::optional< StringRef > ModuleFormat=std::nullopt, std::unique_ptr< ASTUnit > *ErrAST=nullptr, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Create an ASTUnit from a vector of command line arguments, which must specify exactly one source file...
SkipFunctionBodiesScope
Enumerates the available scopes for skipping function bodies.
Definition ASTUnit.h:87
std::unique_ptr< CompilerInvocation > createInvocation(ArrayRef< const char * > Args, CreateInvocationOptions Opts={})
Interpret clang arguments in preparation to parse a file.
CaptureDiagsKind
Enumerates the available kinds for capturing diagnostics.
Definition ASTUnit.h:90
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
IntrusiveRefCntPtr< ModuleCache > createCrossProcessModuleCache()
Creates new ModuleCache backed by a file system directory that may be operated on by multiple process...
TranslationUnitKind
Describes the kind of translation unit being processed.
Optional inputs to createInvocation.
IntrusiveRefCntPtr< DiagnosticsEngine > Diags
Receives diagnostics encountered while parsing command-line flags.
bool ProbePrecompiled
Allow the driver to probe the filesystem for PCH files.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
Used e.g.