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