clang 22.0.0git
ASTUnit.cpp
Go to the documentation of this file.
1//===- ASTUnit.cpp - ASTUnit utility --------------------------------------===//
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 Implementation.
10//
11//===----------------------------------------------------------------------===//
12
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclBase.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclGroup.h"
21#include "clang/AST/DeclObjC.h"
26#include "clang/AST/Type.h"
31#include "clang/Basic/LLVM.h"
34#include "clang/Basic/Module.h"
50#include "clang/Lex/Lexer.h"
55#include "clang/Lex/Token.h"
58#include "clang/Sema/Sema.h"
65#include "llvm/ADT/ArrayRef.h"
66#include "llvm/ADT/DenseMap.h"
67#include "llvm/ADT/IntrusiveRefCntPtr.h"
68#include "llvm/ADT/STLExtras.h"
69#include "llvm/ADT/ScopeExit.h"
70#include "llvm/ADT/SmallVector.h"
71#include "llvm/ADT/StringMap.h"
72#include "llvm/ADT/StringRef.h"
73#include "llvm/ADT/StringSet.h"
74#include "llvm/ADT/Twine.h"
75#include "llvm/ADT/iterator_range.h"
76#include "llvm/Bitstream/BitstreamWriter.h"
77#include "llvm/Support/Allocator.h"
78#include "llvm/Support/CrashRecoveryContext.h"
79#include "llvm/Support/DJB.h"
80#include "llvm/Support/ErrorHandling.h"
81#include "llvm/Support/ErrorOr.h"
82#include "llvm/Support/MemoryBuffer.h"
83#include "llvm/Support/SaveAndRestore.h"
84#include "llvm/Support/Timer.h"
85#include "llvm/Support/VirtualFileSystem.h"
86#include "llvm/Support/raw_ostream.h"
87#include <algorithm>
88#include <atomic>
89#include <cassert>
90#include <cstdint>
91#include <cstdio>
92#include <cstdlib>
93#include <memory>
94#include <mutex>
95#include <optional>
96#include <string>
97#include <tuple>
98#include <utility>
99#include <vector>
100
101using namespace clang;
102
103using llvm::TimeRecord;
104
105namespace {
106
107 class SimpleTimer {
108 bool WantTiming;
109 TimeRecord Start;
110 std::string Output;
111
112 public:
113 explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {
114 if (WantTiming)
115 Start = TimeRecord::getCurrentTime();
116 }
117
118 ~SimpleTimer() {
119 if (WantTiming) {
120 TimeRecord Elapsed = TimeRecord::getCurrentTime();
121 Elapsed -= Start;
122 llvm::errs() << Output << ':';
123 Elapsed.print(Elapsed, llvm::errs());
124 llvm::errs() << '\n';
125 }
126 }
127
128 void setOutput(const Twine &Output) {
129 if (WantTiming)
130 this->Output = Output.str();
131 }
132 };
133
134} // namespace
135
136template <class T>
137static std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
138 if (!Val)
139 return nullptr;
140 return std::move(*Val);
141}
142
143template <class T>
144static bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
145 if (!Val)
146 return false;
147 Output = std::move(*Val);
148 return true;
149}
150
151/// Get a source buffer for \p MainFilePath, handling all file-to-file
152/// and file-to-buffer remappings inside \p Invocation.
153static std::unique_ptr<llvm::MemoryBuffer>
155 llvm::vfs::FileSystem *VFS,
156 StringRef FilePath, bool isVolatile) {
157 const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
158
159 // Try to determine if the main file has been remapped, either from the
160 // command line (to another file) or directly through the compiler
161 // invocation (to a memory buffer).
162 llvm::MemoryBuffer *Buffer = nullptr;
163 std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
164 auto FileStatus = VFS->status(FilePath);
165 if (FileStatus) {
166 llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();
167
168 // Check whether there is a file-file remapping of the main file
169 for (const auto &RF : PreprocessorOpts.RemappedFiles) {
170 std::string MPath(RF.first);
171 auto MPathStatus = VFS->status(MPath);
172 if (MPathStatus) {
173 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
174 if (MainFileID == MID) {
175 // We found a remapping. Try to load the resulting, remapped source.
176 BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second, -1, true, isVolatile));
177 if (!BufferOwner)
178 return nullptr;
179 }
180 }
181 }
182
183 // Check whether there is a file-buffer remapping. It supercedes the
184 // file-file remapping.
185 for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
186 std::string MPath(RB.first);
187 auto MPathStatus = VFS->status(MPath);
188 if (MPathStatus) {
189 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
190 if (MainFileID == MID) {
191 // We found a remapping.
192 BufferOwner.reset();
193 Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
194 }
195 }
196 }
197 }
198
199 // If the main source file was not remapped, load it now.
200 if (!Buffer && !BufferOwner) {
201 BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));
202 if (!BufferOwner)
203 return nullptr;
204 }
205
206 if (BufferOwner)
207 return BufferOwner;
208 if (!Buffer)
209 return nullptr;
210 return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
211}
212
215 llvm::BitstreamWriter Stream;
217
218 ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts)
219 : Stream(Buffer), Writer(Stream, Buffer, ModCache, CGOpts, {}) {}
220};
221
222void ASTUnit::clearFileLevelDecls() {
223 FileDecls.clear();
224}
225
226/// After failing to build a precompiled preamble (due to
227/// errors in the source that occurs in the preamble), the number of
228/// reparses during which we'll skip even trying to precompile the
229/// preamble.
231
232/// Tracks the number of ASTUnit objects that are currently active.
233///
234/// Used for debugging purposes only.
235static std::atomic<unsigned> ActiveASTUnitObjects;
236
237ASTUnit::ASTUnit(bool _MainFileIsAST)
238 : CodeGenOpts(std::make_unique<CodeGenOptions>()),
239 MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),
240 ShouldCacheCodeCompletionResults(false),
241 IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
242 UnsafeToFree(false) {
243 if (getenv("LIBCLANG_OBJTRACKING"))
244 fprintf(stderr, "+++ %u translation units\n", ++ActiveASTUnitObjects);
245}
246
248 // If we loaded from an AST file, balance out the BeginSourceFile call.
249 if (MainFileIsAST && getDiagnostics().getClient()) {
251 }
252
253 clearFileLevelDecls();
254
255 // Free the buffers associated with remapped files. We are required to
256 // perform this operation here because we explicitly request that the
257 // compiler instance *not* free these buffers for each invocation of the
258 // parser.
259 if (Invocation && OwnsRemappedFileBuffers) {
260 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
261 for (const auto &RB : PPOpts.RemappedFileBuffers)
262 delete RB.second;
263 }
264
265 ClearCachedCompletionResults();
266
267 if (getenv("LIBCLANG_OBJTRACKING"))
268 fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects);
269}
270
271void ASTUnit::setPreprocessor(std::shared_ptr<Preprocessor> PP) {
272 this->PP = std::move(PP);
273}
274
276 assert(getDiagnostics().getClient() && Ctx &&
277 "Bad context for source file");
278 getDiagnostics().getClient()->BeginSourceFile(Ctx->getLangOpts(), PP.get());
279}
280
281/// Determine the set of code-completion contexts in which this
282/// declaration should be shown.
283static uint64_t getDeclShowContexts(const NamedDecl *ND,
284 const LangOptions &LangOpts,
285 bool &IsNestedNameSpecifier) {
286 IsNestedNameSpecifier = false;
287
288 if (isa<UsingShadowDecl>(ND))
289 ND = ND->getUnderlyingDecl();
290 if (!ND)
291 return 0;
292
293 uint64_t Contexts = 0;
294 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||
297 // Types can appear in these contexts.
298 if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
299 Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
305
306 // In C++, types can appear in expressions contexts (for functional casts).
307 if (LangOpts.CPlusPlus)
308 Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
309
310 // In Objective-C, message sends can send interfaces. In Objective-C++,
311 // all types are available due to functional casts.
312 if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
314
315 // In Objective-C, you can only be a subclass of another Objective-C class
316 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
317 // Objective-C interfaces can be used in a class property expression.
318 if (ID->getDefinition())
319 Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
322 }
323
324 // Deal with tag names.
325 if (isa<EnumDecl>(ND)) {
326 Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);
327
328 // Part of the nested-name-specifier in C++0x.
329 if (LangOpts.CPlusPlus11)
330 IsNestedNameSpecifier = true;
331 } else if (const auto *Record = dyn_cast<RecordDecl>(ND)) {
332 if (Record->isUnion())
333 Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);
334 else
336
337 if (LangOpts.CPlusPlus)
338 IsNestedNameSpecifier = true;
339 } else if (isa<ClassTemplateDecl>(ND))
340 IsNestedNameSpecifier = true;
341 } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
342 // Values can appear in these contexts.
343 Contexts = (1LL << CodeCompletionContext::CCC_Statement)
347 } else if (isa<ObjCProtocolDecl>(ND)) {
349 } else if (isa<ObjCCategoryDecl>(ND)) {
351 } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
352 Contexts = (1LL << CodeCompletionContext::CCC_Namespace);
353
354 // Part of the nested-name-specifier.
355 IsNestedNameSpecifier = true;
356 }
357
358 return Contexts;
359}
360
361void ASTUnit::CacheCodeCompletionResults() {
362 if (!TheSema)
363 return;
364
365 SimpleTimer Timer(WantTiming);
366 Timer.setOutput("Cache global code completions for " + getMainFileName());
367
368 // Clear out the previous results.
369 ClearCachedCompletionResults();
370
371 // Gather the set of global code completions.
372 using Result = CodeCompletionResult;
373 SmallVector<Result, 8> Results;
374 CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
375 CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
376 TheSema->CodeCompletion().GatherGlobalCodeCompletions(
377 *CachedCompletionAllocator, CCTUInfo, Results);
378
379 // Translate global code completions into cached completions.
380 llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
381 CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel);
382
383 for (auto &R : Results) {
384 switch (R.Kind) {
385 case Result::RK_Declaration: {
386 bool IsNestedNameSpecifier = false;
387 CachedCodeCompletionResult CachedResult;
388 CachedResult.Completion = R.CreateCodeCompletionString(
389 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
390 IncludeBriefCommentsInCodeCompletion);
391 CachedResult.ShowInContexts = getDeclShowContexts(
392 R.Declaration, Ctx->getLangOpts(), IsNestedNameSpecifier);
393 CachedResult.Priority = R.Priority;
394 CachedResult.Kind = R.CursorKind;
395 CachedResult.Availability = R.Availability;
396
397 // Keep track of the type of this completion in an ASTContext-agnostic
398 // way.
399 QualType UsageType = getDeclUsageType(*Ctx, R.Qualifier, R.Declaration);
400 if (UsageType.isNull()) {
401 CachedResult.TypeClass = STC_Void;
402 CachedResult.Type = 0;
403 } else {
404 CanQualType CanUsageType
405 = Ctx->getCanonicalType(UsageType.getUnqualifiedType());
406 CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);
407
408 // Determine whether we have already seen this type. If so, we save
409 // ourselves the work of formatting the type string by using the
410 // temporary, CanQualType-based hash table to find the associated value.
411 unsigned &TypeValue = CompletionTypes[CanUsageType];
412 if (TypeValue == 0) {
413 TypeValue = CompletionTypes.size();
414 CachedCompletionTypes[QualType(CanUsageType).getAsString()]
415 = TypeValue;
416 }
417
418 CachedResult.Type = TypeValue;
419 }
420
421 CachedCompletionResults.push_back(CachedResult);
422
423 /// Handle nested-name-specifiers in C++.
424 if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&
425 !R.StartsNestedNameSpecifier) {
426 // The contexts in which a nested-name-specifier can appear in C++.
427 uint64_t NNSContexts
440
441 if (isa<NamespaceDecl>(R.Declaration) ||
442 isa<NamespaceAliasDecl>(R.Declaration))
443 NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);
444
445 if (uint64_t RemainingContexts
446 = NNSContexts & ~CachedResult.ShowInContexts) {
447 // If there any contexts where this completion can be a
448 // nested-name-specifier but isn't already an option, create a
449 // nested-name-specifier completion.
450 R.StartsNestedNameSpecifier = true;
451 CachedResult.Completion = R.CreateCodeCompletionString(
452 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
453 IncludeBriefCommentsInCodeCompletion);
454 CachedResult.ShowInContexts = RemainingContexts;
455 CachedResult.Priority = CCP_NestedNameSpecifier;
456 CachedResult.TypeClass = STC_Void;
457 CachedResult.Type = 0;
458 CachedCompletionResults.push_back(CachedResult);
459 }
460 }
461 break;
462 }
463
464 case Result::RK_Keyword:
465 case Result::RK_Pattern:
466 // Ignore keywords and patterns; we don't care, since they are so
467 // easily regenerated.
468 break;
469
470 case Result::RK_Macro: {
471 CachedCodeCompletionResult CachedResult;
472 CachedResult.Completion = R.CreateCodeCompletionString(
473 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
474 IncludeBriefCommentsInCodeCompletion);
475 CachedResult.ShowInContexts
488
489 CachedResult.Priority = R.Priority;
490 CachedResult.Kind = R.CursorKind;
491 CachedResult.Availability = R.Availability;
492 CachedResult.TypeClass = STC_Void;
493 CachedResult.Type = 0;
494 CachedCompletionResults.push_back(CachedResult);
495 break;
496 }
497 }
498 }
499
500 // Save the current top-level hash value.
501 CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
502}
503
504void ASTUnit::ClearCachedCompletionResults() {
505 CachedCompletionResults.clear();
506 CachedCompletionTypes.clear();
507 CachedCompletionAllocator = nullptr;
508}
509
510namespace {
511
512/// Gathers information from ASTReader that will be used to initialize
513/// a Preprocessor.
514class ASTInfoCollector : public ASTReaderListener {
515 HeaderSearchOptions &HSOpts;
516 std::string &SpecificModuleCachePath;
517 PreprocessorOptions &PPOpts;
518 LangOptions &LangOpts;
519 CodeGenOptions &CodeGenOpts;
520 TargetOptions &TargetOpts;
521 unsigned &Counter;
522
523public:
524 ASTInfoCollector(HeaderSearchOptions &HSOpts,
525 std::string &SpecificModuleCachePath,
526 PreprocessorOptions &PPOpts, LangOptions &LangOpts,
527 CodeGenOptions &CodeGenOpts, TargetOptions &TargetOpts,
528 unsigned &Counter)
529 : HSOpts(HSOpts), SpecificModuleCachePath(SpecificModuleCachePath),
530 PPOpts(PPOpts), LangOpts(LangOpts), CodeGenOpts(CodeGenOpts),
531 TargetOpts(TargetOpts), Counter(Counter) {}
532
533 bool ReadLanguageOptions(const LangOptions &NewLangOpts,
534 StringRef ModuleFilename, bool Complain,
535 bool AllowCompatibleDifferences) override {
536 LangOpts = NewLangOpts;
537 return false;
538 }
539
540 bool ReadCodeGenOptions(const CodeGenOptions &NewCodeGenOpts,
541 StringRef ModuleFilename, bool Complain,
542 bool AllowCompatibleDifferences) override {
543 CodeGenOpts = NewCodeGenOpts;
544 return false;
545 }
546
547 bool ReadHeaderSearchOptions(const HeaderSearchOptions &NewHSOpts,
548 StringRef ModuleFilename,
549 StringRef NewSpecificModuleCachePath,
550 bool Complain) override {
551 HSOpts = NewHSOpts;
552 SpecificModuleCachePath = NewSpecificModuleCachePath;
553 return false;
554 }
555
556 bool ReadHeaderSearchPaths(const HeaderSearchOptions &NewHSOpts,
557 bool Complain) override {
558 HSOpts.UserEntries = NewHSOpts.UserEntries;
560 HSOpts.VFSOverlayFiles = NewHSOpts.VFSOverlayFiles;
561 return false;
562 }
563
564 bool ReadPreprocessorOptions(const PreprocessorOptions &NewPPOpts,
565 StringRef ModuleFilename, bool ReadMacros,
566 bool Complain,
567 std::string &SuggestedPredefines) override {
568 PPOpts = NewPPOpts;
569 return false;
570 }
571
572 bool ReadTargetOptions(const TargetOptions &NewTargetOpts,
573 StringRef ModuleFilename, bool Complain,
574 bool AllowCompatibleDifferences) override {
575 TargetOpts = NewTargetOpts;
576 return false;
577 }
578
579 void ReadCounter(const serialization::ModuleFile &M,
580 unsigned NewCounter) override {
581 Counter = NewCounter;
582 }
583};
584
585/// Diagnostic consumer that saves each diagnostic it is given.
586class FilterAndStoreDiagnosticConsumer : public DiagnosticConsumer {
587 SmallVectorImpl<StoredDiagnostic> *StoredDiags;
588 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags;
589 bool CaptureNonErrorsFromIncludes = true;
590 const LangOptions *LangOpts = nullptr;
591 SourceManager *SourceMgr = nullptr;
592
593public:
594 FilterAndStoreDiagnosticConsumer(
595 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
596 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags,
597 bool CaptureNonErrorsFromIncludes)
598 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
599 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
600 assert((StoredDiags || StandaloneDiags) &&
601 "No output collections were passed to StoredDiagnosticConsumer.");
602 }
603
604 void BeginSourceFile(const LangOptions &LangOpts,
605 const Preprocessor *PP = nullptr) override {
606 this->LangOpts = &LangOpts;
607 if (PP)
608 SourceMgr = &PP->getSourceManager();
609 }
610
611 void HandleDiagnostic(DiagnosticsEngine::Level Level,
612 const Diagnostic &Info) override;
613};
614
615/// RAII object that optionally captures and filters diagnostics, if
616/// there is no diagnostic client to capture them already.
617class CaptureDroppedDiagnostics {
618 DiagnosticsEngine &Diags;
619 FilterAndStoreDiagnosticConsumer Client;
620 DiagnosticConsumer *PreviousClient = nullptr;
621 std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
622
623public:
624 CaptureDroppedDiagnostics(
625 CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
626 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
627 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
628 : Diags(Diags),
629 Client(StoredDiags, StandaloneDiags,
630 CaptureDiagnostics !=
632 if (CaptureDiagnostics != CaptureDiagsKind::None ||
633 Diags.getClient() == nullptr) {
634 OwningPreviousClient = Diags.takeClient();
635 PreviousClient = Diags.getClient();
636 Diags.setClient(&Client, false);
637 }
638 }
639
640 ~CaptureDroppedDiagnostics() {
641 if (Diags.getClient() == &Client)
642 Diags.setClient(PreviousClient, !!OwningPreviousClient.release());
643 }
644};
645
646} // namespace
647
650 const StoredDiagnostic &InDiag);
651
652static bool isInMainFile(const clang::Diagnostic &D) {
653 if (!D.hasSourceManager() || !D.getLocation().isValid())
654 return false;
655
656 auto &M = D.getSourceManager();
657 return M.isWrittenInMainFile(M.getExpansionLoc(D.getLocation()));
658}
659
660void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
661 DiagnosticsEngine::Level Level, const Diagnostic &Info) {
662 // Default implementation (Warnings/errors count).
664
665 // Only record the diagnostic if it's part of the source manager we know
666 // about. This effectively drops diagnostics from modules we're building.
667 // FIXME: In the long run, ee don't want to drop source managers from modules.
668 if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) {
669 if (!CaptureNonErrorsFromIncludes && Level <= DiagnosticsEngine::Warning &&
670 !isInMainFile(Info)) {
671 return;
672 }
673
674 StoredDiagnostic *ResultDiag = nullptr;
675 if (StoredDiags) {
676 StoredDiags->emplace_back(Level, Info);
677 ResultDiag = &StoredDiags->back();
678 }
679
680 if (StandaloneDiags) {
681 std::optional<StoredDiagnostic> StoredDiag;
682 if (!ResultDiag) {
683 StoredDiag.emplace(Level, Info);
684 ResultDiag = &*StoredDiag;
685 }
686 StandaloneDiags->push_back(
687 makeStandaloneDiagnostic(*LangOpts, *ResultDiag));
688 }
689 }
690}
691
693 return Reader;
694}
695
697 if (WriterData)
698 return &WriterData->Writer;
699 return nullptr;
700}
701
703 if (WriterData)
704 return &WriterData->Writer;
705 return nullptr;
706}
707
708std::unique_ptr<llvm::MemoryBuffer>
709ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
710 assert(FileMgr);
711 auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
712 if (Buffer)
713 return std::move(*Buffer);
714 if (ErrorStr)
715 *ErrorStr = Buffer.getError().message();
716 return nullptr;
717}
718
719/// Configure the diagnostics object for use with ASTUnit.
720void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
721 ASTUnit &AST,
722 CaptureDiagsKind CaptureDiagnostics) {
723 assert(Diags.get() && "no DiagnosticsEngine was provided");
724 if (CaptureDiagnostics != CaptureDiagsKind::None)
725 Diags->setClient(new FilterAndStoreDiagnosticConsumer(
726 &AST.StoredDiagnostics, nullptr,
728}
729
730std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
731 StringRef Filename, const PCHContainerReader &PCHContainerRdr,
733 std::shared_ptr<DiagnosticOptions> DiagOpts,
735 const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts,
736 const LangOptions *ProvidedLangOpts, bool OnlyLocalDecls,
737 CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,
738 bool UserFilesAreVolatile) {
739 std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
740
741 // Recover resources if we crash before exiting this method.
742 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
743 ASTUnitCleanup(AST.get());
744 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
745 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
746 DiagCleanup(Diags.get());
747
748 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
749
750 std::unique_ptr<LangOptions> LocalLangOpts;
751 const LangOptions &LangOpts = [&]() -> const LangOptions & {
752 if (ProvidedLangOpts)
753 return *ProvidedLangOpts;
754 LocalLangOpts = std::make_unique<LangOptions>();
755 return *LocalLangOpts;
756 }();
757
758 AST->LangOpts = std::make_unique<LangOptions>(LangOpts);
759 AST->OnlyLocalDecls = OnlyLocalDecls;
760 AST->CaptureDiagnostics = CaptureDiagnostics;
761 AST->DiagOpts = DiagOpts;
762 AST->Diagnostics = Diags;
763 AST->UserFilesAreVolatile = UserFilesAreVolatile;
764 AST->HSOpts = std::make_unique<HeaderSearchOptions>(HSOpts);
765 AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
766 AST->PPOpts = std::make_shared<PreprocessorOptions>();
767 AST->CodeGenOpts = std::make_unique<CodeGenOptions>();
768 AST->TargetOpts = std::make_shared<TargetOptions>();
769
770 AST->ModCache = createCrossProcessModuleCache();
771
772 // Gather info for preprocessor construction later on.
773 std::string SpecificModuleCachePath;
774 unsigned Counter = 0;
775 // Using a temporary FileManager since the AST file might specify custom
776 // HeaderSearchOptions::VFSOverlayFiles that affect the underlying VFS.
777 FileManager TmpFileMgr(FileSystemOpts, VFS);
778 ASTInfoCollector Collector(*AST->HSOpts, SpecificModuleCachePath,
779 *AST->PPOpts, *AST->LangOpts, *AST->CodeGenOpts,
780 *AST->TargetOpts, Counter);
782 Filename, TmpFileMgr, *AST->ModCache, PCHContainerRdr,
783 /*FindModuleFileExtensions=*/true, Collector,
784 /*ValidateDiagnosticOptions=*/true, ASTReader::ARR_None)) {
785 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
786 return nullptr;
787 }
788
789 VFS = createVFSFromOverlayFiles(AST->HSOpts->VFSOverlayFiles,
790 *AST->Diagnostics, std::move(VFS));
791
792 AST->FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOpts, VFS);
793
794 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
795 AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile);
796
797 AST->HSOpts->PrebuiltModuleFiles = HSOpts.PrebuiltModuleFiles;
798 AST->HSOpts->PrebuiltModulePaths = HSOpts.PrebuiltModulePaths;
799 AST->HeaderInfo = std::make_unique<HeaderSearch>(
800 AST->getHeaderSearchOpts(), AST->getSourceManager(),
801 AST->getDiagnostics(), AST->getLangOpts(),
802 /*Target=*/nullptr);
803 AST->HeaderInfo->setModuleCachePath(SpecificModuleCachePath);
804
805 AST->PP = std::make_shared<Preprocessor>(
806 *AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
807 AST->getSourceManager(), *AST->HeaderInfo, AST->ModuleLoader,
808 /*IILookup=*/nullptr,
809 /*OwnsHeaderSearch=*/false);
810
811 if (ToLoad >= LoadASTOnly)
812 AST->Ctx = llvm::makeIntrusiveRefCnt<ASTContext>(
813 *AST->LangOpts, AST->getSourceManager(), AST->PP->getIdentifierTable(),
814 AST->PP->getSelectorTable(), AST->PP->getBuiltinInfo(),
815 AST->getTranslationUnitKind());
816
817 DisableValidationForModuleKind disableValid =
819 if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
821 AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
822 *AST->PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr,
823 *AST->CodeGenOpts, ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
824 /*isysroot=*/"",
825 /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);
826
827 // Attach the AST reader to the AST context as an external AST source, so that
828 // declarations will be deserialized from the AST file as needed.
829 // We need the external source to be set up before we read the AST, because
830 // eagerly-deserialized declarations may use it.
831 if (AST->Ctx)
832 AST->Ctx->setExternalSource(AST->Reader);
833
834 AST->Target =
835 TargetInfo::CreateTargetInfo(AST->PP->getDiagnostics(), *AST->TargetOpts);
836 // Inform the target of the language options.
837 //
838 // FIXME: We shouldn't need to do this, the target should be immutable once
839 // created. This complexity should be lifted elsewhere.
840 AST->Target->adjust(AST->PP->getDiagnostics(), *AST->LangOpts,
841 /*AuxTarget=*/nullptr);
842
843 // Initialize the preprocessor.
844 AST->PP->Initialize(*AST->Target);
845
846 AST->PP->setCounterValue(Counter);
847
848 if (AST->Ctx) {
849 // Initialize the ASTContext
850 AST->Ctx->InitBuiltinTypes(*AST->Target);
851
852 // Adjust printing policy based on language options.
853 AST->Ctx->setPrintingPolicy(PrintingPolicy(*AST->LangOpts));
854
855 // We didn't have access to the comment options when the ASTContext was
856 // constructed, so register them now.
857 AST->Ctx->getCommentCommandTraits().registerCommentOptions(
858 AST->LangOpts->CommentOpts);
859 }
860
861 // The temporary FileManager we used for ASTReader::readASTFileControlBlock()
862 // might have already read stdin, and reading it again will fail. Let's
863 // explicitly forward the buffer.
864 if (Filename == "-")
865 if (auto FE = llvm::expectedToOptional(TmpFileMgr.getSTDIN()))
866 if (auto BufRef = TmpFileMgr.getBufferForFile(*FE)) {
867 auto Buf = llvm::MemoryBuffer::getMemBufferCopy(
868 (*BufRef)->getBuffer(), (*BufRef)->getBufferIdentifier());
869 AST->Reader->getModuleManager().addInMemoryBuffer("-", std::move(Buf));
870 }
871
872 // Reinstate the provided options that are relevant for reading AST files.
873 AST->HSOpts->ForceCheckCXX20ModulesInputFiles =
874 HSOpts.ForceCheckCXX20ModulesInputFiles;
875
876 switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,
879 break;
880
887 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
888 return nullptr;
889 }
890
891 // Now that we have successfully loaded the AST file, we can reinstate some
892 // options that the clients expect us to preserve (but would trip AST file
893 // validation, so we couldn't set them earlier).
894 AST->HSOpts->UserEntries = HSOpts.UserEntries;
895 AST->HSOpts->SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;
896 AST->HSOpts->VFSOverlayFiles = HSOpts.VFSOverlayFiles;
897 AST->LangOpts->PICLevel = LangOpts.PICLevel;
898 AST->LangOpts->PIE = LangOpts.PIE;
899
900 AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());
901
902 Module *M = AST->HeaderInfo->lookupModule(AST->getLangOpts().CurrentModule);
903 if (M && AST->getLangOpts().isCompilingModule() && M->isNamedModule())
904 AST->Ctx->setCurrentNamedModule(M);
905
906 // Create an AST consumer, even though it isn't used.
907 if (ToLoad >= LoadASTOnly)
908 AST->Consumer.reset(new ASTConsumer);
909
910 // Create a semantic analysis object and tell the AST reader about it.
911 if (ToLoad >= LoadEverything) {
912 AST->TheSema = std::make_unique<Sema>(*AST->PP, *AST->Ctx, *AST->Consumer);
913 AST->TheSema->Initialize();
914 AST->Reader->InitializeSema(*AST->TheSema);
915 }
916
917 // Tell the diagnostic client that we have started a source file.
918 AST->getDiagnostics().getClient()->BeginSourceFile(AST->PP->getLangOpts(),
919 AST->PP.get());
920
921 return AST;
922}
923
924/// Add the given macro to the hash of all top-level entities.
925static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
926 Hash = llvm::djbHash(MacroNameTok.getIdentifierInfo()->getName(), Hash);
927}
928
929namespace {
930
931/// Preprocessor callback class that updates a hash value with the names
932/// of all macros that have been defined by the translation unit.
933class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {
934 unsigned &Hash;
935
936public:
937 explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}
938
939 void MacroDefined(const Token &MacroNameTok,
940 const MacroDirective *MD) override {
941 AddDefinedMacroToHash(MacroNameTok, Hash);
942 }
943};
944
945} // namespace
946
947/// Add the given declaration to the hash of all top-level entities.
948static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
949 if (!D)
950 return;
951
952 DeclContext *DC = D->getDeclContext();
953 if (!DC)
954 return;
955
956 if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))
957 return;
958
959 if (const auto *ND = dyn_cast<NamedDecl>(D)) {
960 if (const auto *EnumD = dyn_cast<EnumDecl>(D)) {
961 // For an unscoped enum include the enumerators in the hash since they
962 // enter the top-level namespace.
963 if (!EnumD->isScoped()) {
964 for (const auto *EI : EnumD->enumerators()) {
965 if (EI->getIdentifier())
966 Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
967 }
968 }
969 }
970
971 if (ND->getIdentifier())
972 Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
973 else if (DeclarationName Name = ND->getDeclName()) {
974 std::string NameStr = Name.getAsString();
975 Hash = llvm::djbHash(NameStr, Hash);
976 }
977 return;
978 }
979
980 if (const auto *ImportD = dyn_cast<ImportDecl>(D)) {
981 if (const Module *Mod = ImportD->getImportedModule()) {
982 std::string ModName = Mod->getFullModuleName();
983 Hash = llvm::djbHash(ModName, Hash);
984 }
985 return;
986 }
987}
988
989namespace {
990
991class TopLevelDeclTrackerConsumer : public ASTConsumer {
992 ASTUnit &Unit;
993 unsigned &Hash;
994
995public:
996 TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)
997 : Unit(_Unit), Hash(Hash) {
998 Hash = 0;
999 }
1000
1001 void handleTopLevelDecl(Decl *D) {
1002 if (!D)
1003 return;
1004
1005 // FIXME: Currently ObjC method declarations are incorrectly being
1006 // reported as top-level declarations, even though their DeclContext
1007 // is the containing ObjC @interface/@implementation. This is a
1008 // fundamental problem in the parser right now.
1009 if (isa<ObjCMethodDecl>(D))
1010 return;
1011
1013 Unit.addTopLevelDecl(D);
1014
1015 handleFileLevelDecl(D);
1016 }
1017
1018 void handleFileLevelDecl(Decl *D) {
1019 Unit.addFileLevelDecl(D);
1020 if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {
1021 for (auto *I : NSD->decls())
1022 handleFileLevelDecl(I);
1023 }
1024 }
1025
1026 bool HandleTopLevelDecl(DeclGroupRef D) override {
1027 for (auto *TopLevelDecl : D)
1028 handleTopLevelDecl(TopLevelDecl);
1029 return true;
1030 }
1031
1032 // We're not interested in "interesting" decls.
1033 void HandleInterestingDecl(DeclGroupRef) override {}
1034
1035 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
1036 for (auto *TopLevelDecl : D)
1037 handleTopLevelDecl(TopLevelDecl);
1038 }
1039
1040 ASTMutationListener *GetASTMutationListener() override {
1041 return Unit.getASTMutationListener();
1042 }
1043
1044 ASTDeserializationListener *GetASTDeserializationListener() override {
1045 return Unit.getDeserializationListener();
1046 }
1047};
1048
1049class TopLevelDeclTrackerAction : public ASTFrontendAction {
1050public:
1051 ASTUnit &Unit;
1052
1053 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
1054 StringRef InFile) override {
1056 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1058 return std::make_unique<TopLevelDeclTrackerConsumer>(
1059 Unit, Unit.getCurrentTopLevelHashValue());
1060 }
1061
1062public:
1063 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
1064
1065 bool hasCodeCompletionSupport() const override { return false; }
1066
1067 TranslationUnitKind getTranslationUnitKind() override {
1068 return Unit.getTranslationUnitKind();
1069 }
1070};
1071
1072class ASTUnitPreambleCallbacks : public PreambleCallbacks {
1073public:
1074 unsigned getHash() const { return Hash; }
1075
1076 std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
1077
1078 std::vector<LocalDeclID> takeTopLevelDeclIDs() {
1079 return std::move(TopLevelDeclIDs);
1080 }
1081
1082 void AfterPCHEmitted(ASTWriter &Writer) override {
1083 TopLevelDeclIDs.reserve(TopLevelDecls.size());
1084 for (const auto *D : TopLevelDecls) {
1085 // Invalid top-level decls may not have been serialized.
1086 if (D->isInvalidDecl())
1087 continue;
1088 TopLevelDeclIDs.push_back(Writer.getDeclID(D));
1089 }
1090 }
1091
1092 void HandleTopLevelDecl(DeclGroupRef DG) override {
1093 for (auto *D : DG) {
1094 // FIXME: Currently ObjC method declarations are incorrectly being
1095 // reported as top-level declarations, even though their DeclContext
1096 // is the containing ObjC @interface/@implementation. This is a
1097 // fundamental problem in the parser right now.
1098 if (isa<ObjCMethodDecl>(D))
1099 continue;
1101 TopLevelDecls.push_back(D);
1102 }
1103 }
1104
1105 std::unique_ptr<PPCallbacks> createPPCallbacks() override {
1106 return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);
1107 }
1108
1109private:
1110 unsigned Hash = 0;
1111 std::vector<Decl *> TopLevelDecls;
1112 std::vector<LocalDeclID> TopLevelDeclIDs;
1113 llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
1114};
1115
1116} // namespace
1117
1118static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
1119 return StoredDiag.getLocation().isValid();
1120}
1121
1122static void
1124 // Get rid of stored diagnostics except the ones from the driver which do not
1125 // have a source location.
1126 llvm::erase_if(StoredDiags, isNonDriverDiag);
1127}
1128
1130 StoredDiagnostics,
1131 SourceManager &SM) {
1132 // The stored diagnostic has the old source manager in it; update
1133 // the locations to refer into the new source manager. Since we've
1134 // been careful to make sure that the source manager's state
1135 // before and after are identical, so that we can reuse the source
1136 // location itself.
1137 for (auto &SD : StoredDiagnostics) {
1138 if (SD.getLocation().isValid()) {
1139 FullSourceLoc Loc(SD.getLocation(), SM);
1140 SD.setLocation(Loc);
1141 }
1142 }
1143}
1144
1145/// Parse the source file into a translation unit using the given compiler
1146/// invocation, replacing the current translation unit.
1147///
1148/// \returns True if a failure occurred that causes the ASTUnit not to
1149/// contain any translation-unit information, false otherwise.
1150bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1151 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
1153 if (!Invocation)
1154 return true;
1155
1156 if (VFS && FileMgr)
1157 assert(VFS == &FileMgr->getVirtualFileSystem() &&
1158 "VFS passed to Parse and VFS in FileMgr are different");
1159
1160 CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
1161 if (OverrideMainBuffer) {
1162 assert(Preamble &&
1163 "No preamble was built, but OverrideMainBuffer is not null");
1164 Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
1165 // VFS may have changed...
1166 }
1167
1168 // Create the compiler instance to use for building the AST.
1169 auto Clang = std::make_unique<CompilerInstance>(CCInvocation,
1170 std::move(PCHContainerOps));
1171
1172 // Clean up on error, disengage it if the function returns successfully.
1173 auto CleanOnError = llvm::make_scope_exit([&]() {
1174 // Remove the overridden buffer we used for the preamble.
1175 SavedMainFileBuffer = nullptr;
1176
1177 // Keep the ownership of the data in the ASTUnit because the client may
1178 // want to see the diagnostics.
1179 transferASTDataFromCompilerInstance(*Clang);
1180 FailedParseDiagnostics.swap(StoredDiagnostics);
1181 StoredDiagnostics.clear();
1182 NumStoredDiagnosticsFromDriver = 0;
1183 });
1184
1185 // Ensure that Clang has a FileManager with the right VFS, which may have
1186 // changed above in AddImplicitPreamble. If VFS is nullptr, rely on
1187 // createFileManager to create one.
1188 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS) {
1189 Clang->setVirtualFileSystem(std::move(VFS));
1190 Clang->setFileManager(FileMgr);
1191 } else {
1192 Clang->setVirtualFileSystem(std::move(VFS));
1193 Clang->createFileManager();
1194 FileMgr = Clang->getFileManagerPtr();
1195 }
1196
1197 // Recover resources if we crash before exiting this method.
1198 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1199 CICleanup(Clang.get());
1200
1201 OriginalSourceFile =
1202 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1203
1204 // Set up diagnostics, capturing any diagnostics that would
1205 // otherwise be dropped.
1206 Clang->setDiagnostics(getDiagnosticsPtr());
1207
1208 // Create the target instance.
1209 if (!Clang->createTarget())
1210 return true;
1211
1212 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1213 "Invocation must have exactly one source file!");
1214 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1216 "FIXME: AST inputs not yet supported here!");
1217 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1219 "IR inputs not support here!");
1220
1221 // Configure the various subsystems.
1222 LangOpts =
1223 std::make_unique<LangOptions>(Clang->getInvocation().getLangOpts());
1224 FileSystemOpts = Clang->getFileSystemOpts();
1225
1226 ResetForParse();
1227
1228 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1229 getDiagnostics(), *FileMgr, +UserFilesAreVolatile);
1230 if (!OverrideMainBuffer) {
1231 checkAndRemoveNonDriverDiags(StoredDiagnostics);
1232 TopLevelDeclsInPreamble.clear();
1233 }
1234
1235 // Create the source manager.
1236 Clang->setSourceManager(getSourceManagerPtr());
1237
1238 // If the main file has been overridden due to the use of a preamble,
1239 // make that override happen and introduce the preamble.
1240 if (OverrideMainBuffer) {
1241 // The stored diagnostic has the old source manager in it; update
1242 // the locations to refer into the new source manager. Since we've
1243 // been careful to make sure that the source manager's state
1244 // before and after are identical, so that we can reuse the source
1245 // location itself.
1246 checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
1247
1248 // Keep track of the override buffer;
1249 SavedMainFileBuffer = std::move(OverrideMainBuffer);
1250 }
1251
1252 std::unique_ptr<TopLevelDeclTrackerAction> Act(
1253 new TopLevelDeclTrackerAction(*this));
1254
1255 // Recover resources if we crash before exiting this method.
1256 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1257 ActCleanup(Act.get());
1258
1259 if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
1260 return true;
1261
1262 if (SavedMainFileBuffer)
1263 TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
1264 PreambleDiagnostics, StoredDiagnostics);
1265 else
1266 PreambleSrcLocCache.clear();
1267
1268 if (llvm::Error Err = Act->Execute()) {
1269 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1270 return true;
1271 }
1272
1273 transferASTDataFromCompilerInstance(*Clang);
1274
1275 Act->EndSourceFile();
1276
1277 FailedParseDiagnostics.clear();
1278
1279 CleanOnError.release();
1280
1281 return false;
1282}
1283
1284static std::pair<unsigned, unsigned>
1286 const LangOptions &LangOpts) {
1287 CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts);
1288 unsigned Offset = SM.getFileOffset(FileRange.getBegin());
1289 unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());
1290 return std::make_pair(Offset, EndOffset);
1291}
1292
1294 const LangOptions &LangOpts,
1295 const FixItHint &InFix) {
1297 OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);
1299 LangOpts);
1300 OutFix.CodeToInsert = InFix.CodeToInsert;
1302 return OutFix;
1303}
1304
1307 const StoredDiagnostic &InDiag) {
1309 OutDiag.ID = InDiag.getID();
1310 OutDiag.Level = InDiag.getLevel();
1311 OutDiag.Message = std::string(InDiag.getMessage());
1312 OutDiag.LocOffset = 0;
1313 if (InDiag.getLocation().isInvalid())
1314 return OutDiag;
1315 const SourceManager &SM = InDiag.getLocation().getManager();
1316 SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());
1317 OutDiag.Filename = std::string(SM.getFilename(FileLoc));
1318 if (OutDiag.Filename.empty())
1319 return OutDiag;
1320 OutDiag.LocOffset = SM.getFileOffset(FileLoc);
1321 for (const auto &Range : InDiag.getRanges())
1322 OutDiag.Ranges.push_back(makeStandaloneRange(Range, SM, LangOpts));
1323 for (const auto &FixIt : InDiag.getFixIts())
1324 OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, FixIt));
1325
1326 return OutDiag;
1327}
1328
1329/// Attempt to build or re-use a precompiled preamble when (re-)parsing
1330/// the source file.
1331///
1332/// This routine will compute the preamble of the main source file. If a
1333/// non-trivial preamble is found, it will precompile that preamble into a
1334/// precompiled header so that the precompiled preamble can be used to reduce
1335/// reparsing time. If a precompiled preamble has already been constructed,
1336/// this routine will determine if it is still valid and, if so, avoid
1337/// rebuilding the precompiled preamble.
1338///
1339/// \param AllowRebuild When true (the default), this routine is
1340/// allowed to rebuild the precompiled preamble if it is found to be
1341/// out-of-date.
1342///
1343/// \param MaxLines When non-zero, the maximum number of lines that
1344/// can occur within the preamble.
1345///
1346/// \returns If the precompiled preamble can be used, returns a newly-allocated
1347/// buffer that should be used in place of the main file when doing so.
1348/// Otherwise, returns a NULL pointer.
1349std::unique_ptr<llvm::MemoryBuffer>
1350ASTUnit::getMainBufferWithPrecompiledPreamble(
1351 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1352 CompilerInvocation &PreambleInvocationIn,
1353 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild,
1354 unsigned MaxLines) {
1355 auto MainFilePath =
1356 PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
1357 std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
1358 getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
1359 MainFilePath, UserFilesAreVolatile);
1360 if (!MainFileBuffer)
1361 return nullptr;
1362
1363 PreambleBounds Bounds = ComputePreambleBounds(
1364 PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines);
1365 if (!Bounds.Size)
1366 return nullptr;
1367
1368 if (Preamble) {
1369 if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
1370 *VFS)) {
1371 // Okay! We can re-use the precompiled preamble.
1372
1373 // Set the state of the diagnostic object to mimic its state
1374 // after parsing the preamble.
1377 PreambleInvocationIn.getDiagnosticOpts(), *VFS);
1378 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1379
1380 PreambleRebuildCountdown = 1;
1381 return MainFileBuffer;
1382 } else {
1383 Preamble.reset();
1384 PreambleDiagnostics.clear();
1385 TopLevelDeclsInPreamble.clear();
1386 PreambleSrcLocCache.clear();
1387 PreambleRebuildCountdown = 1;
1388 }
1389 }
1390
1391 // If the preamble rebuild counter > 1, it's because we previously
1392 // failed to build a preamble and we're not yet ready to try
1393 // again. Decrement the counter and return a failure.
1394 if (PreambleRebuildCountdown > 1) {
1395 --PreambleRebuildCountdown;
1396 return nullptr;
1397 }
1398
1399 assert(!Preamble && "No Preamble should be stored at that point");
1400 // If we aren't allowed to rebuild the precompiled preamble, just
1401 // return now.
1402 if (!AllowRebuild)
1403 return nullptr;
1404
1405 ++PreambleCounter;
1406
1407 SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;
1408 SmallVector<StoredDiagnostic, 4> NewPreambleDiags;
1409 ASTUnitPreambleCallbacks Callbacks;
1410 {
1411 std::optional<CaptureDroppedDiagnostics> Capture;
1412 if (CaptureDiagnostics != CaptureDiagsKind::None)
1413 Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,
1414 &NewPreambleDiagsStandalone);
1415
1416 // We did not previously compute a preamble, or it can't be reused anyway.
1417 SimpleTimer PreambleTimer(WantTiming);
1418 PreambleTimer.setOutput("Precompiling preamble");
1419
1420 const bool PreviousSkipFunctionBodies =
1421 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;
1422 if (SkipFunctionBodies == SkipFunctionBodiesScope::Preamble)
1423 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true;
1424
1425 llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(
1426 PreambleInvocationIn, MainFileBuffer.get(), Bounds, Diagnostics, VFS,
1427 PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,
1428 Callbacks);
1429
1430 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
1431 PreviousSkipFunctionBodies;
1432
1433 if (NewPreamble) {
1434 Preamble = std::move(*NewPreamble);
1435 PreambleRebuildCountdown = 1;
1436 } else {
1437 switch (static_cast<BuildPreambleError>(NewPreamble.getError().value())) {
1439 // Try again next time.
1440 PreambleRebuildCountdown = 1;
1441 return nullptr;
1446 // These erros are more likely to repeat, retry after some period.
1447 PreambleRebuildCountdown = DefaultPreambleRebuildInterval;
1448 return nullptr;
1449 }
1450 llvm_unreachable("unexpected BuildPreambleError");
1451 }
1452 }
1453
1454 assert(Preamble && "Preamble wasn't built");
1455
1456 TopLevelDecls.clear();
1457 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
1458 PreambleTopLevelHashValue = Callbacks.getHash();
1459
1460 NumWarningsInPreamble = getDiagnostics().getNumWarnings();
1461
1462 checkAndRemoveNonDriverDiags(NewPreambleDiags);
1463 StoredDiagnostics = std::move(NewPreambleDiags);
1464 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
1465
1466 // If the hash of top-level entities differs from the hash of the top-level
1467 // entities the last time we rebuilt the preamble, clear out the completion
1468 // cache.
1469 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
1470 CompletionCacheTopLevelHashValue = 0;
1471 PreambleTopLevelHashValue = CurrentTopLevelHashValue;
1472 }
1473
1474 return MainFileBuffer;
1475}
1476
1477void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1478 assert(Preamble && "Should only be called when preamble was built");
1479
1480 std::vector<Decl *> Resolved;
1481 Resolved.reserve(TopLevelDeclsInPreamble.size());
1482 // The module file of the preamble.
1483 serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();
1484 for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1485 // Resolve the declaration ID to an actual declaration, possibly
1486 // deserializing the declaration in the process.
1487 if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))
1488 Resolved.push_back(D);
1489 }
1490 TopLevelDeclsInPreamble.clear();
1491 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1492}
1493
1494void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
1495 // Steal the created target, context, and preprocessor if they have been
1496 // created.
1497 LangOpts = std::make_unique<LangOptions>(CI.getInvocation().getLangOpts());
1498 TheSema = CI.takeSema();
1499 Consumer = CI.takeASTConsumer();
1500 if (CI.hasASTContext())
1501 Ctx = CI.getASTContextPtr();
1502 if (CI.hasPreprocessor())
1503 PP = CI.getPreprocessorPtr();
1504 CI.setSourceManager(nullptr);
1505 CI.setFileManager(nullptr);
1506 if (CI.hasTarget())
1507 Target = CI.getTargetPtr();
1508 Reader = CI.getASTReader();
1509 HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
1510 if (Invocation != CI.getInvocationPtr()) {
1511 // This happens when Parse creates a copy of \c Invocation to modify.
1512 ModifiedInvocation = CI.getInvocationPtr();
1513 }
1514}
1515
1516StringRef ASTUnit::getMainFileName() const {
1517 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1518 const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];
1519 if (Input.isFile())
1520 return Input.getFile();
1521 else
1522 return Input.getBuffer().getBufferIdentifier();
1523 }
1524
1525 if (SourceMgr) {
1526 if (OptionalFileEntryRef FE =
1527 SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID()))
1528 return FE->getName();
1529 }
1530
1531 return {};
1532}
1533
1534StringRef ASTUnit::getASTFileName() const {
1535 if (!isMainFileAST())
1536 return {};
1537
1539 Mod = Reader->getModuleManager().getPrimaryModule();
1540 return Mod.FileName;
1541}
1542
1543std::unique_ptr<ASTUnit>
1544ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
1545 std::shared_ptr<DiagnosticOptions> DiagOpts,
1547 CaptureDiagsKind CaptureDiagnostics,
1548 bool UserFilesAreVolatile) {
1549 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1550 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1553 AST->DiagOpts = DiagOpts;
1554 AST->Diagnostics = Diags;
1555 AST->FileSystemOpts = CI->getFileSystemOpts();
1556 AST->Invocation = std::move(CI);
1557 AST->FileMgr =
1558 llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
1559 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1560 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1561 AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile);
1562 AST->ModCache = createCrossProcessModuleCache();
1563
1564 return AST;
1565}
1566
1568 std::shared_ptr<CompilerInvocation> CI,
1569 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1570 std::shared_ptr<DiagnosticOptions> DiagOpts,
1572 ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
1573 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1574 unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
1575 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1576 assert(CI && "A CompilerInvocation is required");
1577
1578 std::unique_ptr<ASTUnit> OwnAST;
1579 ASTUnit *AST = Unit;
1580 if (!AST) {
1581 // Create the AST unit.
1582 OwnAST =
1583 create(CI, DiagOpts, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1584 AST = OwnAST.get();
1585 if (!AST)
1586 return nullptr;
1587 }
1588
1589 if (!ResourceFilesPath.empty()) {
1590 // Override the resources path.
1591 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1592 }
1593 AST->OnlyLocalDecls = OnlyLocalDecls;
1594 AST->CaptureDiagnostics = CaptureDiagnostics;
1595 if (PrecompilePreambleAfterNParses > 0)
1596 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1597 AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
1598 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1599 AST->IncludeBriefCommentsInCodeCompletion = false;
1600
1601 // Recover resources if we crash before exiting this method.
1602 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1603 ASTUnitCleanup(OwnAST.get());
1604 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1605 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1606 DiagCleanup(Diags.get());
1607
1608 // We'll manage file buffers ourselves.
1609 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1610 CI->getFrontendOpts().DisableFree = false;
1611 ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts(),
1613
1614 // Create the compiler instance to use for building the AST.
1615 auto Clang = std::make_unique<CompilerInstance>(std::move(CI),
1616 std::move(PCHContainerOps));
1617
1618 // Recover resources if we crash before exiting this method.
1619 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1620 CICleanup(Clang.get());
1621
1622 AST->OriginalSourceFile =
1623 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1624
1625 // Set up diagnostics, capturing any diagnostics that would
1626 // otherwise be dropped.
1627 Clang->setDiagnostics(AST->getDiagnosticsPtr());
1628
1629 // Create the target instance.
1630 if (!Clang->createTarget())
1631 return nullptr;
1632
1633 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1634 "Invocation must have exactly one source file!");
1635 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1637 "FIXME: AST inputs not yet supported here!");
1638 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1640 "IR inputs not support here!");
1641
1642 // Configure the various subsystems.
1643 AST->TheSema.reset();
1644 AST->Ctx = nullptr;
1645 AST->PP = nullptr;
1646 AST->Reader = nullptr;
1647
1648 // Create a file manager object to provide access to and cache the filesystem.
1649 Clang->setVirtualFileSystem(AST->getVirtualFileSystemPtr());
1650 Clang->setFileManager(AST->getFileManagerPtr());
1651
1652 // Create the source manager.
1653 Clang->setSourceManager(AST->getSourceManagerPtr());
1654
1655 FrontendAction *Act = Action;
1656
1657 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1658 if (!Act) {
1659 TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
1660 Act = TrackerAct.get();
1661 }
1662
1663 // Recover resources if we crash before exiting this method.
1664 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1665 ActCleanup(TrackerAct.get());
1666
1667 if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1668 AST->transferASTDataFromCompilerInstance(*Clang);
1669 if (OwnAST && ErrAST)
1670 ErrAST->swap(OwnAST);
1671
1672 return nullptr;
1673 }
1674
1675 if (Persistent && !TrackerAct) {
1676 Clang->getPreprocessor().addPPCallbacks(
1677 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1679 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1680 if (Clang->hasASTConsumer())
1681 Consumers.push_back(Clang->takeASTConsumer());
1682 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1683 *AST, AST->getCurrentTopLevelHashValue()));
1684 Clang->setASTConsumer(
1685 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1686 }
1687 if (llvm::Error Err = Act->Execute()) {
1688 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1689 AST->transferASTDataFromCompilerInstance(*Clang);
1690 if (OwnAST && ErrAST)
1691 ErrAST->swap(OwnAST);
1692
1693 return nullptr;
1694 }
1695
1696 // Steal the created target, context, and preprocessor.
1697 AST->transferASTDataFromCompilerInstance(*Clang);
1698
1699 Act->EndSourceFile();
1700
1701 if (OwnAST)
1702 return OwnAST.release();
1703 else
1704 return AST;
1705}
1706
1707bool ASTUnit::LoadFromCompilerInvocation(
1708 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1709 unsigned PrecompilePreambleAfterNParses,
1711 if (!Invocation)
1712 return true;
1713
1714 assert(VFS && "VFS is null");
1715
1716 // We'll manage file buffers ourselves.
1717 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1718 Invocation->getFrontendOpts().DisableFree = false;
1720 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),
1721 *VFS);
1722
1723 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1724 if (PrecompilePreambleAfterNParses > 0) {
1725 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1726 OverrideMainBuffer =
1727 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1729 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),
1730 *VFS);
1731 }
1732
1733 SimpleTimer ParsingTimer(WantTiming);
1734 ParsingTimer.setOutput("Parsing " + getMainFileName());
1735
1736 // Recover resources if we crash before exiting this method.
1737 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1738 MemBufferCleanup(OverrideMainBuffer.get());
1739
1740 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1741}
1742
1743std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1744 std::shared_ptr<CompilerInvocation> CI,
1745 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1746 std::shared_ptr<DiagnosticOptions> DiagOpts,
1748 IntrusiveRefCntPtr<FileManager> FileMgr, bool OnlyLocalDecls,
1749 CaptureDiagsKind CaptureDiagnostics,
1750 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1751 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1752 bool UserFilesAreVolatile) {
1753 // Create the AST unit.
1754 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1755 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1756 AST->DiagOpts = DiagOpts;
1757 AST->Diagnostics = Diags;
1758 AST->OnlyLocalDecls = OnlyLocalDecls;
1759 AST->CaptureDiagnostics = CaptureDiagnostics;
1760 AST->TUKind = TUKind;
1761 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1762 AST->IncludeBriefCommentsInCodeCompletion
1763 = IncludeBriefCommentsInCodeCompletion;
1764 AST->Invocation = std::move(CI);
1765 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1766 AST->FileMgr = FileMgr;
1767 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1768
1769 // Recover resources if we crash before exiting this method.
1770 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1771 ASTUnitCleanup(AST.get());
1772 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1773 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1774 DiagCleanup(Diags.get());
1775
1776 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1777 PrecompilePreambleAfterNParses,
1778 AST->FileMgr->getVirtualFileSystemPtr()))
1779 return nullptr;
1780 return AST;
1781}
1782
1783std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
1784 const char **ArgBegin, const char **ArgEnd,
1785 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1786 std::shared_ptr<DiagnosticOptions> DiagOpts,
1787 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
1788 bool StorePreamblesInMemory, StringRef PreambleStoragePath,
1789 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1790 ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
1791 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1792 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1793 bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
1794 bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
1795 bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
1796 std::unique_ptr<ASTUnit> *ErrAST,
1798 assert(Diags.get() && "no DiagnosticsEngine was provided");
1799
1800 // If no VFS was provided, create one that tracks the physical file system.
1801 // If '-working-directory' was passed as an argument, 'createInvocation' will
1802 // set this as the current working directory of the VFS.
1803 if (!VFS)
1804 VFS = llvm::vfs::createPhysicalFileSystem();
1805
1806 SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
1807
1808 std::shared_ptr<CompilerInvocation> CI;
1809
1810 {
1811 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
1812 &StoredDiagnostics, nullptr);
1813
1815 CIOpts.VFS = VFS;
1816 CIOpts.Diags = Diags;
1817 CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
1818 CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));
1819 if (!CI)
1820 return nullptr;
1821 }
1822
1823 // Override any files that need remapping
1824 for (const auto &RemappedFile : RemappedFiles) {
1825 CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1826 RemappedFile.second);
1827 }
1828 PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
1829 PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
1830 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
1831 PPOpts.SingleFileParseMode = SingleFileParse;
1832 PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
1833
1834 // Override the resources path.
1835 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1836
1837 CI->getFrontendOpts().SkipFunctionBodies =
1839
1840 if (ModuleFormat)
1841 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
1842
1843 // Create the AST unit.
1844 std::unique_ptr<ASTUnit> AST;
1845 AST.reset(new ASTUnit(false));
1846 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1847 AST->StoredDiagnostics.swap(StoredDiagnostics);
1848 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1849 AST->DiagOpts = DiagOpts;
1850 AST->Diagnostics = Diags;
1851 AST->FileSystemOpts = CI->getFileSystemOpts();
1852 AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
1853 VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
1854 AST->FileMgr =
1855 llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
1856 AST->StorePreamblesInMemory = StorePreamblesInMemory;
1857 AST->PreambleStoragePath = PreambleStoragePath;
1858 AST->ModCache = createCrossProcessModuleCache();
1859 AST->OnlyLocalDecls = OnlyLocalDecls;
1860 AST->CaptureDiagnostics = CaptureDiagnostics;
1861 AST->TUKind = TUKind;
1862 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1863 AST->IncludeBriefCommentsInCodeCompletion
1864 = IncludeBriefCommentsInCodeCompletion;
1865 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1866 AST->Invocation = CI;
1867 AST->SkipFunctionBodies = SkipFunctionBodies;
1868 if (ForSerialization)
1869 AST->WriterData.reset(new ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
1870 // Zero out now to ease cleanup during crash recovery.
1871 CI = nullptr;
1872 Diags = nullptr;
1873
1874 // Recover resources if we crash before exiting this method.
1875 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1876 ASTUnitCleanup(AST.get());
1877
1878 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1879 PrecompilePreambleAfterNParses,
1880 VFS)) {
1881 // Some error occurred, if caller wants to examine diagnostics, pass it the
1882 // ASTUnit.
1883 if (ErrAST) {
1884 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1885 ErrAST->swap(AST);
1886 }
1887 return nullptr;
1888 }
1889
1890 return AST;
1891}
1892
1893bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1894 ArrayRef<RemappedFile> RemappedFiles,
1896 if (!Invocation)
1897 return true;
1898
1899 if (!VFS) {
1900 assert(FileMgr && "FileMgr is null on Reparse call");
1901 VFS = FileMgr->getVirtualFileSystemPtr();
1902 }
1903
1904 clearFileLevelDecls();
1905
1906 SimpleTimer ParsingTimer(WantTiming);
1907 ParsingTimer.setOutput("Reparsing " + getMainFileName());
1908
1909 // Remap files.
1910 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1911 for (const auto &RB : PPOpts.RemappedFileBuffers)
1912 delete RB.second;
1913
1914 Invocation->getPreprocessorOpts().clearRemappedFiles();
1915 for (const auto &RemappedFile : RemappedFiles) {
1916 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1917 RemappedFile.second);
1918 }
1919
1920 // If we have a preamble file lying around, or if we might try to
1921 // build a precompiled preamble, do so now.
1922 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1923 if (Preamble || PreambleRebuildCountdown > 0)
1924 OverrideMainBuffer =
1925 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1926
1927 // Clear out the diagnostics state.
1928 FileMgr.reset();
1930 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),
1931 *VFS);
1932 if (OverrideMainBuffer)
1933 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1934
1935 // Parse the sources
1936 bool Result =
1937 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1938
1939 // If we're caching global code-completion results, and the top-level
1940 // declarations have changed, clear out the code-completion cache.
1941 if (!Result && ShouldCacheCodeCompletionResults &&
1942 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1943 CacheCodeCompletionResults();
1944
1945 // We now need to clear out the completion info related to this translation
1946 // unit; it'll be recreated if necessary.
1947 CCTUInfo.reset();
1948
1949 return Result;
1950}
1951
1953 SavedMainFileBuffer.reset();
1954
1955 SourceMgr.reset();
1956 TheSema.reset();
1957 Ctx.reset();
1958 PP.reset();
1959 Reader.reset();
1960
1961 TopLevelDecls.clear();
1962 clearFileLevelDecls();
1963}
1964
1965//----------------------------------------------------------------------------//
1966// Code completion
1967//----------------------------------------------------------------------------//
1968
1969namespace {
1970
1971 /// Code completion consumer that combines the cached code-completion
1972 /// results from an ASTUnit with the code-completion results provided to it,
1973 /// then passes the result on to
1974 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
1975 uint64_t NormalContexts;
1976 ASTUnit &AST;
1978
1979 public:
1980 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
1981 const CodeCompleteOptions &CodeCompleteOpts)
1982 : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
1983 // Compute the set of contexts in which we will look when we don't have
1984 // any information about the specific context.
1985 NormalContexts
1999
2000 if (AST.getASTContext().getLangOpts().CPlusPlus)
2001 NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
2004 }
2005
2006 void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
2007 CodeCompletionResult *Results,
2008 unsigned NumResults) override;
2009
2010 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
2011 OverloadCandidate *Candidates,
2012 unsigned NumCandidates,
2013 SourceLocation OpenParLoc,
2014 bool Braced) override {
2015 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
2016 OpenParLoc, Braced);
2017 }
2018
2019 CodeCompletionAllocator &getAllocator() override {
2020 return Next.getAllocator();
2021 }
2022
2023 CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
2024 return Next.getCodeCompletionTUInfo();
2025 }
2026 };
2027
2028} // namespace
2029
2030/// Helper function that computes which global names are hidden by the
2031/// local code-completion results.
2033 CodeCompletionResult *Results,
2034 unsigned NumResults,
2035 ASTContext &Ctx,
2036 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
2037 bool OnlyTagNames = false;
2038 switch (Context.getKind()) {
2058 break;
2059
2063 OnlyTagNames = true;
2064 break;
2065
2083 // We're looking for nothing, or we're looking for names that cannot
2084 // be hidden.
2085 return;
2086 }
2087
2088 using Result = CodeCompletionResult;
2089 for (unsigned I = 0; I != NumResults; ++I) {
2090 if (Results[I].Kind != Result::RK_Declaration)
2091 continue;
2092
2093 unsigned IDNS
2095
2096 bool Hiding = false;
2097 if (OnlyTagNames)
2098 Hiding = (IDNS & Decl::IDNS_Tag);
2099 else {
2100 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
2103 if (Ctx.getLangOpts().CPlusPlus)
2104 HiddenIDNS |= Decl::IDNS_Tag;
2105 Hiding = (IDNS & HiddenIDNS);
2106 }
2107
2108 if (!Hiding)
2109 continue;
2110
2111 DeclarationName Name = Results[I].Declaration->getDeclName();
2112 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
2113 HiddenNames.insert(Identifier->getName());
2114 else
2115 HiddenNames.insert(Name.getAsString());
2116 }
2117}
2118
2119void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
2120 CodeCompletionContext Context,
2121 CodeCompletionResult *Results,
2122 unsigned NumResults) {
2123 // Merge the results we were given with the results we cached.
2124 bool AddedResult = false;
2125 uint64_t InContexts =
2126 Context.getKind() == CodeCompletionContext::CCC_Recovery
2127 ? NormalContexts : (1LL << Context.getKind());
2128 // Contains the set of names that are hidden by "local" completion results.
2129 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2131 SmallVector<Result, 8> AllResults;
2133 C = AST.cached_completion_begin(),
2134 CEnd = AST.cached_completion_end();
2135 C != CEnd; ++C) {
2136 // If the context we are in matches any of the contexts we are
2137 // interested in, we'll add this result.
2138 if ((C->ShowInContexts & InContexts) == 0)
2139 continue;
2140
2141 // If we haven't added any results previously, do so now.
2142 if (!AddedResult) {
2143 CalculateHiddenNames(Context, Results, NumResults, S.Context,
2144 HiddenNames);
2145 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2146 AddedResult = true;
2147 }
2148
2149 // Determine whether this global completion result is hidden by a local
2150 // completion result. If so, skip it.
2151 if (C->Kind != CXCursor_MacroDefinition &&
2152 HiddenNames.count(C->Completion->getTypedText()))
2153 continue;
2154
2155 // Adjust priority based on similar type classes.
2156 unsigned Priority = C->Priority;
2157 CodeCompletionString *Completion = C->Completion;
2158 if (!Context.getPreferredType().isNull()) {
2159 if (C->Kind == CXCursor_MacroDefinition) {
2160 Priority = getMacroUsagePriority(C->Completion->getTypedText(),
2161 S.getLangOpts(),
2162 Context.getPreferredType()->isAnyPointerType());
2163 } else if (C->Type) {
2166 Context.getPreferredType().getUnqualifiedType());
2168 if (ExpectedSTC == C->TypeClass) {
2169 // We know this type is similar; check for an exact match.
2170 llvm::StringMap<unsigned> &CachedCompletionTypes
2172 llvm::StringMap<unsigned>::iterator Pos
2173 = CachedCompletionTypes.find(QualType(Expected).getAsString());
2174 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
2175 Priority /= CCF_ExactTypeMatch;
2176 else
2177 Priority /= CCF_SimilarTypeMatch;
2178 }
2179 }
2180 }
2181
2182 // Adjust the completion string, if required.
2183 if (C->Kind == CXCursor_MacroDefinition &&
2184 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
2185 // Create a new code-completion string that just contains the
2186 // macro name, without its arguments.
2187 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
2188 CCP_CodePattern, C->Availability);
2189 Builder.AddTypedTextChunk(C->Completion->getTypedText());
2190 Priority = CCP_CodePattern;
2191 Completion = Builder.TakeString();
2192 }
2193
2194 AllResults.push_back(Result(Completion, Priority, C->Kind,
2195 C->Availability));
2196 }
2197
2198 // If we did not add any cached completion results, just forward the
2199 // results we were given to the next consumer.
2200 if (!AddedResult) {
2201 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2202 return;
2203 }
2204
2205 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2206 AllResults.size());
2207}
2208
2210 StringRef File, unsigned Line, unsigned Column,
2211 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
2212 bool IncludeCodePatterns, bool IncludeBriefComments,
2213 CodeCompleteConsumer &Consumer,
2214 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2218 SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
2220 std::unique_ptr<SyntaxOnlyAction> Act) {
2221 if (!Invocation)
2222 return;
2223
2224 SimpleTimer CompletionTimer(WantTiming);
2225 CompletionTimer.setOutput("Code completion @ " + File + ":" +
2226 Twine(Line) + ":" + Twine(Column));
2227
2228 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2229
2230 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2231 CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
2232 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2233
2234 CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2235 CachedCompletionResults.empty();
2236 CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2237 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2238 CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2239 CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
2240 CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
2241
2242 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2243
2244 FrontendOpts.CodeCompletionAt.FileName = std::string(File);
2245 FrontendOpts.CodeCompletionAt.Line = Line;
2246 FrontendOpts.CodeCompletionAt.Column = Column;
2247
2248 // Set the language options appropriately.
2249 LangOpts = CCInvocation->getLangOpts();
2250
2251 // Spell-checking and warnings are wasteful during code-completion.
2252 LangOpts.SpellChecking = false;
2253 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
2254
2255 auto Clang = std::make_unique<CompilerInstance>(std::move(CCInvocation),
2256 PCHContainerOps);
2257
2258 // Recover resources if we crash before exiting this method.
2259 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2260 CICleanup(Clang.get());
2261
2262 auto &Inv = Clang->getInvocation();
2263 OriginalSourceFile =
2264 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2265
2266 // Set up diagnostics, capturing any diagnostics produced.
2267 Clang->setDiagnostics(Diag);
2268 CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
2269 Clang->getDiagnostics(),
2270 &StoredDiagnostics, nullptr);
2271 ProcessWarningOptions(*Diag, Inv.getDiagnosticOpts(),
2272 FileMgr->getVirtualFileSystem());
2273
2274 // Create the target instance.
2275 if (!Clang->createTarget()) {
2276 return;
2277 }
2278
2279 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2280 "Invocation must have exactly one source file!");
2281 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2283 "FIXME: AST inputs not yet supported here!");
2284 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2286 "IR inputs not support here!");
2287
2288 // Use the source and file managers that we were given.
2289 Clang->setVirtualFileSystem(FileMgr->getVirtualFileSystemPtr());
2290 Clang->setFileManager(FileMgr);
2291 Clang->setSourceManager(SourceMgr);
2292
2293 // Remap files.
2294 PreprocessorOpts.clearRemappedFiles();
2295 PreprocessorOpts.RetainRemappedFileBuffers = true;
2296 for (const auto &RemappedFile : RemappedFiles) {
2297 PreprocessorOpts.addRemappedFile(RemappedFile.first, RemappedFile.second);
2298 OwnedBuffers.push_back(RemappedFile.second);
2299 }
2300
2301 // Use the code completion consumer we were given, but adding any cached
2302 // code-completion results.
2303 AugmentedCodeCompleteConsumer *AugmentedConsumer
2304 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
2305 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2306
2307 auto getUniqueID =
2308 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2309 if (auto Status = FileMgr->getVirtualFileSystem().status(Filename))
2310 return Status->getUniqueID();
2311 return std::nullopt;
2312 };
2313
2314 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2315 if (LHS == RHS)
2316 return true;
2317 if (auto LHSID = getUniqueID(LHS))
2318 if (auto RHSID = getUniqueID(RHS))
2319 return *LHSID == *RHSID;
2320 return false;
2321 };
2322
2323 // If we have a precompiled preamble, try to use it. We only allow
2324 // the use of the precompiled preamble if we're if the completion
2325 // point is within the main file, after the end of the precompiled
2326 // preamble.
2327 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2328 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
2329 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2330 PCHContainerOps, Inv, FileMgr->getVirtualFileSystemPtr(), false,
2331 Line - 1);
2332 }
2333
2334 // If the main file has been overridden due to the use of a preamble,
2335 // make that override happen and introduce the preamble.
2336 if (OverrideMainBuffer) {
2337 assert(Preamble &&
2338 "No preamble was built, but OverrideMainBuffer is not null");
2339
2341 FileMgr->getVirtualFileSystemPtr();
2342 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2343 OverrideMainBuffer.get());
2344 // FIXME: there is no way to update VFS if it was changed by
2345 // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
2346 // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
2347 // PCH files are always readable.
2348 OwnedBuffers.push_back(OverrideMainBuffer.release());
2349 } else {
2350 PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2351 PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2352 }
2353
2354 // Disable the preprocessing record if modules are not enabled.
2355 if (!Clang->getLangOpts().Modules)
2356 PreprocessorOpts.DetailedRecord = false;
2357
2358 if (!Act)
2359 Act.reset(new SyntaxOnlyAction);
2360
2361 if (Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
2362 if (llvm::Error Err = Act->Execute()) {
2363 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
2364 }
2365 Act->EndSourceFile();
2366 }
2367}
2368
2369bool ASTUnit::Save(StringRef File) {
2370 if (HadModuleLoaderFatalFailure)
2371 return true;
2372
2373 // FIXME: Can we somehow regenerate the stat cache here, or do we need to
2374 // unconditionally create a stat cache when we parse the file?
2375
2376 if (llvm::Error Err = llvm::writeToOutput(
2377 File, [this](llvm::raw_ostream &Out) {
2378 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2379 "ASTUnit serialization failed",
2380 llvm::inconvertibleErrorCode())
2381 : llvm::Error::success();
2382 })) {
2383 consumeError(std::move(Err));
2384 return true;
2385 }
2386 return false;
2387}
2388
2389static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,
2390 Sema &S, raw_ostream &OS) {
2391 Writer.WriteAST(&S, std::string(), nullptr, "");
2392
2393 // Write the generated bitstream to "Out".
2394 if (!Buffer.empty())
2395 OS.write(Buffer.data(), Buffer.size());
2396
2397 return false;
2398}
2399
2400bool ASTUnit::serialize(raw_ostream &OS) {
2401 if (WriterData)
2402 return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS);
2403
2404 SmallString<128> Buffer;
2405 llvm::BitstreamWriter Stream(Buffer);
2407 ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});
2408 return serializeUnit(Writer, Buffer, getSema(), OS);
2409}
2410
2411void ASTUnit::TranslateStoredDiagnostics(
2416 // Map the standalone diagnostic into the new source manager. We also need to
2417 // remap all the locations to the new view. This includes the diag location,
2418 // any associated source ranges, and the source ranges of associated fix-its.
2419 // FIXME: There should be a cleaner way to do this.
2421 Result.reserve(Diags.size());
2422
2423 for (const auto &SD : Diags) {
2424 // Rebuild the StoredDiagnostic.
2425 if (SD.Filename.empty())
2426 continue;
2427 auto FE = FileMgr.getOptionalFileRef(SD.Filename);
2428 if (!FE)
2429 continue;
2430 SourceLocation FileLoc;
2431 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2432 if (ItFileID == PreambleSrcLocCache.end()) {
2433 FileID FID = SrcMgr.translateFile(*FE);
2434 FileLoc = SrcMgr.getLocForStartOfFile(FID);
2435 PreambleSrcLocCache[SD.Filename] = FileLoc;
2436 } else {
2437 FileLoc = ItFileID->getValue();
2438 }
2439
2440 if (FileLoc.isInvalid())
2441 continue;
2442 SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
2443 FullSourceLoc Loc(L, SrcMgr);
2444
2445 SmallVector<CharSourceRange, 4> Ranges;
2446 Ranges.reserve(SD.Ranges.size());
2447 for (const auto &Range : SD.Ranges) {
2448 SourceLocation BL = FileLoc.getLocWithOffset(Range.first);
2449 SourceLocation EL = FileLoc.getLocWithOffset(Range.second);
2450 Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
2451 }
2452
2453 SmallVector<FixItHint, 2> FixIts;
2454 FixIts.reserve(SD.FixIts.size());
2455 for (const auto &FixIt : SD.FixIts) {
2456 FixIts.push_back(FixItHint());
2457 FixItHint &FH = FixIts.back();
2458 FH.CodeToInsert = FixIt.CodeToInsert;
2459 SourceLocation BL = FileLoc.getLocWithOffset(FixIt.RemoveRange.first);
2460 SourceLocation EL = FileLoc.getLocWithOffset(FixIt.RemoveRange.second);
2462 }
2463
2464 Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
2465 SD.Message, Loc, Ranges, FixIts));
2466 }
2467 Result.swap(Out);
2468}
2469
2471 assert(D);
2472
2473 // We only care about local declarations.
2474 if (D->isFromASTFile())
2475 return;
2476
2477 SourceManager &SM = *SourceMgr;
2478 SourceLocation Loc = D->getLocation();
2479 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2480 return;
2481
2482 // We only keep track of the file-level declarations of each file.
2484 return;
2485
2486 SourceLocation FileLoc = SM.getFileLoc(Loc);
2487 assert(SM.isLocalSourceLocation(FileLoc));
2488 auto [FID, Offset] = SM.getDecomposedLoc(FileLoc);
2489 if (FID.isInvalid())
2490 return;
2491
2492 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2493 if (!Decls)
2494 Decls = std::make_unique<LocDeclsTy>();
2495
2496 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2497
2498 if (Decls->empty() || Decls->back().first <= Offset) {
2499 Decls->push_back(LocDecl);
2500 return;
2501 }
2502
2503 LocDeclsTy::iterator I =
2504 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2505
2506 Decls->insert(I, LocDecl);
2507}
2508
2509void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2510 SmallVectorImpl<Decl *> &Decls) {
2511 if (File.isInvalid())
2512 return;
2513
2514 if (SourceMgr->isLoadedFileID(File)) {
2515 assert(Ctx->getExternalSource() && "No external source!");
2516 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2517 Decls);
2518 }
2519
2520 FileDeclsTy::iterator I = FileDecls.find(File);
2521 if (I == FileDecls.end())
2522 return;
2523
2524 LocDeclsTy &LocDecls = *I->second;
2525 if (LocDecls.empty())
2526 return;
2527
2528 LocDeclsTy::iterator BeginIt =
2529 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2530 return LD.first < Offset;
2531 });
2532 if (BeginIt != LocDecls.begin())
2533 --BeginIt;
2534
2535 // If we are pointing at a top-level decl inside an objc container, we need
2536 // to backtrack until we find it otherwise we will fail to report that the
2537 // region overlaps with an objc container.
2538 while (BeginIt != LocDecls.begin() &&
2539 BeginIt->second->isTopLevelDeclInObjCContainer())
2540 --BeginIt;
2541
2542 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2543 LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),
2544 llvm::less_first());
2545 if (EndIt != LocDecls.end())
2546 ++EndIt;
2547
2548 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2549 Decls.push_back(DIt->second);
2550}
2551
2553 unsigned Line, unsigned Col) const {
2555 SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);
2556 return SM.getMacroArgExpandedLocation(Loc);
2557}
2558
2560 unsigned Offset) const {
2562 SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);
2563 return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
2564}
2565
2566/// If \arg Loc is a loaded location from the preamble, returns
2567/// the corresponding local location of the main file, otherwise it returns
2568/// \arg Loc.
2570 FileID PreambleID;
2571 if (SourceMgr)
2572 PreambleID = SourceMgr->getPreambleFileID();
2573
2574 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2575 return Loc;
2576
2577 unsigned Offs;
2578 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2579 SourceLocation FileLoc
2580 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2581 return FileLoc.getLocWithOffset(Offs);
2582 }
2583
2584 return Loc;
2585}
2586
2587/// If \arg Loc is a local location of the main file but inside the
2588/// preamble chunk, returns the corresponding loaded location from the
2589/// preamble, otherwise it returns \arg Loc.
2591 FileID PreambleID;
2592 if (SourceMgr)
2593 PreambleID = SourceMgr->getPreambleFileID();
2594
2595 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2596 return Loc;
2597
2598 unsigned Offs;
2599 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2600 Offs < Preamble->getBounds().Size) {
2601 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2602 return FileLoc.getLocWithOffset(Offs);
2603 }
2604
2605 return Loc;
2606}
2607
2609 FileID FID;
2610 if (SourceMgr)
2611 FID = SourceMgr->getPreambleFileID();
2612
2613 if (Loc.isInvalid() || FID.isInvalid())
2614 return false;
2615
2616 return SourceMgr->isInFileID(Loc, FID);
2617}
2618
2620 FileID FID;
2621 if (SourceMgr)
2622 FID = SourceMgr->getMainFileID();
2623
2624 if (Loc.isInvalid() || FID.isInvalid())
2625 return false;
2626
2627 return SourceMgr->isInFileID(Loc, FID);
2628}
2629
2631 FileID FID;
2632 if (SourceMgr)
2633 FID = SourceMgr->getPreambleFileID();
2634
2635 if (FID.isInvalid())
2636 return {};
2637
2638 return SourceMgr->getLocForEndOfFile(FID);
2639}
2640
2642 FileID FID;
2643 if (SourceMgr)
2644 FID = SourceMgr->getMainFileID();
2645
2646 if (FID.isInvalid())
2647 return {};
2648
2649 return SourceMgr->getLocForStartOfFile(FID);
2650}
2651
2652llvm::iterator_range<PreprocessingRecord::iterator>
2654 if (isMainFileAST()) {
2656 Mod = Reader->getModuleManager().getPrimaryModule();
2657 return Reader->getModulePreprocessedEntities(Mod);
2658 }
2659
2660 if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())
2661 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2662
2663 return llvm::make_range(PreprocessingRecord::iterator(),
2665}
2666
2668 if (isMainFileAST()) {
2670 Mod = Reader->getModuleManager().getPrimaryModule();
2671 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2672 if (!Fn(context, D))
2673 return false;
2674 }
2675
2676 return true;
2677 }
2678
2680 TLEnd = top_level_end();
2681 TL != TLEnd; ++TL) {
2682 if (!Fn(context, *TL))
2683 return false;
2684 }
2685
2686 return true;
2687}
2688
2690 if (!Reader)
2691 return std::nullopt;
2692
2693 serialization::ModuleFile *Mod = nullptr;
2694 Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
2695 switch (M.Kind) {
2699 return true; // skip dependencies.
2701 Mod = &M;
2702 return true; // found it.
2704 return false; // look in dependencies.
2706 return false; // look in dependencies.
2707 }
2708
2709 return true;
2710 });
2711 if (Mod)
2712 return Mod->File;
2713
2714 return std::nullopt;
2715}
2716
2719}
2720
2722 auto &LangOpts = getLangOpts();
2723
2724 Language Lang;
2725 if (LangOpts.OpenCL)
2726 Lang = Language::OpenCL;
2727 else if (LangOpts.CUDA)
2728 Lang = Language::CUDA;
2729 else if (LangOpts.CPlusPlus)
2730 Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
2731 else
2732 Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
2733
2735 if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
2737
2738 // We don't know if input was preprocessed. Assume not.
2739 bool PP = false;
2740
2741 return InputKind(Lang, Fmt, PP);
2742}
2743
2744#ifndef NDEBUG
2745ASTUnit::ConcurrencyState::ConcurrencyState() {
2746 Mutex = new std::recursive_mutex;
2747}
2748
2749ASTUnit::ConcurrencyState::~ConcurrencyState() {
2750 delete static_cast<std::recursive_mutex *>(Mutex);
2751}
2752
2753void ASTUnit::ConcurrencyState::start() {
2754 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
2755 assert(acquired && "Concurrent access to ASTUnit!");
2756}
2757
2758void ASTUnit::ConcurrencyState::finish() {
2759 static_cast<std::recursive_mutex *>(Mutex)->unlock();
2760}
2761
2762#else // NDEBUG
2763
2764ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
2765ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2766void ASTUnit::ConcurrencyState::start() {}
2767void ASTUnit::ConcurrencyState::finish() {}
2768
2769#endif // NDEBUG
Defines the clang::ASTContext interface.
static void checkAndSanitizeDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiagnostics, SourceManager &SM)
Definition ASTUnit.cpp:1129
static void CalculateHiddenNames(const CodeCompletionContext &Context, CodeCompletionResult *Results, unsigned NumResults, ASTContext &Ctx, llvm::StringSet< llvm::BumpPtrAllocator > &HiddenNames)
Helper function that computes which global names are hidden by the local code-completion results.
Definition ASTUnit.cpp:2032
static uint64_t getDeclShowContexts(const NamedDecl *ND, const LangOptions &LangOpts, bool &IsNestedNameSpecifier)
Determine the set of code-completion contexts in which this declaration should be shown.
Definition ASTUnit.cpp:283
static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash)
Add the given declaration to the hash of all top-level entities.
Definition ASTUnit.cpp:948
static bool moveOnNoError(llvm::ErrorOr< T > Val, T &Output)
Definition ASTUnit.cpp:144
static std::unique_ptr< T > valueOrNull(llvm::ErrorOr< std::unique_ptr< T > > Val)
Definition ASTUnit.cpp:137
static std::pair< unsigned, unsigned > makeStandaloneRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Definition ASTUnit.cpp:1285
static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl< char > &Buffer, Sema &S, raw_ostream &OS)
Definition ASTUnit.cpp:2389
static std::unique_ptr< llvm::MemoryBuffer > getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation, llvm::vfs::FileSystem *VFS, StringRef FilePath, bool isVolatile)
Get a source buffer for MainFilePath, handling all file-to-file and file-to-buffer remappings inside ...
Definition ASTUnit.cpp:154
const unsigned DefaultPreambleRebuildInterval
After failing to build a precompiled preamble (due to errors in the source that occurs in the preambl...
Definition ASTUnit.cpp:230
static void checkAndRemoveNonDriverDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiags)
Definition ASTUnit.cpp:1123
static bool isInMainFile(const clang::Diagnostic &D)
Definition ASTUnit.cpp:652
static ASTUnit::StandaloneDiagnostic makeStandaloneDiagnostic(const LangOptions &LangOpts, const StoredDiagnostic &InDiag)
Definition ASTUnit.cpp:1306
static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag)
Definition ASTUnit.cpp:1118
static std::atomic< unsigned > ActiveASTUnitObjects
Tracks the number of ASTUnit objects that are currently active.
Definition ASTUnit.cpp:235
static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM, const LangOptions &LangOpts, const FixItHint &InFix)
Definition ASTUnit.cpp:1293
static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash)
Add the given macro to the hash of all top-level entities.
Definition ASTUnit.cpp:925
Defines the Diagnostic-related interfaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::FileManager interface and associated types.
FormatToken * Next
The next token in the unwrapped line.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Definition MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
#define SM(sm)
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
This file declares facilities that support code completion.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines the clang::TargetOptions class.
Allows QualTypes to be sorted and hence used in maps and sets.
C Language Family Type Representation.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Definition ASTConsumer.h:34
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
Definition ASTContext.h:926
Abstract base class to use for AST consumer-based frontend actions.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Abstract interface for callback invocations by the ASTReader.
Definition ASTReader.h:117
@ ARR_None
The client can't handle any AST loading failures.
Definition ASTReader.h:1829
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities=ARR_ConfigurationMismatch|ARR_OutOfDate)
Read the control block for the named AST file.
@ Success
The control block was read successfully.
Definition ASTReader.h:453
@ ConfigurationMismatch
The AST file was written with a different language/target configuration.
Definition ASTReader.h:470
@ OutOfDate
The AST file is out-of-date relative to its input files, and needs to be regenerated.
Definition ASTReader.h:463
@ Failure
The AST file itself appears corrupted.
Definition ASTReader.h:456
@ VersionMismatch
The AST file was written by a different version of Clang.
Definition ASTReader.h:466
@ HadErrors
The AST file has errors.
Definition ASTReader.h:473
@ Missing
The AST file was missing.
Definition ASTReader.h:459
Utility class for loading a ASTContext from an AST file.
Definition ASTUnit.h:90
unsigned & getCurrentTopLevelHashValue()
Retrieve a reference to the current top-level name hash value.
Definition ASTUnit.h:575
void enableSourceFileDiagnostics()
Enable source-range based diagnostic messages.
Definition ASTUnit.cpp:275
void addFileLevelDecl(Decl *D)
Add a new local file-level declaration.
Definition ASTUnit.cpp:2470
const FileManager & getFileManager() const
Definition ASTUnit.h:507
void CodeComplete(StringRef File, unsigned Line, unsigned Column, ArrayRef< RemappedFile > RemappedFiles, bool IncludeMacros, bool IncludeCodePatterns, bool IncludeBriefComments, CodeCompleteConsumer &Consumer, std::shared_ptr< PCHContainerOperations > PCHContainerOps, llvm::IntrusiveRefCntPtr< DiagnosticsEngine > Diag, LangOptions &LangOpts, llvm::IntrusiveRefCntPtr< SourceManager > SourceMgr, llvm::IntrusiveRefCntPtr< FileManager > FileMgr, SmallVectorImpl< StoredDiagnostic > &StoredDiagnostics, SmallVectorImpl< const llvm::MemoryBuffer * > &OwnedBuffers, std::unique_ptr< SyntaxOnlyAction > Act)
Perform code completion at the given file, line, and column within this translation unit.
Definition ASTUnit.cpp:2209
cached_completion_iterator cached_completion_end()
Definition ASTUnit.h:663
static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts, const LangOptions *LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false)
Create a ASTUnit from an AST file.
Definition ASTUnit.cpp:730
bool serialize(raw_ostream &OS)
Serialize this translation unit with the given output stream.
Definition ASTUnit.cpp:2400
ASTDeserializationListener * getDeserializationListener()
Definition ASTUnit.cpp:702
bool Reparse(std::shared_ptr< PCHContainerOperations > PCHContainerOps, ArrayRef< RemappedFile > RemappedFiles={}, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Reparse the source files using the same command-line options that were originally used to produce thi...
Definition ASTUnit.cpp:1893
std::unique_ptr< llvm::MemoryBuffer > getBufferForFile(StringRef Filename, std::string *ErrorStr=nullptr)
Definition ASTUnit.cpp:709
llvm::StringMap< unsigned > & getCachedCompletionTypes()
Retrieve the mapping from formatted type names to unique type identifiers.
Definition ASTUnit.h:322
const DiagnosticsEngine & getDiagnostics() const
Definition ASTUnit.h:446
SourceLocation getLocation(const FileEntry *File, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
Definition ASTUnit.cpp:2552
void ResetForParse()
Free data that will be re-generated on the next parse.
Definition ASTUnit.cpp:1952
llvm::IntrusiveRefCntPtr< SourceManager > getSourceManagerPtr()
Definition ASTUnit.h:454
InputKind getInputKind() const
Determine the input kind this AST unit represents.
Definition ASTUnit.cpp:2721
OptionalFileEntryRef getPCHFile()
Get the PCH file if one was included.
Definition ASTUnit.cpp:2689
StringRef getMainFileName() const
Definition ASTUnit.cpp:1516
Sema & getSema() const
Definition ASTUnit.h:482
SourceLocation mapLocationToPreamble(SourceLocation Loc) const
If Loc is a local location of the main file but inside the preamble chunk, returns the corresponding ...
Definition ASTUnit.cpp:2590
cached_completion_iterator cached_completion_begin()
Definition ASTUnit.h:659
const LangOptions & getLangOpts() const
Definition ASTUnit.h:487
bool isMainFileAST() const
Definition ASTUnit.h:441
std::vector< Decl * >::iterator top_level_iterator
Definition ASTUnit.h:532
const SourceManager & getSourceManager() const
Definition ASTUnit.h:452
SourceLocation getEndOfPreambleFileID() const
Definition ASTUnit.cpp:2630
std::vector< CachedCodeCompletionResult >::iterator cached_completion_iterator
Definition ASTUnit.h:656
llvm::IntrusiveRefCntPtr< DiagnosticsEngine > getDiagnosticsPtr()
Definition ASTUnit.h:448
static ASTUnit * LoadFromCompilerInvocationAction(std::shared_ptr< CompilerInvocation > CI, std::shared_ptr< PCHContainerOperations > PCHContainerOps, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, FrontendAction *Action=nullptr, ASTUnit *Unit=nullptr, bool Persistent=true, StringRef ResourceFilesPath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, unsigned PrecompilePreambleAfterNParses=0, bool CacheCodeCompletionResults=false, bool UserFilesAreVolatile=false, std::unique_ptr< ASTUnit > *ErrAST=nullptr)
Create an ASTUnit from a source file, via a CompilerInvocation object, by invoking the optionally pro...
Definition ASTUnit.cpp:1567
@ LoadASTOnly
Load the AST, but do not restore Sema state.
Definition ASTUnit.h:719
@ LoadEverything
Load everything, including Sema.
Definition ASTUnit.h:722
top_level_iterator top_level_end()
Definition ASTUnit.h:541
SourceLocation getStartOfMainFileID() const
Definition ASTUnit.cpp:2641
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition ASTUnit.cpp:692
IntrusiveRefCntPtr< FileManager > getFileManagerPtr()
Definition ASTUnit.h:509
bool(*)(void *context, const Decl *D) DeclVisitorFn
Type for a function iterating over a number of declarations.
Definition ASTUnit.h:679
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn)
Iterate over local declarations (locally parsed if this is a parsed source file or the loaded declara...
Definition ASTUnit.cpp:2667
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr()
Definition ASTUnit.h:502
llvm::iterator_range< PreprocessingRecord::iterator > getLocalPreprocessingEntities() const
Returns an iterator range for the local preprocessing entities of the local Preprocessor,...
Definition ASTUnit.cpp:2653
top_level_iterator top_level_begin()
Definition ASTUnit.h:534
ASTMutationListener * getASTMutationListener()
Definition ASTUnit.cpp:696
TranslationUnitKind getTranslationUnitKind() const
Determine what kind of translation unit this AST represents.
Definition ASTUnit.h:698
static std::unique_ptr< ASTUnit > LoadFromCommandLine(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< 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)
LoadFromCommandLine - Create an ASTUnit from a vector of command line arguments, which must specify e...
Definition ASTUnit.cpp:1783
void setPreprocessor(std::shared_ptr< Preprocessor > pp)
Definition ASTUnit.cpp:271
StringRef getASTFileName() const
If this ASTUnit came from an AST file, returns the filename for it.
Definition ASTUnit.cpp:1534
bool Save(StringRef File)
Save this translation unit to a file with the given name.
Definition ASTUnit.cpp:2369
static std::unique_ptr< ASTUnit > create(std::shared_ptr< CompilerInvocation > CI, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile)
Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
Definition ASTUnit.cpp:1544
void addTopLevelDecl(Decl *D)
Add a new top-level declaration.
Definition ASTUnit.h:559
bool isInMainFileID(SourceLocation Loc) const
Definition ASTUnit.cpp:2619
bool isModuleFile() const
Returns true if the ASTUnit was constructed from a serialized module file.
Definition ASTUnit.cpp:2717
void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, SmallVectorImpl< Decl * > &Decls)
Get the decls that are contained in a file in the Offset/Length range.
Definition ASTUnit.cpp:2509
const ASTContext & getASTContext() const
Definition ASTUnit.h:462
bool isInPreambleFileID(SourceLocation Loc) const
Definition ASTUnit.cpp:2608
SourceLocation mapLocationFromPreamble(SourceLocation Loc) const
If Loc is a loaded location from the preamble, returns the corresponding local location of the main f...
Definition ASTUnit.cpp:2569
std::pair< std::string, llvm::MemoryBuffer * > RemappedFile
A mapping from a file name to the memory buffer that stores the remapped contents of that file.
Definition ASTUnit.h:705
Writes an AST file containing the contents of a translation unit.
Definition ASTWriter.h:97
LocalDeclID getDeclID(const Decl *D)
Determine the local declaration ID of an already-emitted declaration.
ASTFileSignature WriteAST(llvm::PointerUnion< Sema *, Preprocessor * > Subject, StringRef OutputFile, Module *WritingModule, StringRef isysroot, bool ShouldCacheASTInMemory=false)
Write a precompiled header or a module with the AST produced by the Sema object, or a dependency scan...
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
SourceLocation getEnd() const
SourceLocation getBegin() const
Abstract interface for a consumer of code-completion information.
Options controlling the behavior of code completion.
unsigned IncludeCodePatterns
Show code patterns in code completion results.
unsigned IncludeFixIts
Include results after corrections (small fix-its), e.g.
unsigned LoadExternal
Hint whether to load data from the external AST to provide full results.
unsigned IncludeMacros
Show macros in code completion results.
unsigned IncludeBriefComments
Show brief documentation comments in code completion results.
unsigned IncludeGlobals
Show top-level decls in code completion results.
A builder class used to construct new code-completion strings.
The context in which code completion occurred, so that the code-completion consumer can process the r...
@ CCC_TypeQualifiers
Code completion within a type-qualifier list.
@ CCC_ObjCMessageReceiver
Code completion occurred where an Objective-C message receiver is expected.
@ CCC_PreprocessorExpression
Code completion occurred within a preprocessor expression.
@ CCC_ObjCCategoryName
Code completion where an Objective-C category name is expected.
@ CCC_ObjCIvarList
Code completion occurred within the instance variable list of an Objective-C interface,...
@ CCC_Statement
Code completion occurred where a statement (or declaration) is expected in a function,...
@ CCC_Type
Code completion occurred where a type name is expected.
@ CCC_ArrowMemberAccess
Code completion occurred on the right-hand side of a member access expression using the arrow operato...
@ CCC_ClassStructUnion
Code completion occurred within a class, struct, or union.
@ CCC_ObjCInterface
Code completion occurred within an Objective-C interface, protocol, or category interface.
@ CCC_ObjCPropertyAccess
Code completion occurred on the right-hand side of an Objective-C property access expression.
@ CCC_Expression
Code completion occurred where an expression is expected.
@ CCC_SelectorName
Code completion for a selector, as in an @selector expression.
@ CCC_TopLevelOrExpression
Code completion at a top level, i.e.
@ CCC_EnumTag
Code completion occurred after the "enum" keyword, to indicate an enumeration name.
@ CCC_UnionTag
Code completion occurred after the "union" keyword, to indicate a union name.
@ CCC_ParenthesizedExpression
Code completion in a parenthesized expression, which means that we may also have types here in C and ...
@ CCC_TopLevel
Code completion occurred within a "top-level" completion context, e.g., at namespace or global scope.
@ CCC_ClassOrStructTag
Code completion occurred after the "struct" or "class" keyword, to indicate a struct or class name.
@ CCC_ObjCClassMessage
Code completion where an Objective-C class message is expected.
@ CCC_ObjCImplementation
Code completion occurred within an Objective-C implementation or category implementation.
@ CCC_IncludedFile
Code completion inside the filename part of a include directive.
@ CCC_ObjCInstanceMessage
Code completion where an Objective-C instance message is expected.
@ CCC_SymbolOrNewName
Code completion occurred where both a new name and an existing symbol is permissible.
@ CCC_Recovery
An unknown context, in which we are recovering from a parsing error and don't know which completions ...
@ CCC_ObjCProtocolName
Code completion occurred where a protocol name is expected.
@ CCC_OtherWithMacros
An unspecified code-completion context where we should also add macro completions.
@ CCC_NewName
Code completion occurred where a new name is expected.
@ CCC_MacroNameUse
Code completion occurred where a macro name is expected (without any arguments, in the case of a func...
@ CCC_Symbol
Code completion occurred where an existing name(such as type, functionor variable) is expected.
@ CCC_Attribute
Code completion of an attribute name.
@ CCC_Other
An unspecified code-completion context.
@ CCC_DotMemberAccess
Code completion occurred on the right-hand side of a member access expression using the dot operator.
@ CCC_MacroName
Code completion occurred where an macro is being defined.
@ CCC_Namespace
Code completion occurred where a namespace or namespace alias is expected.
@ CCC_PreprocessorDirective
Code completion occurred where a preprocessor directive is expected.
@ CCC_NaturalLanguage
Code completion occurred in a context where natural language is expected, e.g., a comment or string l...
@ CCC_ObjCInterfaceName
Code completion where the name of an Objective-C class is expected.
Captures a result of code completion.
const NamedDecl * Declaration
When Kind == RK_Declaration or RK_Pattern, the declaration we are referring to.
A "string" used to describe how code completion can be performed for an entity.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
std::shared_ptr< Preprocessor > getPreprocessorPtr()
std::unique_ptr< Sema > takeSema()
IntrusiveRefCntPtr< ASTContext > getASTContextPtr() const
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Preprocessor & getPreprocessor() const
Return the current preprocessor.
IntrusiveRefCntPtr< TargetInfo > getTargetPtr() const
std::shared_ptr< CompilerInvocation > getInvocationPtr()
bool hadModuleLoaderFatalFailure() const
void setSourceManager(llvm::IntrusiveRefCntPtr< SourceManager > Value)
setSourceManager - Replace the current source manager.
CompilerInvocation & getInvocation()
std::unique_ptr< ASTConsumer > takeASTConsumer()
takeASTConsumer - Remove the current AST consumer and give ownership to the caller.
void setFileManager(IntrusiveRefCntPtr< FileManager > Value)
Replace the current file manager.
Helper class for holding the data necessary to invoke the compiler.
PreprocessorOptions & getPreprocessorOpts()
LangOptions & getLangOpts()
Mutable getters.
FrontendOptions & getFrontendOpts()
DiagnosticOptions & getDiagnosticOpts()
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
bool isFileContext() const
Definition DeclBase.h:2180
bool isTranslationUnit() const
Definition DeclBase.h:2185
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
Definition DeclBase.h:793
unsigned getIdentifierNamespace() const
Definition DeclBase.h:889
SourceLocation getLocation() const
Definition DeclBase.h:439
@ IDNS_NonMemberOperator
This declaration is a C++ operator declared in a non-class context.
Definition DeclBase.h:168
@ IDNS_Ordinary
Ordinary names.
Definition DeclBase.h:144
@ IDNS_Type
Types, declared with 'struct foo', typedefs, etc.
Definition DeclBase.h:130
@ IDNS_Member
Members, declared with object declarations within tag definitions.
Definition DeclBase.h:136
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
Definition DeclBase.h:140
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
Definition DeclBase.h:125
DeclContext * getDeclContext()
Definition DeclBase.h:448
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:918
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
std::string getAsString() const
Retrieve the human-readable string for this name.
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info)
Handle this diagnostic, reporting it to the user or capturing it to a log as needed.
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
const SourceLocation & getLocation() const
SourceManager & getSourceManager() const
bool hasSourceManager() const
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
void setNumWarnings(unsigned NumWarnings)
Definition Diagnostic.h:889
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
Level
The level of the diagnostic, after it has been through mapping.
Definition Diagnostic.h:237
DiagnosticConsumer * getClient()
Definition Diagnostic.h:607
unsigned getNumWarnings() const
Definition Diagnostic.h:887
void Reset(bool soft=false)
Reset the state of the diagnostic object to its initial configuration.
Cached information about one file (either on disk or in the virtual file system).
Definition FileEntry.h:302
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isInvalid() const
Implements support for file system lookup, file system caching, and directory search management.
Definition FileManager.h:53
llvm::vfs::FileSystem & getVirtualFileSystem() const
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
llvm::Expected< FileEntryRef > getSTDIN()
Get the FileEntryRef for stdin, returning an error if stdin cannot be read.
Keeps track of options that affect how file operations are performed.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
Definition Diagnostic.h:79
bool BeforePreviousInsertions
Definition Diagnostic.h:93
CharSourceRange RemoveRange
Code that should be replaced to correct the error.
Definition Diagnostic.h:83
CharSourceRange InsertFromRange
Code in the specific range that should be inserted in the insertion location.
Definition Diagnostic.h:87
std::string CodeToInsert
The actual code to insert at the insertion location, as a string.
Definition Diagnostic.h:91
Abstract base class for actions which can be performed by the frontend.
virtual void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
llvm::Error Execute()
Set the source manager's main input file, and run the action.
virtual TranslationUnitKind getTranslationUnitKind()
For AST-based actions, the kind of translation unit we're handling.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
An input file for the front end.
llvm::MemoryBufferRef getBuffer() const
StringRef getFile() const
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned SkipFunctionBodies
Skip over function bodies to speed up parsing in cases you do not need them (e.g.
CodeCompleteOptions CodeCompleteOpts
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
A SourceLocation and its associated SourceManager.
const SourceManager & getManager() const
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
std::vector< SystemHeaderPrefix > SystemHeaderPrefixes
User-specified system header prefixes.
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
std::vector< Entry > UserEntries
User specified include entries.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
The kind of a file that we've been handed as an input.
Format
The input file format.
@ CMK_ModuleMap
Compiling a module from a module map.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompilingModule() const
Are we compiling a module?
static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Accepts a range and returns a character range with file locations.
Definition Lexer.cpp:951
The module cache used for compiling modules implicitly.
Definition ModuleCache.h:26
Describes a module or submodule.
Definition Module.h:144
bool isNamedModule() const
Does this Module is a named module of a standard named module?
Definition Module.h:224
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:487
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
This abstract interface provides operations for unwrapping containers for serialized ASTs (precompile...
virtual llvm::ArrayRef< llvm::StringRef > getFormats() const =0
Equivalent to the format passed to -fmodule-format=.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition PPCallbacks.h:37
A set of callbacks to gather useful information while building a preamble.
static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, IntrusiveRefCntPtr< DiagnosticsEngine > Diagnostics, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, bool StoreInMemory, StringRef StoragePath, PreambleCallbacks &Callbacks)
Try to build PrecompiledPreamble for Invocation.
Iteration over the preprocessed entities.
A record of the steps taken while preprocessing a source file, including the various preprocessing di...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
bool RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
bool DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
void addRemappedFile(StringRef From, StringRef To)
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8372
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:854
ASTContext & Context
Definition Sema.h:1283
const LangOptions & getLangOpts() const
Definition Sema.h:918
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
Represents a diagnostic in a form that can be retained until its corresponding source manager is dest...
unsigned getID() const
ArrayRef< FixItHint > getFixIts() const
ArrayRef< CharSourceRange > getRanges() const
DiagnosticsEngine::Level getLevel() const
const FullSourceLoc & getLocation() const
StringRef getMessage() const
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts)
Construct a target for the given options.
Definition Targets.cpp:792
Token - This structure provides full information about a lexed token.
Definition Token.h:36
IdentifierInfo * getIdentifierInfo() const
Definition Token.h:189
Information about a module that has been loaded by the ASTReader.
Definition ModuleFile.h:130
FileEntryRef File
The file entry for the module file.
Definition ModuleFile.h:185
std::string FileName
The file name of the module file.
Definition ModuleFile.h:145
ModuleKind Kind
The type of this module.
Definition ModuleFile.h:142
@ CXCursor_MacroDefinition
Definition Index.h:2288
Defines the clang::TargetInfo interface.
Public enums and private classes that are part of the SourceManager implementation.
@ FixIt
Parse and apply any fixits to the source.
@ MK_PCH
File is a PCH file treated as such.
Definition ModuleFile.h:51
@ MK_Preamble
File is a PCH file treated as the preamble.
Definition ModuleFile.h:54
@ MK_MainFile
File is a PCH file treated as the actual main file.
Definition ModuleFile.h:57
@ MK_ExplicitModule
File is an explicitly-loaded module.
Definition ModuleFile.h:48
@ MK_ImplicitModule
File is an implicitly-loaded module.
Definition ModuleFile.h:45
@ MK_PrebuiltModule
File is from a prebuilt module path.
Definition ModuleFile.h:60
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:208
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromOverlayFiles(ArrayRef< std::string > VFSOverlayFiles, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)
@ CCP_NestedNameSpecifier
Priority for a nested-name-specifier.
@ CCP_CodePattern
Priority for a code pattern.
SkipFunctionBodiesScope
Enumerates the available scopes for skipping function bodies.
Definition ASTUnit.h:84
@ Parse
Parse the block; this code is always used.
Definition Parser.h:137
std::unique_ptr< CompilerInvocation > createInvocation(ArrayRef< const char * > Args, CreateInvocationOptions Opts={})
Interpret clang arguments in preparation to parse a file.
Language
The language for the input, used to select and validate the language standard and possible actions.
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
SimplifiedTypeClass
A simplified classification of types used when determining "similar" types for code completion.
const FunctionProtoType * T
CaptureDiagsKind
Enumerates the available kinds for capturing diagnostics.
Definition ASTUnit.h:87
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...
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, llvm::vfs::FileSystem &VFS, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
Definition Warnings.cpp:46
TranslationUnitKind
Describes the kind of translation unit being processed.
@ TU_Complete
The translation unit is a complete translation unit.
@ CCF_ExactTypeMatch
Divide by this factor when a code-completion result's type exactly matches the type we expect.
@ CCF_SimilarTypeMatch
Divide by this factor when a code-completion result's type is similar to the type we expect (e....
SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T)
Determine the simplified type class of the given canonical type.
unsigned getMacroUsagePriority(StringRef MacroName, const LangOptions &LangOpts, bool PreferredTypeIsPointer=false)
Determine the priority to be given to a macro code completion result with the given name.
DisableValidationForModuleKind
Whether to disable the normal validation performed on precompiled headers and module files when they ...
@ None
Perform validation, don't disable it.
@ All
Disable validation for all kinds.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, const llvm::MemoryBufferRef &Buffer, unsigned MaxLines)
Runs lexer to compute suggested preamble bounds.
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:62
QualType getDeclUsageType(ASTContext &C, NestedNameSpecifier Qualifier, const NamedDecl *ND)
Determine the type that this declaration will have if it is used as a type or in an expression.
unsigned long uint64_t
#define false
Definition stdbool.h:26
llvm::BitstreamWriter Stream
Definition ASTUnit.cpp:215
SmallString< 128 > Buffer
Definition ASTUnit.cpp:214
ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts)
Definition ASTUnit.cpp:218
A cached code-completion result, which may be introduced in one of many different contexts.
Definition ASTUnit.h:284
CodeCompletionString * Completion
The code-completion string corresponding to this completion result.
Definition ASTUnit.h:287
DiagnosticsEngine::Level Level
Definition ASTUnit.h:101
std::vector< std::pair< unsigned, unsigned > > Ranges
Definition ASTUnit.h:105
std::vector< StandaloneFixIt > FixIts
Definition ASTUnit.h:106
std::pair< unsigned, unsigned > InsertFromRange
Definition ASTUnit.h:94
std::pair< unsigned, unsigned > RemoveRange
Definition ASTUnit.h:93
Optional inputs to createInvocation.
Definition Utils.h:196
IntrusiveRefCntPtr< DiagnosticsEngine > Diags
Receives diagnostics encountered while parsing command-line flags.
Definition Utils.h:199
bool ProbePrecompiled
Allow the driver to probe the filesystem for PCH files.
Definition Utils.h:212
IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
Used e.g.
Definition Utils.h:203
OverloadCandidate - A single candidate in an overload set (C++ 13.3).
Definition Overload.h:926
unsigned Size
Size of the preamble in bytes.
Definition Lexer.h:62
Describes how types, statements, expressions, and declarations should be printed.