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