1//===- ASTUnit.h - ASTUnit utility ------------------------------*- C++ -*-===//
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// ASTUnit utility class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
14#define LLVM_CLANG_FRONTEND_ASTUNIT_H
15
16#include "clang-c/Index.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/Basic/Diagnostic.h"
19#include "clang/Basic/FileSystemOptions.h"
20#include "clang/Basic/LLVM.h"
21#include "clang/Basic/LangOptions.h"
22#include "clang/Basic/SourceLocation.h"
23#include "clang/Basic/SourceManager.h"
24#include "clang/Basic/TargetOptions.h"
25#include "clang/Lex/HeaderSearchOptions.h"
26#include "clang/Lex/ModuleLoader.h"
27#include "clang/Lex/PreprocessingRecord.h"
28#include "clang/Sema/CodeCompleteConsumer.h"
29#include "clang/Serialization/ASTBitCodes.h"
30#include "clang/Frontend/PrecompiledPreamble.h"
31#include "llvm/ADT/ArrayRef.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/IntrusiveRefCntPtr.h"
34#include "llvm/ADT/STLExtras.h"
35#include "llvm/ADT/SmallVector.h"
36#include "llvm/ADT/StringMap.h"
37#include "llvm/ADT/StringRef.h"
38#include "llvm/ADT/iterator_range.h"
39#include <cassert>
40#include <cstddef>
41#include <cstdint>
42#include <memory>
43#include <optional>
44#include <string>
45#include <utility>
46#include <vector>
47
48namespace llvm {
49
50class MemoryBuffer;
51
52namespace vfs {
53
54class FileSystem;
55
56} // namespace vfs
57} // namespace llvm
58
59namespace clang {
60
61class ASTContext;
62class ASTDeserializationListener;
63class ASTMutationListener;
64class ASTReader;
65class CompilerInstance;
66class CompilerInvocation;
67class Decl;
68class FileEntry;
69class FileManager;
70class FrontendAction;
71class HeaderSearch;
72class InputKind;
73class InMemoryModuleCache;
74class PCHContainerOperations;
75class PCHContainerReader;
76class Preprocessor;
77class PreprocessorOptions;
78class Sema;
79class TargetInfo;
80class SyntaxOnlyAction;
81
82/// \brief Enumerates the available scopes for skipping function bodies.
83enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile };
84
85/// \brief Enumerates the available kinds for capturing diagnostics.
86enum class CaptureDiagsKind { None, All, AllWithoutNonErrorsFromIncludes };
87
88/// Utility class for loading a ASTContext from an AST file.
89class ASTUnit {
90public:
91 struct StandaloneFixIt {
92 std::pair<unsigned, unsigned> RemoveRange;
93 std::pair<unsigned, unsigned> InsertFromRange;
94 std::string CodeToInsert;
95 bool BeforePreviousInsertions;
96 };
97
98 struct StandaloneDiagnostic {
99 unsigned ID;
100 DiagnosticsEngine::Level Level;
101 std::string Message;
102 std::string Filename;
103 unsigned LocOffset;
104 std::vector<std::pair<unsigned, unsigned>> Ranges;
105 std::vector<StandaloneFixIt> FixIts;
106 };
107
108private:
109 std::shared_ptr<LangOptions> LangOpts;
110 IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
111 IntrusiveRefCntPtr<FileManager> FileMgr;
112 IntrusiveRefCntPtr<SourceManager> SourceMgr;
113 IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
114 std::unique_ptr<HeaderSearch> HeaderInfo;
115 IntrusiveRefCntPtr<TargetInfo> Target;
116 std::shared_ptr<Preprocessor> PP;
117 IntrusiveRefCntPtr<ASTContext> Ctx;
118 std::shared_ptr<TargetOptions> TargetOpts;
119 std::shared_ptr<HeaderSearchOptions> HSOpts;
120 std::shared_ptr<PreprocessorOptions> PPOpts;
121 IntrusiveRefCntPtr<ASTReader> Reader;
122 bool HadModuleLoaderFatalFailure = false;
123 bool StorePreamblesInMemory = false;
124
125 struct ASTWriterData;
126 std::unique_ptr<ASTWriterData> WriterData;
127
128 FileSystemOptions FileSystemOpts;
129 std::string PreambleStoragePath;
130
131 /// The AST consumer that received information about the translation
132 /// unit as it was parsed or loaded.
133 std::unique_ptr<ASTConsumer> Consumer;
134
135 /// The semantic analysis object used to type-check the translation
136 /// unit.
137 std::unique_ptr<Sema> TheSema;
138
139 /// Optional owned invocation, just used to make the invocation used in
140 /// LoadFromCommandLine available.
141 std::shared_ptr<CompilerInvocation> Invocation;
142
143 /// Fake module loader: the AST unit doesn't need to load any modules.
144 TrivialModuleLoader ModuleLoader;
145
146 // OnlyLocalDecls - when true, walking this AST should only visit declarations
147 // that come from the AST itself, not from included precompiled headers.
148 // FIXME: This is temporary; eventually, CIndex will always do this.
149 bool OnlyLocalDecls = false;
150
151 /// Whether to capture any diagnostics produced.
152 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None;
153
154 /// Track whether the main file was loaded from an AST or not.
155 bool MainFileIsAST;
156
157 /// What kind of translation unit this AST represents.
158 TranslationUnitKind TUKind = TU_Complete;
159
160 /// Whether we should time each operation.
161 bool WantTiming;
162
163 /// Whether the ASTUnit should delete the remapped buffers.
164 bool OwnsRemappedFileBuffers = true;
165
166 /// Track the top-level decls which appeared in an ASTUnit which was loaded
167 /// from a source file.
168 //
169 // FIXME: This is just an optimization hack to avoid deserializing large parts
170 // of a PCH file when using the Index library on an ASTUnit loaded from
171 // source. In the long term we should make the Index library use efficient and
172 // more scalable search mechanisms.
173 std::vector<Decl*> TopLevelDecls;
174
175 /// Sorted (by file offset) vector of pairs of file offset/Decl.
176 using LocDeclsTy = SmallVector<std::pair<unsigned, Decl *>, 64>;
177 using FileDeclsTy = llvm::DenseMap<FileID, std::unique_ptr<LocDeclsTy>>;
178
179 /// Map from FileID to the file-level declarations that it contains.
180 /// The files and decls are only local (and non-preamble) ones.
181 FileDeclsTy FileDecls;
182
183 /// The name of the original source file used to generate this ASTUnit.
184 std::string OriginalSourceFile;
185
186 /// The set of diagnostics produced when creating the preamble.
187 SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
188
189 /// The set of diagnostics produced when creating this
190 /// translation unit.
191 SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
192
193 /// The set of diagnostics produced when failing to parse, e.g. due
194 /// to failure to load the PCH.
195 SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics;
196
197 /// The number of stored diagnostics that come from the driver
198 /// itself.
199 ///
200 /// Diagnostics that come from the driver are retained from one parse to
201 /// the next.
202 unsigned NumStoredDiagnosticsFromDriver = 0;
203
204 /// Counter that determines when we want to try building a
205 /// precompiled preamble.
206 ///
207 /// If zero, we will never build a precompiled preamble. Otherwise,
208 /// it's treated as a counter that decrements each time we reparse
209 /// without the benefit of a precompiled preamble. When it hits 1,
210 /// we'll attempt to rebuild the precompiled header. This way, if
211 /// building the precompiled preamble fails, we won't try again for
212 /// some number of calls.
213 unsigned PreambleRebuildCountdown = 0;
214
215 /// Counter indicating how often the preamble was build in total.
216 unsigned PreambleCounter = 0;
217
218 /// Cache pairs "filename - source location"
219 ///
220 /// Cache contains only source locations from preamble so it is
221 /// guaranteed that they stay valid when the SourceManager is recreated.
222 /// This cache is used when loading preamble to increase performance
223 /// of that loading. It must be cleared when preamble is recreated.
224 llvm::StringMap<SourceLocation> PreambleSrcLocCache;
225
226 /// The contents of the preamble.
227 std::optional<PrecompiledPreamble> Preamble;
228
229 /// When non-NULL, this is the buffer used to store the contents of
230 /// the main file when it has been padded for use with the precompiled
231 /// preamble.
232 std::unique_ptr<llvm::MemoryBuffer> SavedMainFileBuffer;
233
234 /// The number of warnings that occurred while parsing the preamble.
235 ///
236 /// This value will be used to restore the state of the \c DiagnosticsEngine
237 /// object when re-using the precompiled preamble. Note that only the
238 /// number of warnings matters, since we will not save the preamble
239 /// when any errors are present.
240 unsigned NumWarningsInPreamble = 0;
241
242 /// A list of the serialization ID numbers for each of the top-level
243 /// declarations parsed within the precompiled preamble.
244 std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
245
246 /// Whether we should be caching code-completion results.
247 bool ShouldCacheCodeCompletionResults : 1;
248
249 /// Whether to include brief documentation within the set of code
250 /// completions cached.
251 bool IncludeBriefCommentsInCodeCompletion : 1;
252
253 /// True if non-system source files should be treated as volatile
254 /// (likely to change while trying to use them).
255 bool UserFilesAreVolatile : 1;
256
257 static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
258 ASTUnit &AST, CaptureDiagsKind CaptureDiagnostics);
259
260 void TranslateStoredDiagnostics(FileManager &FileMgr,
261 SourceManager &SrcMan,
262 const SmallVectorImpl<StandaloneDiagnostic> &Diags,
263 SmallVectorImpl<StoredDiagnostic> &Out);
264
265 void clearFileLevelDecls();
266
267public:
268 /// A cached code-completion result, which may be introduced in one of
269 /// many different contexts.
270 struct CachedCodeCompletionResult {
271 /// The code-completion string corresponding to this completion
272 /// result.
273 CodeCompletionString *Completion;
274
275 /// A bitmask that indicates which code-completion contexts should
276 /// contain this completion result.
277 ///
278 /// The bits in the bitmask correspond to the values of
279 /// CodeCompleteContext::Kind. To map from a completion context kind to a
280 /// bit, shift 1 by that number of bits. Many completions can occur in
281 /// several different contexts.
282 uint64_t ShowInContexts;
283
284 /// The priority given to this code-completion result.
285 unsigned Priority;
286
287 /// The libclang cursor kind corresponding to this code-completion
288 /// result.
289 CXCursorKind Kind;
290
291 /// The availability of this code-completion result.
292 CXAvailabilityKind Availability;
293
294 /// The simplified type class for a non-macro completion result.
295 SimplifiedTypeClass TypeClass;
296
297 /// The type of a non-macro completion result, stored as a unique
298 /// integer used by the string map of cached completion types.
299 ///
300 /// This value will be zero if the type is not known, or a unique value
301 /// determined by the formatted type string. Se \c CachedCompletionTypes
302 /// for more information.
303 unsigned Type;
304 };
305
306 /// Retrieve the mapping from formatted type names to unique type
307 /// identifiers.
308 llvm::StringMap<unsigned> &getCachedCompletionTypes() {
309 return CachedCompletionTypes;
310 }
311
312 /// Retrieve the allocator used to cache global code completions.
313 std::shared_ptr<GlobalCodeCompletionAllocator>
314 getCachedCompletionAllocator() {
315 return CachedCompletionAllocator;
316 }
317
318 CodeCompletionTUInfo &getCodeCompletionTUInfo() {
319 if (!CCTUInfo)
320 CCTUInfo = std::make_unique<CodeCompletionTUInfo>(
321 args: std::make_shared<GlobalCodeCompletionAllocator>());
322 return *CCTUInfo;
323 }
324
325private:
326 /// Allocator used to store cached code completions.
327 std::shared_ptr<GlobalCodeCompletionAllocator> CachedCompletionAllocator;
328
329 std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
330
331 /// The set of cached code-completion results.
332 std::vector<CachedCodeCompletionResult> CachedCompletionResults;
333
334 /// A mapping from the formatted type name to a unique number for that
335 /// type, which is used for type equality comparisons.
336 llvm::StringMap<unsigned> CachedCompletionTypes;
337
338 /// A string hash of the top-level declaration and macro definition
339 /// names processed the last time that we reparsed the file.
340 ///
341 /// This hash value is used to determine when we need to refresh the
342 /// global code-completion cache.
343 unsigned CompletionCacheTopLevelHashValue = 0;
344
345 /// A string hash of the top-level declaration and macro definition
346 /// names processed the last time that we reparsed the precompiled preamble.
347 ///
348 /// This hash value is used to determine when we need to refresh the
349 /// global code-completion cache after a rebuild of the precompiled preamble.
350 unsigned PreambleTopLevelHashValue = 0;
351
352 /// The current hash value for the top-level declaration and macro
353 /// definition names
354 unsigned CurrentTopLevelHashValue = 0;
355
356 /// Bit used by CIndex to mark when a translation unit may be in an
357 /// inconsistent state, and is not safe to free.
358 LLVM_PREFERRED_TYPE(bool)
359 unsigned UnsafeToFree : 1;
360
361 /// \brief Enumerator specifying the scope for skipping function bodies.
362 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
363
364 /// Cache any "global" code-completion results, so that we can avoid
365 /// recomputing them with each completion.
366 void CacheCodeCompletionResults();
367
368 /// Clear out and deallocate
369 void ClearCachedCompletionResults();
370
371 explicit ASTUnit(bool MainFileIsAST);
372
373 bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
374 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
375 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
376
377 std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
378 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
379 CompilerInvocation &PreambleInvocationIn,
380 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild = true,
381 unsigned MaxLines = 0);
382 void RealizeTopLevelDeclsFromPreamble();
383
384 /// Transfers ownership of the objects (like SourceManager) from
385 /// \param CI to this ASTUnit.
386 void transferASTDataFromCompilerInstance(CompilerInstance &CI);
387
388 /// Allows us to assert that ASTUnit is not being used concurrently,
389 /// which is not supported.
390 ///
391 /// Clients should create instances of the ConcurrencyCheck class whenever
392 /// using the ASTUnit in a way that isn't intended to be concurrent, which is
393 /// just about any usage.
394 /// Becomes a noop in release mode; only useful for debug mode checking.
395 class ConcurrencyState {
396 void *Mutex; // a std::recursive_mutex in debug;
397
398 public:
399 ConcurrencyState();
400 ~ConcurrencyState();
401
402 void start();
403 void finish();
404 };
405 ConcurrencyState ConcurrencyCheckValue;
406
407public:
408 friend class ConcurrencyCheck;
409
410 class ConcurrencyCheck {
411 ASTUnit &Self;
412
413 public:
414 explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) {
415 Self.ConcurrencyCheckValue.start();
416 }
417
418 ~ConcurrencyCheck() {
419 Self.ConcurrencyCheckValue.finish();
420 }
421 };
422
423 ASTUnit(const ASTUnit &) = delete;
424 ASTUnit &operator=(const ASTUnit &) = delete;
425 ~ASTUnit();
426
427 bool isMainFileAST() const { return MainFileIsAST; }
428
429 bool isUnsafeToFree() const { return UnsafeToFree; }
430 void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
431
432 const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
433 DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
434
435 const SourceManager &getSourceManager() const { return *SourceMgr; }
436 SourceManager &getSourceManager() { return *SourceMgr; }
437
438 const Preprocessor &getPreprocessor() const { return *PP; }
439 Preprocessor &getPreprocessor() { return *PP; }
440 std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; }
441
442 const ASTContext &getASTContext() const { return *Ctx; }
443 ASTContext &getASTContext() { return *Ctx; }
444
445 void setASTContext(ASTContext *ctx) { Ctx = ctx; }
446 void setPreprocessor(std::shared_ptr<Preprocessor> pp);
447
448 /// Enable source-range based diagnostic messages.
449 ///
450 /// If diagnostic messages with source-range information are to be expected
451 /// and AST comes not from file (e.g. after LoadFromCompilerInvocation) this
452 /// function has to be called.
453 /// The function is to be called only once and the AST should be associated
454 /// with the same source file afterwards.
455 void enableSourceFileDiagnostics();
456
457 bool hasSema() const { return (bool)TheSema; }
458
459 Sema &getSema() const {
460 assert(TheSema && "ASTUnit does not have a Sema object!");
461 return *TheSema;
462 }
463
464 const LangOptions &getLangOpts() const {
465 assert(LangOpts && "ASTUnit does not have language options");
466 return *LangOpts;
467 }
468
469 const HeaderSearchOptions &getHeaderSearchOpts() const {
470 assert(HSOpts && "ASTUnit does not have header search options");
471 return *HSOpts;
472 }
473
474 const PreprocessorOptions &getPreprocessorOpts() const {
475 assert(PPOpts && "ASTUnit does not have preprocessor options");
476 return *PPOpts;
477 }
478
479 const FileManager &getFileManager() const { return *FileMgr; }
480 FileManager &getFileManager() { return *FileMgr; }
481
482 const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
483
484 IntrusiveRefCntPtr<ASTReader> getASTReader() const;
485
486 StringRef getOriginalSourceFileName() const {
487 return OriginalSourceFile;
488 }
489
490 ASTMutationListener *getASTMutationListener();
491 ASTDeserializationListener *getDeserializationListener();
492
493 bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
494
495 bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; }
496 void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; }
497
498 StringRef getMainFileName() const;
499
500 /// If this ASTUnit came from an AST file, returns the filename for it.
501 StringRef getASTFileName() const;
502
503 using top_level_iterator = std::vector<Decl *>::iterator;
504
505 top_level_iterator top_level_begin() {
506 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
507 if (!TopLevelDeclsInPreamble.empty())
508 RealizeTopLevelDeclsFromPreamble();
509 return TopLevelDecls.begin();
510 }
511
512 top_level_iterator top_level_end() {
513 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
514 if (!TopLevelDeclsInPreamble.empty())
515 RealizeTopLevelDeclsFromPreamble();
516 return TopLevelDecls.end();
517 }
518
519 std::size_t top_level_size() const {
520 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
521 return TopLevelDeclsInPreamble.size() + TopLevelDecls.size();
522 }
523
524 bool top_level_empty() const {
525 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
526 return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty();
527 }
528
529 /// Add a new top-level declaration.
530 void addTopLevelDecl(Decl *D) {
531 TopLevelDecls.push_back(x: D);
532 }
533
534 /// Add a new local file-level declaration.
535 void addFileLevelDecl(Decl *D);
536
537 /// Get the decls that are contained in a file in the Offset/Length
538 /// range. \p Length can be 0 to indicate a point at \p Offset instead of
539 /// a range.
540 void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
541 SmallVectorImpl<Decl *> &Decls);
542
543 /// Retrieve a reference to the current top-level name hash value.
544 ///
545 /// Note: This is used internally by the top-level tracking action
546 unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; }
547
548 /// Get the source location for the given file:line:col triplet.
549 ///
550 /// The difference with SourceManager::getLocation is that this method checks
551 /// whether the requested location points inside the precompiled preamble
552 /// in which case the returned source location will be a "loaded" one.
553 SourceLocation getLocation(const FileEntry *File,
554 unsigned Line, unsigned Col) const;
555
556 /// Get the source location for the given file:offset pair.
557 SourceLocation getLocation(const FileEntry *File, unsigned Offset) const;
558
559 /// If \p Loc is a loaded location from the preamble, returns
560 /// the corresponding local location of the main file, otherwise it returns
561 /// \p Loc.
562 SourceLocation mapLocationFromPreamble(SourceLocation Loc) const;
563
564 /// If \p Loc is a local location of the main file but inside the
565 /// preamble chunk, returns the corresponding loaded location from the
566 /// preamble, otherwise it returns \p Loc.
567 SourceLocation mapLocationToPreamble(SourceLocation Loc) const;
568
569 bool isInPreambleFileID(SourceLocation Loc) const;
570 bool isInMainFileID(SourceLocation Loc) const;
571 SourceLocation getStartOfMainFileID() const;
572 SourceLocation getEndOfPreambleFileID() const;
573
574 /// \see mapLocationFromPreamble.
575 SourceRange mapRangeFromPreamble(SourceRange R) const {
576 return SourceRange(mapLocationFromPreamble(Loc: R.getBegin()),
577 mapLocationFromPreamble(Loc: R.getEnd()));
578 }
579
580 /// \see mapLocationToPreamble.
581 SourceRange mapRangeToPreamble(SourceRange R) const {
582 return SourceRange(mapLocationToPreamble(Loc: R.getBegin()),
583 mapLocationToPreamble(Loc: R.getEnd()));
584 }
585
586 unsigned getPreambleCounterForTests() const { return PreambleCounter; }
587
588 // Retrieve the diagnostics associated with this AST
589 using stored_diag_iterator = StoredDiagnostic *;
590 using stored_diag_const_iterator = const StoredDiagnostic *;
591
592 stored_diag_const_iterator stored_diag_begin() const {
593 return StoredDiagnostics.begin();
594 }
595
596 stored_diag_iterator stored_diag_begin() {
597 return StoredDiagnostics.begin();
598 }
599
600 stored_diag_const_iterator stored_diag_end() const {
601 return StoredDiagnostics.end();
602 }
603
604 stored_diag_iterator stored_diag_end() {
605 return StoredDiagnostics.end();
606 }
607
608 unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
609
610 stored_diag_iterator stored_diag_afterDriver_begin() {
611 if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size())
612 NumStoredDiagnosticsFromDriver = 0;
613 return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver;
614 }
615
616 using cached_completion_iterator =
617 std::vector<CachedCodeCompletionResult>::iterator;
618
619 cached_completion_iterator cached_completion_begin() {
620 return CachedCompletionResults.begin();
621 }
622
623 cached_completion_iterator cached_completion_end() {
624 return CachedCompletionResults.end();
625 }
626
627 unsigned cached_completion_size() const {
628 return CachedCompletionResults.size();
629 }
630
631 /// Returns an iterator range for the local preprocessing entities
632 /// of the local Preprocessor, if this is a parsed source file, or the loaded
633 /// preprocessing entities of the primary module if this is an AST file.
634 llvm::iterator_range<PreprocessingRecord::iterator>
635 getLocalPreprocessingEntities() const;
636
637 /// Type for a function iterating over a number of declarations.
638 /// \returns true to continue iteration and false to abort.
639 using DeclVisitorFn = bool (*)(void *context, const Decl *D);
640
641 /// Iterate over local declarations (locally parsed if this is a parsed
642 /// source file or the loaded declarations of the primary module if this is an
643 /// AST file).
644 /// \returns true if the iteration was complete or false if it was aborted.
645 bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn);
646
647 /// Get the PCH file if one was included.
648 OptionalFileEntryRef getPCHFile();
649
650 /// Returns true if the ASTUnit was constructed from a serialized
651 /// module file.
652 bool isModuleFile() const;
653
654 std::unique_ptr<llvm::MemoryBuffer>
655 getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr);
656
657 /// Determine what kind of translation unit this AST represents.
658 TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
659
660 /// Determine the input kind this AST unit represents.
661 InputKind getInputKind() const;
662
663 /// A mapping from a file name to the memory buffer that stores the
664 /// remapped contents of that file.
665 using RemappedFile = std::pair<std::string, llvm::MemoryBuffer *>;
666
667 /// Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
668 static std::unique_ptr<ASTUnit>
669 create(std::shared_ptr<CompilerInvocation> CI,
670 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
671 CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile);
672
673 enum WhatToLoad {
674 /// Load options and the preprocessor state.
675 LoadPreprocessorOnly,
676
677 /// Load the AST, but do not restore Sema state.
678 LoadASTOnly,
679
680 /// Load everything, including Sema.
681 LoadEverything
682 };
683
684 /// Create a ASTUnit from an AST file.
685 ///
686 /// \param Filename - The AST file to load.
687 ///
688 /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
689 /// creating modules.
690 /// \param Diags - The diagnostics engine to use for reporting errors; its
691 /// lifetime is expected to extend past that of the returned ASTUnit.
692 ///
693 /// \returns - The initialized ASTUnit or null if the AST failed to load.
694 static std::unique_ptr<ASTUnit> LoadFromASTFile(
695 const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
696 WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
697 const FileSystemOptions &FileSystemOpts,
698 std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls = false,
699 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
700 bool AllowASTWithCompilerErrors = false,
701 bool UserFilesAreVolatile = false,
702 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
703 llvm::vfs::getRealFileSystem());
704
705private:
706 /// Helper function for \c LoadFromCompilerInvocation() and
707 /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation.
708 ///
709 /// \param PrecompilePreambleAfterNParses After how many parses the preamble
710 /// of this translation unit should be precompiled, to improve the performance
711 /// of reparsing. Set to zero to disable preambles.
712 ///
713 /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
714 /// Note that preamble is saved to a temporary directory on a RealFileSystem,
715 /// so in order for it to be loaded correctly, VFS should have access to
716 /// it(i.e., be an overlay over RealFileSystem).
717 ///
718 /// \returns \c true if a catastrophic failure occurred (which means that the
719 /// \c ASTUnit itself is invalid), or \c false otherwise.
720 bool LoadFromCompilerInvocation(
721 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
722 unsigned PrecompilePreambleAfterNParses,
723 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
724
725public:
726 /// Create an ASTUnit from a source file, via a CompilerInvocation
727 /// object, by invoking the optionally provided ASTFrontendAction.
728 ///
729 /// \param CI - The compiler invocation to use; it must have exactly one input
730 /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
731 ///
732 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
733 /// creating modules.
734 ///
735 /// \param Diags - The diagnostics engine to use for reporting errors; its
736 /// lifetime is expected to extend past that of the returned ASTUnit.
737 ///
738 /// \param Action - The ASTFrontendAction to invoke. Its ownership is not
739 /// transferred.
740 ///
741 /// \param Unit - optionally an already created ASTUnit. Its ownership is not
742 /// transferred.
743 ///
744 /// \param Persistent - if true the returned ASTUnit will be complete.
745 /// false means the caller is only interested in getting info through the
746 /// provided \see Action.
747 ///
748 /// \param ErrAST - If non-null and parsing failed without any AST to return
749 /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
750 /// mainly to allow the caller to see the diagnostics.
751 /// This will only receive an ASTUnit if a new one was created. If an already
752 /// created ASTUnit was passed in \p Unit then the caller can check that.
753 ///
754 static ASTUnit *LoadFromCompilerInvocationAction(
755 std::shared_ptr<CompilerInvocation> CI,
756 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
757 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
758 FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
759 bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
760 bool OnlyLocalDecls = false,
761 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
762 unsigned PrecompilePreambleAfterNParses = 0,
763 bool CacheCodeCompletionResults = false,
764 bool UserFilesAreVolatile = false,
765 std::unique_ptr<ASTUnit> *ErrAST = nullptr);
766
767 /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
768 /// CompilerInvocation object.
769 ///
770 /// \param CI - The compiler invocation to use; it must have exactly one input
771 /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
772 ///
773 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
774 /// creating modules.
775 ///
776 /// \param Diags - The diagnostics engine to use for reporting errors; its
777 /// lifetime is expected to extend past that of the returned ASTUnit.
778 //
779 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
780 // shouldn't need to specify them at construction time.
781 static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
782 std::shared_ptr<CompilerInvocation> CI,
783 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
784 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
785 bool OnlyLocalDecls = false,
786 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
787 unsigned PrecompilePreambleAfterNParses = 0,
788 TranslationUnitKind TUKind = TU_Complete,
789 bool CacheCodeCompletionResults = false,
790 bool IncludeBriefCommentsInCodeCompletion = false,
791 bool UserFilesAreVolatile = false);
792
793 /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
794 /// arguments, which must specify exactly one source file.
795 ///
796 /// \param ArgBegin - The beginning of the argument vector.
797 ///
798 /// \param ArgEnd - The end of the argument vector.
799 ///
800 /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
801 /// creating modules.
802 ///
803 /// \param Diags - The diagnostics engine to use for reporting errors; its
804 /// lifetime is expected to extend past that of the returned ASTUnit.
805 ///
806 /// \param ResourceFilesPath - The path to the compiler resource files.
807 ///
808 /// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
809 /// PCH are stored in temporary files.
810 ///
811 /// \param PreambleStoragePath - The path to a directory, in which to create
812 /// temporary PCH files. If empty, the default system temporary directory is
813 /// used. This parameter is ignored if \p StorePreamblesInMemory is true.
814 ///
815 /// \param ModuleFormat - If provided, uses the specific module format.
816 ///
817 /// \param ErrAST - If non-null and parsing failed without any AST to return
818 /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
819 /// mainly to allow the caller to see the diagnostics.
820 ///
821 /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
822 /// Note that preamble is saved to a temporary directory on a RealFileSystem,
823 /// so in order for it to be loaded correctly, VFS should have access to
824 /// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
825 /// if \p VFS is nullptr.
826 ///
827 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
828 // shouldn't need to specify them at construction time.
829 static std::unique_ptr<ASTUnit> LoadFromCommandLine(
830 const char **ArgBegin, const char **ArgEnd,
831 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
832 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
833 bool StorePreamblesInMemory = false,
834 StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
835 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
836 ArrayRef<RemappedFile> RemappedFiles = std::nullopt,
837 bool RemappedFilesKeepOriginalName = true,
838 unsigned PrecompilePreambleAfterNParses = 0,
839 TranslationUnitKind TUKind = TU_Complete,
840 bool CacheCodeCompletionResults = false,
841 bool IncludeBriefCommentsInCodeCompletion = false,
842 bool AllowPCHWithCompilerErrors = false,
843 SkipFunctionBodiesScope SkipFunctionBodies =
844 SkipFunctionBodiesScope::None,
845 bool SingleFileParse = false, bool UserFilesAreVolatile = false,
846 bool ForSerialization = false,
847 bool RetainExcludedConditionalBlocks = false,
848 std::optional<StringRef> ModuleFormat = std::nullopt,
849 std::unique_ptr<ASTUnit> *ErrAST = nullptr,
850 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
851
852 /// Reparse the source files using the same command-line options that
853 /// were originally used to produce this translation unit.
854 ///
855 /// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
856 /// Note that preamble is saved to a temporary directory on a RealFileSystem,
857 /// so in order for it to be loaded correctly, VFS should give an access to
858 /// this(i.e. be an overlay over RealFileSystem).
859 /// FileMgr->getVirtualFileSystem() will be used if \p VFS is nullptr.
860 ///
861 /// \returns True if a failure occurred that causes the ASTUnit not to
862 /// contain any translation-unit information, false otherwise.
863 bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
864 ArrayRef<RemappedFile> RemappedFiles = std::nullopt,
865 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
866
867 /// Free data that will be re-generated on the next parse.
868 ///
869 /// Preamble-related data is not affected.
870 void ResetForParse();
871
872 /// Perform code completion at the given file, line, and
873 /// column within this translation unit.
874 ///
875 /// \param File The file in which code completion will occur.
876 ///
877 /// \param Line The line at which code completion will occur.
878 ///
879 /// \param Column The column at which code completion will occur.
880 ///
881 /// \param IncludeMacros Whether to include macros in the code-completion
882 /// results.
883 ///
884 /// \param IncludeCodePatterns Whether to include code patterns (such as a
885 /// for loop) in the code-completion results.
886 ///
887 /// \param IncludeBriefComments Whether to include brief documentation within
888 /// the set of code completions returned.
889 ///
890 /// \param Act If supplied, this argument is used to parse the input file,
891 /// allowing customized parsing by overriding SyntaxOnlyAction lifecycle
892 /// methods.
893 ///
894 /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
895 /// OwnedBuffers parameters are all disgusting hacks. They will go away.
896 void CodeComplete(StringRef File, unsigned Line, unsigned Column,
897 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
898 bool IncludeCodePatterns, bool IncludeBriefComments,
899 CodeCompleteConsumer &Consumer,
900 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
901 DiagnosticsEngine &Diag, LangOptions &LangOpts,
902 SourceManager &SourceMgr, FileManager &FileMgr,
903 SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
904 SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,
905 std::unique_ptr<SyntaxOnlyAction> Act);
906
907 /// Save this translation unit to a file with the given name.
908 ///
909 /// \returns true if there was a file error or false if the save was
910 /// successful.
911 bool Save(StringRef File);
912
913 /// Serialize this translation unit with the given output stream.
914 ///
915 /// \returns True if an error occurred, false otherwise.
916 bool serialize(raw_ostream &OS);
917};
918
919} // namespace clang
920
921#endif // LLVM_CLANG_FRONTEND_ASTUNIT_H
922

source code of clang/include/clang/Frontend/ASTUnit.h