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<LocalDeclID> 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<LocalDeclID> 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());
1470 // The module file of the preamble.
1471 serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();
1472 for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1473 // Resolve the declaration ID to an actual declaration, possibly
1474 // deserializing the declaration in the process.
1475 if (Decl *D = Reader->GetDecl(Reader->getGlobalDeclID(MF, TopLevelDecl)))
1476 Resolved.push_back(D);
1477 }
1478 TopLevelDeclsInPreamble.clear();
1479 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1480}
1481
1482void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
1483 // Steal the created target, context, and preprocessor if they have been
1484 // created.
1485 assert(CI.hasInvocation() && "missing invocation");
1486 LangOpts = CI.getInvocation().LangOpts;
1487 TheSema = CI.takeSema();
1488 Consumer = CI.takeASTConsumer();
1489 if (CI.hasASTContext())
1490 Ctx = &CI.getASTContext();
1491 if (CI.hasPreprocessor())
1492 PP = CI.getPreprocessorPtr();
1493 CI.setSourceManager(nullptr);
1494 CI.setFileManager(nullptr);
1495 if (CI.hasTarget())
1496 Target = &CI.getTarget();
1497 Reader = CI.getASTReader();
1498 HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
1499}
1500
1501StringRef ASTUnit::getMainFileName() const {
1502 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1503 const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];
1504 if (Input.isFile())
1505 return Input.getFile();
1506 else
1507 return Input.getBuffer().getBufferIdentifier();
1508 }
1509
1510 if (SourceMgr) {
1511 if (OptionalFileEntryRef FE =
1512 SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID()))
1513 return FE->getName();
1514 }
1515
1516 return {};
1517}
1518
1519StringRef ASTUnit::getASTFileName() const {
1520 if (!isMainFileAST())
1521 return {};
1522
1524 Mod = Reader->getModuleManager().getPrimaryModule();
1525 return Mod.FileName;
1526}
1527
1528std::unique_ptr<ASTUnit>
1529ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
1531 CaptureDiagsKind CaptureDiagnostics,
1532 bool UserFilesAreVolatile) {
1533 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1534 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1537 AST->Diagnostics = Diags;
1538 AST->FileSystemOpts = CI->getFileSystemOpts();
1539 AST->Invocation = std::move(CI);
1540 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
1541 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1542 AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
1543 UserFilesAreVolatile);
1544 AST->ModuleCache = new InMemoryModuleCache;
1545
1546 return AST;
1547}
1548
1550 std::shared_ptr<CompilerInvocation> CI,
1551 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1553 ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
1554 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1555 unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
1556 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1557 assert(CI && "A CompilerInvocation is required");
1558
1559 std::unique_ptr<ASTUnit> OwnAST;
1560 ASTUnit *AST = Unit;
1561 if (!AST) {
1562 // Create the AST unit.
1563 OwnAST = create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1564 AST = OwnAST.get();
1565 if (!AST)
1566 return nullptr;
1567 }
1568
1569 if (!ResourceFilesPath.empty()) {
1570 // Override the resources path.
1571 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1572 }
1573 AST->OnlyLocalDecls = OnlyLocalDecls;
1574 AST->CaptureDiagnostics = CaptureDiagnostics;
1575 if (PrecompilePreambleAfterNParses > 0)
1576 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1577 AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
1578 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1579 AST->IncludeBriefCommentsInCodeCompletion = false;
1580
1581 // Recover resources if we crash before exiting this method.
1582 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1583 ASTUnitCleanup(OwnAST.get());
1584 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1585 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1586 DiagCleanup(Diags.get());
1587
1588 // We'll manage file buffers ourselves.
1589 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1590 CI->getFrontendOpts().DisableFree = false;
1591 ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
1592
1593 // Create the compiler instance to use for building the AST.
1594 std::unique_ptr<CompilerInstance> Clang(
1595 new CompilerInstance(std::move(PCHContainerOps)));
1596
1597 // Recover resources if we crash before exiting this method.
1598 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1599 CICleanup(Clang.get());
1600
1601 Clang->setInvocation(std::move(CI));
1602 AST->OriginalSourceFile =
1603 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1604
1605 // Set up diagnostics, capturing any diagnostics that would
1606 // otherwise be dropped.
1607 Clang->setDiagnostics(&AST->getDiagnostics());
1608
1609 // Create the target instance.
1610 if (!Clang->createTarget())
1611 return nullptr;
1612
1613 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1614 "Invocation must have exactly one source file!");
1615 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1617 "FIXME: AST inputs not yet supported here!");
1618 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1620 "IR inputs not support here!");
1621
1622 // Configure the various subsystems.
1623 AST->TheSema.reset();
1624 AST->Ctx = nullptr;
1625 AST->PP = nullptr;
1626 AST->Reader = nullptr;
1627
1628 // Create a file manager object to provide access to and cache the filesystem.
1629 Clang->setFileManager(&AST->getFileManager());
1630
1631 // Create the source manager.
1632 Clang->setSourceManager(&AST->getSourceManager());
1633
1634 FrontendAction *Act = Action;
1635
1636 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1637 if (!Act) {
1638 TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
1639 Act = TrackerAct.get();
1640 }
1641
1642 // Recover resources if we crash before exiting this method.
1643 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1644 ActCleanup(TrackerAct.get());
1645
1646 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
1647 AST->transferASTDataFromCompilerInstance(*Clang);
1648 if (OwnAST && ErrAST)
1649 ErrAST->swap(OwnAST);
1650
1651 return nullptr;
1652 }
1653
1654 if (Persistent && !TrackerAct) {
1655 Clang->getPreprocessor().addPPCallbacks(
1656 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1658 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1659 if (Clang->hasASTConsumer())
1660 Consumers.push_back(Clang->takeASTConsumer());
1661 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1662 *AST, AST->getCurrentTopLevelHashValue()));
1663 Clang->setASTConsumer(
1664 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1665 }
1666 if (llvm::Error Err = Act->Execute()) {
1667 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1668 AST->transferASTDataFromCompilerInstance(*Clang);
1669 if (OwnAST && ErrAST)
1670 ErrAST->swap(OwnAST);
1671
1672 return nullptr;
1673 }
1674
1675 // Steal the created target, context, and preprocessor.
1676 AST->transferASTDataFromCompilerInstance(*Clang);
1677
1678 Act->EndSourceFile();
1679
1680 if (OwnAST)
1681 return OwnAST.release();
1682 else
1683 return AST;
1684}
1685
1686bool ASTUnit::LoadFromCompilerInvocation(
1687 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1688 unsigned PrecompilePreambleAfterNParses,
1690 if (!Invocation)
1691 return true;
1692
1693 assert(VFS && "VFS is null");
1694
1695 // We'll manage file buffers ourselves.
1696 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1697 Invocation->getFrontendOpts().DisableFree = false;
1699 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
1700
1701 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1702 if (PrecompilePreambleAfterNParses > 0) {
1703 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1704 OverrideMainBuffer =
1705 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1707 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
1708 }
1709
1710 SimpleTimer ParsingTimer(WantTiming);
1711 ParsingTimer.setOutput("Parsing " + getMainFileName());
1712
1713 // Recover resources if we crash before exiting this method.
1714 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1715 MemBufferCleanup(OverrideMainBuffer.get());
1716
1717 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1718}
1719
1720std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1721 std::shared_ptr<CompilerInvocation> CI,
1722 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1724 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1725 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1726 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1727 bool UserFilesAreVolatile) {
1728 // Create the AST unit.
1729 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1730 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1731 AST->Diagnostics = Diags;
1732 AST->OnlyLocalDecls = OnlyLocalDecls;
1733 AST->CaptureDiagnostics = CaptureDiagnostics;
1734 AST->TUKind = TUKind;
1735 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1736 AST->IncludeBriefCommentsInCodeCompletion
1737 = IncludeBriefCommentsInCodeCompletion;
1738 AST->Invocation = std::move(CI);
1739 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1740 AST->FileMgr = FileMgr;
1741 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1742
1743 // Recover resources if we crash before exiting this method.
1744 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1745 ASTUnitCleanup(AST.get());
1746 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1747 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1748 DiagCleanup(Diags.get());
1749
1750 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1751 PrecompilePreambleAfterNParses,
1752 &AST->FileMgr->getVirtualFileSystem()))
1753 return nullptr;
1754 return AST;
1755}
1756
1757std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
1758 const char **ArgBegin, const char **ArgEnd,
1759 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1760 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
1761 bool StorePreamblesInMemory, StringRef PreambleStoragePath,
1762 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1763 ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
1764 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1765 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1766 bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
1767 bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
1768 bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
1769 std::unique_ptr<ASTUnit> *ErrAST,
1771 assert(Diags.get() && "no DiagnosticsEngine was provided");
1772
1773 // If no VFS was provided, create one that tracks the physical file system.
1774 // If '-working-directory' was passed as an argument, 'createInvocation' will
1775 // set this as the current working directory of the VFS.
1776 if (!VFS)
1777 VFS = llvm::vfs::createPhysicalFileSystem();
1778
1779 SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
1780
1781 std::shared_ptr<CompilerInvocation> CI;
1782
1783 {
1784 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
1785 &StoredDiagnostics, nullptr);
1786
1788 CIOpts.VFS = VFS;
1789 CIOpts.Diags = Diags;
1790 CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
1791 CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));
1792 if (!CI)
1793 return nullptr;
1794 }
1795
1796 // Override any files that need remapping
1797 for (const auto &RemappedFile : RemappedFiles) {
1798 CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1799 RemappedFile.second);
1800 }
1801 PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
1802 PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
1803 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
1804 PPOpts.SingleFileParseMode = SingleFileParse;
1805 PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
1806
1807 // Override the resources path.
1808 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1809
1810 CI->getFrontendOpts().SkipFunctionBodies =
1812
1813 if (ModuleFormat)
1814 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
1815
1816 // Create the AST unit.
1817 std::unique_ptr<ASTUnit> AST;
1818 AST.reset(new ASTUnit(false));
1819 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1820 AST->StoredDiagnostics.swap(StoredDiagnostics);
1821 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1822 AST->Diagnostics = Diags;
1823 AST->FileSystemOpts = CI->getFileSystemOpts();
1824 VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
1825 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
1826 AST->StorePreamblesInMemory = StorePreamblesInMemory;
1827 AST->PreambleStoragePath = PreambleStoragePath;
1828 AST->ModuleCache = new InMemoryModuleCache;
1829 AST->OnlyLocalDecls = OnlyLocalDecls;
1830 AST->CaptureDiagnostics = CaptureDiagnostics;
1831 AST->TUKind = TUKind;
1832 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1833 AST->IncludeBriefCommentsInCodeCompletion
1834 = IncludeBriefCommentsInCodeCompletion;
1835 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1836 AST->Invocation = CI;
1837 AST->SkipFunctionBodies = SkipFunctionBodies;
1838 if (ForSerialization)
1839 AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));
1840 // Zero out now to ease cleanup during crash recovery.
1841 CI = nullptr;
1842 Diags = nullptr;
1843
1844 // Recover resources if we crash before exiting this method.
1845 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1846 ASTUnitCleanup(AST.get());
1847
1848 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1849 PrecompilePreambleAfterNParses,
1850 VFS)) {
1851 // Some error occurred, if caller wants to examine diagnostics, pass it the
1852 // ASTUnit.
1853 if (ErrAST) {
1854 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1855 ErrAST->swap(AST);
1856 }
1857 return nullptr;
1858 }
1859
1860 return AST;
1861}
1862
1863bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1864 ArrayRef<RemappedFile> RemappedFiles,
1866 if (!Invocation)
1867 return true;
1868
1869 if (!VFS) {
1870 assert(FileMgr && "FileMgr is null on Reparse call");
1871 VFS = &FileMgr->getVirtualFileSystem();
1872 }
1873
1874 clearFileLevelDecls();
1875
1876 SimpleTimer ParsingTimer(WantTiming);
1877 ParsingTimer.setOutput("Reparsing " + getMainFileName());
1878
1879 // Remap files.
1880 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1881 for (const auto &RB : PPOpts.RemappedFileBuffers)
1882 delete RB.second;
1883
1884 Invocation->getPreprocessorOpts().clearRemappedFiles();
1885 for (const auto &RemappedFile : RemappedFiles) {
1886 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1887 RemappedFile.second);
1888 }
1889
1890 // If we have a preamble file lying around, or if we might try to
1891 // build a precompiled preamble, do so now.
1892 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1893 if (Preamble || PreambleRebuildCountdown > 0)
1894 OverrideMainBuffer =
1895 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1896
1897 // Clear out the diagnostics state.
1898 FileMgr.reset();
1900 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
1901 if (OverrideMainBuffer)
1902 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1903
1904 // Parse the sources
1905 bool Result =
1906 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1907
1908 // If we're caching global code-completion results, and the top-level
1909 // declarations have changed, clear out the code-completion cache.
1910 if (!Result && ShouldCacheCodeCompletionResults &&
1911 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1912 CacheCodeCompletionResults();
1913
1914 // We now need to clear out the completion info related to this translation
1915 // unit; it'll be recreated if necessary.
1916 CCTUInfo.reset();
1917
1918 return Result;
1919}
1920
1922 SavedMainFileBuffer.reset();
1923
1924 SourceMgr.reset();
1925 TheSema.reset();
1926 Ctx.reset();
1927 PP.reset();
1928 Reader.reset();
1929
1930 TopLevelDecls.clear();
1931 clearFileLevelDecls();
1932}
1933
1934//----------------------------------------------------------------------------//
1935// Code completion
1936//----------------------------------------------------------------------------//
1937
1938namespace {
1939
1940 /// Code completion consumer that combines the cached code-completion
1941 /// results from an ASTUnit with the code-completion results provided to it,
1942 /// then passes the result on to
1943 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
1944 uint64_t NormalContexts;
1945 ASTUnit &AST;
1947
1948 public:
1949 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
1950 const CodeCompleteOptions &CodeCompleteOpts)
1951 : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
1952 // Compute the set of contexts in which we will look when we don't have
1953 // any information about the specific context.
1954 NormalContexts
1968
1969 if (AST.getASTContext().getLangOpts().CPlusPlus)
1970 NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
1973 }
1974
1975 void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
1976 CodeCompletionResult *Results,
1977 unsigned NumResults) override;
1978
1979 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1980 OverloadCandidate *Candidates,
1981 unsigned NumCandidates,
1982 SourceLocation OpenParLoc,
1983 bool Braced) override {
1984 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
1985 OpenParLoc, Braced);
1986 }
1987
1988 CodeCompletionAllocator &getAllocator() override {
1989 return Next.getAllocator();
1990 }
1991
1992 CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
1993 return Next.getCodeCompletionTUInfo();
1994 }
1995 };
1996
1997} // namespace
1998
1999/// Helper function that computes which global names are hidden by the
2000/// local code-completion results.
2002 CodeCompletionResult *Results,
2003 unsigned NumResults,
2004 ASTContext &Ctx,
2005 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
2006 bool OnlyTagNames = false;
2007 switch (Context.getKind()) {
2027 break;
2028
2032 OnlyTagNames = true;
2033 break;
2034
2052 // We're looking for nothing, or we're looking for names that cannot
2053 // be hidden.
2054 return;
2055 }
2056
2058 for (unsigned I = 0; I != NumResults; ++I) {
2059 if (Results[I].Kind != Result::RK_Declaration)
2060 continue;
2061
2062 unsigned IDNS
2063 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
2064
2065 bool Hiding = false;
2066 if (OnlyTagNames)
2067 Hiding = (IDNS & Decl::IDNS_Tag);
2068 else {
2069 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
2072 if (Ctx.getLangOpts().CPlusPlus)
2073 HiddenIDNS |= Decl::IDNS_Tag;
2074 Hiding = (IDNS & HiddenIDNS);
2075 }
2076
2077 if (!Hiding)
2078 continue;
2079
2080 DeclarationName Name = Results[I].Declaration->getDeclName();
2081 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
2082 HiddenNames.insert(Identifier->getName());
2083 else
2084 HiddenNames.insert(Name.getAsString());
2085 }
2086}
2087
2088void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
2089 CodeCompletionContext Context,
2090 CodeCompletionResult *Results,
2091 unsigned NumResults) {
2092 // Merge the results we were given with the results we cached.
2093 bool AddedResult = false;
2094 uint64_t InContexts =
2095 Context.getKind() == CodeCompletionContext::CCC_Recovery
2096 ? NormalContexts : (1LL << Context.getKind());
2097 // Contains the set of names that are hidden by "local" completion results.
2098 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2100 SmallVector<Result, 8> AllResults;
2102 C = AST.cached_completion_begin(),
2103 CEnd = AST.cached_completion_end();
2104 C != CEnd; ++C) {
2105 // If the context we are in matches any of the contexts we are
2106 // interested in, we'll add this result.
2107 if ((C->ShowInContexts & InContexts) == 0)
2108 continue;
2109
2110 // If we haven't added any results previously, do so now.
2111 if (!AddedResult) {
2112 CalculateHiddenNames(Context, Results, NumResults, S.Context,
2113 HiddenNames);
2114 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2115 AddedResult = true;
2116 }
2117
2118 // Determine whether this global completion result is hidden by a local
2119 // completion result. If so, skip it.
2120 if (C->Kind != CXCursor_MacroDefinition &&
2121 HiddenNames.count(C->Completion->getTypedText()))
2122 continue;
2123
2124 // Adjust priority based on similar type classes.
2125 unsigned Priority = C->Priority;
2126 CodeCompletionString *Completion = C->Completion;
2127 if (!Context.getPreferredType().isNull()) {
2128 if (C->Kind == CXCursor_MacroDefinition) {
2129 Priority = getMacroUsagePriority(C->Completion->getTypedText(),
2130 S.getLangOpts(),
2131 Context.getPreferredType()->isAnyPointerType());
2132 } else if (C->Type) {
2135 Context.getPreferredType().getUnqualifiedType());
2137 if (ExpectedSTC == C->TypeClass) {
2138 // We know this type is similar; check for an exact match.
2139 llvm::StringMap<unsigned> &CachedCompletionTypes
2141 llvm::StringMap<unsigned>::iterator Pos
2142 = CachedCompletionTypes.find(QualType(Expected).getAsString());
2143 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
2145 else
2147 }
2148 }
2149 }
2150
2151 // Adjust the completion string, if required.
2152 if (C->Kind == CXCursor_MacroDefinition &&
2153 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
2154 // Create a new code-completion string that just contains the
2155 // macro name, without its arguments.
2156 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
2157 CCP_CodePattern, C->Availability);
2158 Builder.AddTypedTextChunk(C->Completion->getTypedText());
2160 Completion = Builder.TakeString();
2161 }
2162
2163 AllResults.push_back(Result(Completion, Priority, C->Kind,
2164 C->Availability));
2165 }
2166
2167 // If we did not add any cached completion results, just forward the
2168 // results we were given to the next consumer.
2169 if (!AddedResult) {
2170 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2171 return;
2172 }
2173
2174 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2175 AllResults.size());
2176}
2177
2179 StringRef File, unsigned Line, unsigned Column,
2180 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
2181 bool IncludeCodePatterns, bool IncludeBriefComments,
2182 CodeCompleteConsumer &Consumer,
2183 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2184 DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr,
2185 FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
2187 std::unique_ptr<SyntaxOnlyAction> Act) {
2188 if (!Invocation)
2189 return;
2190
2191 SimpleTimer CompletionTimer(WantTiming);
2192 CompletionTimer.setOutput("Code completion @ " + File + ":" +
2193 Twine(Line) + ":" + Twine(Column));
2194
2195 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2196
2197 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2198 CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
2199 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2200
2201 CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2202 CachedCompletionResults.empty();
2203 CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2204 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2205 CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2206 CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
2207 CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
2208
2209 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2210
2211 FrontendOpts.CodeCompletionAt.FileName = std::string(File);
2212 FrontendOpts.CodeCompletionAt.Line = Line;
2213 FrontendOpts.CodeCompletionAt.Column = Column;
2214
2215 // Set the language options appropriately.
2216 LangOpts = CCInvocation->getLangOpts();
2217
2218 // Spell-checking and warnings are wasteful during code-completion.
2219 LangOpts.SpellChecking = false;
2220 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
2221
2222 std::unique_ptr<CompilerInstance> Clang(
2223 new CompilerInstance(PCHContainerOps));
2224
2225 // Recover resources if we crash before exiting this method.
2226 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2227 CICleanup(Clang.get());
2228
2229 auto &Inv = *CCInvocation;
2230 Clang->setInvocation(std::move(CCInvocation));
2231 OriginalSourceFile =
2232 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2233
2234 // Set up diagnostics, capturing any diagnostics produced.
2235 Clang->setDiagnostics(&Diag);
2236 CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
2237 Clang->getDiagnostics(),
2238 &StoredDiagnostics, nullptr);
2239 ProcessWarningOptions(Diag, Inv.getDiagnosticOpts());
2240
2241 // Create the target instance.
2242 if (!Clang->createTarget()) {
2243 Clang->setInvocation(nullptr);
2244 return;
2245 }
2246
2247 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2248 "Invocation must have exactly one source file!");
2249 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2251 "FIXME: AST inputs not yet supported here!");
2252 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2254 "IR inputs not support here!");
2255
2256 // Use the source and file managers that we were given.
2257 Clang->setFileManager(&FileMgr);
2258 Clang->setSourceManager(&SourceMgr);
2259
2260 // Remap files.
2261 PreprocessorOpts.clearRemappedFiles();
2262 PreprocessorOpts.RetainRemappedFileBuffers = true;
2263 for (const auto &RemappedFile : RemappedFiles) {
2264 PreprocessorOpts.addRemappedFile(RemappedFile.first, RemappedFile.second);
2265 OwnedBuffers.push_back(RemappedFile.second);
2266 }
2267
2268 // Use the code completion consumer we were given, but adding any cached
2269 // code-completion results.
2270 AugmentedCodeCompleteConsumer *AugmentedConsumer
2271 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
2272 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2273
2274 auto getUniqueID =
2275 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2276 if (auto Status = FileMgr.getVirtualFileSystem().status(Filename))
2277 return Status->getUniqueID();
2278 return std::nullopt;
2279 };
2280
2281 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2282 if (LHS == RHS)
2283 return true;
2284 if (auto LHSID = getUniqueID(LHS))
2285 if (auto RHSID = getUniqueID(RHS))
2286 return *LHSID == *RHSID;
2287 return false;
2288 };
2289
2290 // If we have a precompiled preamble, try to use it. We only allow
2291 // the use of the precompiled preamble if we're if the completion
2292 // point is within the main file, after the end of the precompiled
2293 // preamble.
2294 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2295 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
2296 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2297 PCHContainerOps, Inv, &FileMgr.getVirtualFileSystem(), false, Line - 1);
2298 }
2299
2300 // If the main file has been overridden due to the use of a preamble,
2301 // make that override happen and introduce the preamble.
2302 if (OverrideMainBuffer) {
2303 assert(Preamble &&
2304 "No preamble was built, but OverrideMainBuffer is not null");
2305
2307 &FileMgr.getVirtualFileSystem();
2308 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2309 OverrideMainBuffer.get());
2310 // FIXME: there is no way to update VFS if it was changed by
2311 // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
2312 // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
2313 // PCH files are always readable.
2314 OwnedBuffers.push_back(OverrideMainBuffer.release());
2315 } else {
2316 PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2317 PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2318 }
2319
2320 // Disable the preprocessing record if modules are not enabled.
2321 if (!Clang->getLangOpts().Modules)
2322 PreprocessorOpts.DetailedRecord = false;
2323
2324 if (!Act)
2325 Act.reset(new SyntaxOnlyAction);
2326
2327 if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
2328 if (llvm::Error Err = Act->Execute()) {
2329 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
2330 }
2331 Act->EndSourceFile();
2332 }
2333}
2334
2335bool ASTUnit::Save(StringRef File) {
2336 if (HadModuleLoaderFatalFailure)
2337 return true;
2338
2339 // FIXME: Can we somehow regenerate the stat cache here, or do we need to
2340 // unconditionally create a stat cache when we parse the file?
2341
2342 if (llvm::Error Err = llvm::writeToOutput(
2343 File, [this](llvm::raw_ostream &Out) {
2344 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2345 "ASTUnit serialization failed",
2346 llvm::inconvertibleErrorCode())
2347 : llvm::Error::success();
2348 })) {
2349 consumeError(std::move(Err));
2350 return true;
2351 }
2352 return false;
2353}
2354
2355static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,
2356 Sema &S, raw_ostream &OS) {
2357 Writer.WriteAST(S, std::string(), nullptr, "");
2358
2359 // Write the generated bitstream to "Out".
2360 if (!Buffer.empty())
2361 OS.write(Buffer.data(), Buffer.size());
2362
2363 return false;
2364}
2365
2366bool ASTUnit::serialize(raw_ostream &OS) {
2367 if (WriterData)
2368 return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS);
2369
2370 SmallString<128> Buffer;
2371 llvm::BitstreamWriter Stream(Buffer);
2372 InMemoryModuleCache ModuleCache;
2373 ASTWriter Writer(Stream, Buffer, ModuleCache, {});
2374 return serializeUnit(Writer, Buffer, getSema(), OS);
2375}
2376
2378
2379void ASTUnit::TranslateStoredDiagnostics(
2380 FileManager &FileMgr,
2381 SourceManager &SrcMgr,
2384 // Map the standalone diagnostic into the new source manager. We also need to
2385 // remap all the locations to the new view. This includes the diag location,
2386 // any associated source ranges, and the source ranges of associated fix-its.
2387 // FIXME: There should be a cleaner way to do this.
2389 Result.reserve(Diags.size());
2390
2391 for (const auto &SD : Diags) {
2392 // Rebuild the StoredDiagnostic.
2393 if (SD.Filename.empty())
2394 continue;
2395 auto FE = FileMgr.getFile(SD.Filename);
2396 if (!FE)
2397 continue;
2398 SourceLocation FileLoc;
2399 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2400 if (ItFileID == PreambleSrcLocCache.end()) {
2401 FileID FID = SrcMgr.translateFile(*FE);
2402 FileLoc = SrcMgr.getLocForStartOfFile(FID);
2403 PreambleSrcLocCache[SD.Filename] = FileLoc;
2404 } else {
2405 FileLoc = ItFileID->getValue();
2406 }
2407
2408 if (FileLoc.isInvalid())
2409 continue;
2410 SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
2411 FullSourceLoc Loc(L, SrcMgr);
2412
2414 Ranges.reserve(SD.Ranges.size());
2415 for (const auto &Range : SD.Ranges) {
2416 SourceLocation BL = FileLoc.getLocWithOffset(Range.first);
2417 SourceLocation EL = FileLoc.getLocWithOffset(Range.second);
2418 Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
2419 }
2420
2422 FixIts.reserve(SD.FixIts.size());
2423 for (const auto &FixIt : SD.FixIts) {
2424 FixIts.push_back(FixItHint());
2425 FixItHint &FH = FixIts.back();
2426 FH.CodeToInsert = FixIt.CodeToInsert;
2427 SourceLocation BL = FileLoc.getLocWithOffset(FixIt.RemoveRange.first);
2428 SourceLocation EL = FileLoc.getLocWithOffset(FixIt.RemoveRange.second);
2430 }
2431
2432 Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
2433 SD.Message, Loc, Ranges, FixIts));
2434 }
2435 Result.swap(Out);
2436}
2437
2439 assert(D);
2440
2441 // We only care about local declarations.
2442 if (D->isFromASTFile())
2443 return;
2444
2445 SourceManager &SM = *SourceMgr;
2446 SourceLocation Loc = D->getLocation();
2447 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2448 return;
2449
2450 // We only keep track of the file-level declarations of each file.
2452 return;
2453
2454 SourceLocation FileLoc = SM.getFileLoc(Loc);
2455 assert(SM.isLocalSourceLocation(FileLoc));
2456 FileID FID;
2457 unsigned Offset;
2458 std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
2459 if (FID.isInvalid())
2460 return;
2461
2462 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2463 if (!Decls)
2464 Decls = std::make_unique<LocDeclsTy>();
2465
2466 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2467
2468 if (Decls->empty() || Decls->back().first <= Offset) {
2469 Decls->push_back(LocDecl);
2470 return;
2471 }
2472
2473 LocDeclsTy::iterator I =
2474 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2475
2476 Decls->insert(I, LocDecl);
2477}
2478
2479void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2480 SmallVectorImpl<Decl *> &Decls) {
2481 if (File.isInvalid())
2482 return;
2483
2484 if (SourceMgr->isLoadedFileID(File)) {
2485 assert(Ctx->getExternalSource() && "No external source!");
2486 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2487 Decls);
2488 }
2489
2490 FileDeclsTy::iterator I = FileDecls.find(File);
2491 if (I == FileDecls.end())
2492 return;
2493
2494 LocDeclsTy &LocDecls = *I->second;
2495 if (LocDecls.empty())
2496 return;
2497
2498 LocDeclsTy::iterator BeginIt =
2499 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2500 return LD.first < Offset;
2501 });
2502 if (BeginIt != LocDecls.begin())
2503 --BeginIt;
2504
2505 // If we are pointing at a top-level decl inside an objc container, we need
2506 // to backtrack until we find it otherwise we will fail to report that the
2507 // region overlaps with an objc container.
2508 while (BeginIt != LocDecls.begin() &&
2509 BeginIt->second->isTopLevelDeclInObjCContainer())
2510 --BeginIt;
2511
2512 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2513 LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),
2514 llvm::less_first());
2515 if (EndIt != LocDecls.end())
2516 ++EndIt;
2517
2518 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2519 Decls.push_back(DIt->second);
2520}
2521
2523 unsigned Line, unsigned Col) const {
2525 SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);
2526 return SM.getMacroArgExpandedLocation(Loc);
2527}
2528
2530 unsigned Offset) const {
2532 SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);
2533 return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
2534}
2535
2536/// If \arg Loc is a loaded location from the preamble, returns
2537/// the corresponding local location of the main file, otherwise it returns
2538/// \arg Loc.
2540 FileID PreambleID;
2541 if (SourceMgr)
2542 PreambleID = SourceMgr->getPreambleFileID();
2543
2544 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2545 return Loc;
2546
2547 unsigned Offs;
2548 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2549 SourceLocation FileLoc
2550 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2551 return FileLoc.getLocWithOffset(Offs);
2552 }
2553
2554 return Loc;
2555}
2556
2557/// If \arg Loc is a local location of the main file but inside the
2558/// preamble chunk, returns the corresponding loaded location from the
2559/// preamble, otherwise it returns \arg Loc.
2561 FileID PreambleID;
2562 if (SourceMgr)
2563 PreambleID = SourceMgr->getPreambleFileID();
2564
2565 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2566 return Loc;
2567
2568 unsigned Offs;
2569 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2570 Offs < Preamble->getBounds().Size) {
2571 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2572 return FileLoc.getLocWithOffset(Offs);
2573 }
2574
2575 return Loc;
2576}
2577
2579 FileID FID;
2580 if (SourceMgr)
2581 FID = SourceMgr->getPreambleFileID();
2582
2583 if (Loc.isInvalid() || FID.isInvalid())
2584 return false;
2585
2586 return SourceMgr->isInFileID(Loc, FID);
2587}
2588
2590 FileID FID;
2591 if (SourceMgr)
2592 FID = SourceMgr->getMainFileID();
2593
2594 if (Loc.isInvalid() || FID.isInvalid())
2595 return false;
2596
2597 return SourceMgr->isInFileID(Loc, FID);
2598}
2599
2601 FileID FID;
2602 if (SourceMgr)
2603 FID = SourceMgr->getPreambleFileID();
2604
2605 if (FID.isInvalid())
2606 return {};
2607
2608 return SourceMgr->getLocForEndOfFile(FID);
2609}
2610
2612 FileID FID;
2613 if (SourceMgr)
2614 FID = SourceMgr->getMainFileID();
2615
2616 if (FID.isInvalid())
2617 return {};
2618
2619 return SourceMgr->getLocForStartOfFile(FID);
2620}
2621
2622llvm::iterator_range<PreprocessingRecord::iterator>
2624 if (isMainFileAST()) {
2626 Mod = Reader->getModuleManager().getPrimaryModule();
2627 return Reader->getModulePreprocessedEntities(Mod);
2628 }
2629
2631 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2632
2633 return llvm::make_range(PreprocessingRecord::iterator(),
2635}
2636
2638 if (isMainFileAST()) {
2640 Mod = Reader->getModuleManager().getPrimaryModule();
2641 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2642 if (!Fn(context, D))
2643 return false;
2644 }
2645
2646 return true;
2647 }
2648
2650 TLEnd = top_level_end();
2651 TL != TLEnd; ++TL) {
2652 if (!Fn(context, *TL))
2653 return false;
2654 }
2655
2656 return true;
2657}
2658
2660 if (!Reader)
2661 return std::nullopt;
2662
2663 serialization::ModuleFile *Mod = nullptr;
2664 Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
2665 switch (M.Kind) {
2666 case serialization::MK_ImplicitModule:
2667 case serialization::MK_ExplicitModule:
2668 case serialization::MK_PrebuiltModule:
2669 return true; // skip dependencies.
2670 case serialization::MK_PCH:
2671 Mod = &M;
2672 return true; // found it.
2673 case serialization::MK_Preamble:
2674 return false; // look in dependencies.
2675 case serialization::MK_MainFile:
2676 return false; // look in dependencies.
2677 }
2678
2679 return true;
2680 });
2681 if (Mod)
2682 return Mod->File;
2683
2684 return std::nullopt;
2685}
2686
2689}
2690
2692 auto &LangOpts = getLangOpts();
2693
2694 Language Lang;
2695 if (LangOpts.OpenCL)
2696 Lang = Language::OpenCL;
2697 else if (LangOpts.CUDA)
2698 Lang = Language::CUDA;
2699 else if (LangOpts.RenderScript)
2701 else if (LangOpts.CPlusPlus)
2702 Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
2703 else
2704 Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
2705
2707 if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
2709
2710 // We don't know if input was preprocessed. Assume not.
2711 bool PP = false;
2712
2713 return InputKind(Lang, Fmt, PP);
2714}
2715
2716#ifndef NDEBUG
2717ASTUnit::ConcurrencyState::ConcurrencyState() {
2718 Mutex = new std::recursive_mutex;
2719}
2720
2721ASTUnit::ConcurrencyState::~ConcurrencyState() {
2722 delete static_cast<std::recursive_mutex *>(Mutex);
2723}
2724
2725void ASTUnit::ConcurrencyState::start() {
2726 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
2727 assert(acquired && "Concurrent access to ASTUnit!");
2728}
2729
2730void ASTUnit::ConcurrencyState::finish() {
2731 static_cast<std::recursive_mutex *>(Mutex)->unlock();
2732}
2733
2734#else // NDEBUG
2735
2736ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
2737ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2738void ASTUnit::ConcurrencyState::start() {}
2739void ASTUnit::ConcurrencyState::finish() {}
2740
2741#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:2001
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:2355
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:2975
StringRef Filename
Definition: Format.cpp:2971
StringRef Identifier
Definition: Format.cpp:2979
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:143
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Definition: MachO.h:48
llvm::MachO::Record Record
Definition: MachO.h:31
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:2574
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:936
const LangOptions & getLangOpts() const
Definition: ASTContext.h:775
void setPrintingPolicy(const clang::PrintingPolicy &Policy)
Definition: ASTContext.h:701
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:1611
@ 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:2438
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:1757
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:2178
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:2366
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:1863
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:2522
void ResetForParse()
Free data that will be re-generated on the next parse.
Definition: ASTUnit.cpp:1921
InputKind getInputKind() const
Determine the input kind this AST unit represents.
Definition: ASTUnit.cpp:2691
OptionalFileEntryRef getPCHFile()
Get the PCH file if one was included.
Definition: ASTUnit.cpp:2659
StringRef getMainFileName() const
Definition: ASTUnit.cpp:1501
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:2560
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:2600
@ 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:2611
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:2637
llvm::iterator_range< PreprocessingRecord::iterator > getLocalPreprocessingEntities() const
Returns an iterator range for the local preprocessing entities of the local Preprocessor,...
Definition: ASTUnit.cpp:2623
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:1519
bool Save(StringRef File)
Save this translation unit to a file with the given name.
Definition: ASTUnit.cpp:2335
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:1529
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:1549
bool isInMainFileID(SourceLocation Loc) const
Definition: ASTUnit.cpp:2589
bool isModuleFile() const
Returns true if the ASTUnit was constructed from a serialized module file.
Definition: ASTUnit.cpp:2687
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:2479
const ASTContext & getASTContext() const
Definition: ASTUnit.h:442
bool isInPreambleFileID(SourceLocation Loc) const
Definition: ASTUnit.cpp:2578
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:2539
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:4714
LocalDeclID getDeclID(const Decl *D)
Determine the local declaration ID of an already-emitted declaration.
Definition: ASTWriter.cpp:6024
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:2137
bool isTranslationUnit() const
Definition: DeclBase.h:2142
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
Definition: DeclBase.cpp:1215
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
Definition: DeclBase.h:776
SourceLocation getLocation() const
Definition: DeclBase.h:445
@ IDNS_NonMemberOperator
This declaration is a C++ operator declared in a non-class context.
Definition: DeclBase.h:168
@ IDNS_Ordinary
Ordinary names.
Definition: DeclBase.h:144
@ IDNS_Type
Types, declared with 'struct foo', typedefs, etc.
Definition: DeclBase.h:130
@ IDNS_Member
Members, declared with object declarations within tag definitions.
Definition: DeclBase.h:136
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
Definition: DeclBase.h:140
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
Definition: DeclBase.h:125
DeclContext * getDeclContext()
Definition: DeclBase.h:454
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
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:251
FileSystemOptions & getFileSystemOpts()
Returns the current file system options.
Definition: FileManager.h:248
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
Definition: FileManager.h:253
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:261
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:253
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:102
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:461
CommentOptions CommentOpts
Options for parsing comments.
Definition: LangOptions.h:525
bool isCompilingModule() const
Are we compiling a module?
Definition: LangOptions.h:602
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:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7449
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1327
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:457
ASTContext & Context
Definition: Sema.h:858
const LangOptions & getLangOpts() const
Definition: Sema.h:520
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:2216
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)
@ 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....
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.
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.
@ 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)
TranslationUnitKind
Describes the kind of translation unit being processed.
Definition: LangOptions.h:1036
@ TU_Complete
The translation unit is a complete translation unit.
Definition: LangOptions.h:1038
SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T)
Determine the simplified type class of the given canonical type.
@ CCP_NestedNameSpecifier
Priority for a nested-name-specifier.
@ CCP_CodePattern
Priority for a code pattern.
const FunctionProtoType * T
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:848
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