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 StringRef 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(), *VFS);
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(),
1598
1599 // Create the compiler instance to use for building the AST.
1600 std::unique_ptr<CompilerInstance> Clang(
1601 new CompilerInstance(std::move(PCHContainerOps)));
1602
1603 // Recover resources if we crash before exiting this method.
1604 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1605 CICleanup(Clang.get());
1606
1607 Clang->setInvocation(std::move(CI));
1608 AST->OriginalSourceFile =
1609 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1610
1611 // Set up diagnostics, capturing any diagnostics that would
1612 // otherwise be dropped.
1613 Clang->setDiagnostics(&AST->getDiagnostics());
1614
1615 // Create the target instance.
1616 if (!Clang->createTarget())
1617 return nullptr;
1618
1619 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1620 "Invocation must have exactly one source file!");
1621 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1623 "FIXME: AST inputs not yet supported here!");
1624 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1626 "IR inputs not support here!");
1627
1628 // Configure the various subsystems.
1629 AST->TheSema.reset();
1630 AST->Ctx = nullptr;
1631 AST->PP = nullptr;
1632 AST->Reader = nullptr;
1633
1634 // Create a file manager object to provide access to and cache the filesystem.
1635 Clang->setFileManager(&AST->getFileManager());
1636
1637 // Create the source manager.
1638 Clang->setSourceManager(&AST->getSourceManager());
1639
1640 FrontendAction *Act = Action;
1641
1642 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1643 if (!Act) {
1644 TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
1645 Act = TrackerAct.get();
1646 }
1647
1648 // Recover resources if we crash before exiting this method.
1649 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1650 ActCleanup(TrackerAct.get());
1651
1652 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
1653 AST->transferASTDataFromCompilerInstance(*Clang);
1654 if (OwnAST && ErrAST)
1655 ErrAST->swap(OwnAST);
1656
1657 return nullptr;
1658 }
1659
1660 if (Persistent && !TrackerAct) {
1661 Clang->getPreprocessor().addPPCallbacks(
1662 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1664 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1665 if (Clang->hasASTConsumer())
1666 Consumers.push_back(Clang->takeASTConsumer());
1667 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1668 *AST, AST->getCurrentTopLevelHashValue()));
1669 Clang->setASTConsumer(
1670 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1671 }
1672 if (llvm::Error Err = Act->Execute()) {
1673 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1674 AST->transferASTDataFromCompilerInstance(*Clang);
1675 if (OwnAST && ErrAST)
1676 ErrAST->swap(OwnAST);
1677
1678 return nullptr;
1679 }
1680
1681 // Steal the created target, context, and preprocessor.
1682 AST->transferASTDataFromCompilerInstance(*Clang);
1683
1684 Act->EndSourceFile();
1685
1686 if (OwnAST)
1687 return OwnAST.release();
1688 else
1689 return AST;
1690}
1691
1692bool ASTUnit::LoadFromCompilerInvocation(
1693 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1694 unsigned PrecompilePreambleAfterNParses,
1696 if (!Invocation)
1697 return true;
1698
1699 assert(VFS && "VFS is null");
1700
1701 // We'll manage file buffers ourselves.
1702 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1703 Invocation->getFrontendOpts().DisableFree = false;
1705 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),
1706 *VFS);
1707
1708 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1709 if (PrecompilePreambleAfterNParses > 0) {
1710 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1711 OverrideMainBuffer =
1712 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1714 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),
1715 *VFS);
1716 }
1717
1718 SimpleTimer ParsingTimer(WantTiming);
1719 ParsingTimer.setOutput("Parsing " + getMainFileName());
1720
1721 // Recover resources if we crash before exiting this method.
1722 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1723 MemBufferCleanup(OverrideMainBuffer.get());
1724
1725 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1726}
1727
1728std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1729 std::shared_ptr<CompilerInvocation> CI,
1730 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1732 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1733 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1734 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1735 bool UserFilesAreVolatile) {
1736 // Create the AST unit.
1737 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1738 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1739 AST->Diagnostics = Diags;
1740 AST->OnlyLocalDecls = OnlyLocalDecls;
1741 AST->CaptureDiagnostics = CaptureDiagnostics;
1742 AST->TUKind = TUKind;
1743 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1744 AST->IncludeBriefCommentsInCodeCompletion
1745 = IncludeBriefCommentsInCodeCompletion;
1746 AST->Invocation = std::move(CI);
1747 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1748 AST->FileMgr = FileMgr;
1749 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1750
1751 // Recover resources if we crash before exiting this method.
1752 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1753 ASTUnitCleanup(AST.get());
1754 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1755 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1756 DiagCleanup(Diags.get());
1757
1758 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1759 PrecompilePreambleAfterNParses,
1760 &AST->FileMgr->getVirtualFileSystem()))
1761 return nullptr;
1762 return AST;
1763}
1764
1765std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
1766 const char **ArgBegin, const char **ArgEnd,
1767 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1768 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
1769 bool StorePreamblesInMemory, StringRef PreambleStoragePath,
1770 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1771 ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
1772 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1773 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1774 bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
1775 bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
1776 bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
1777 std::unique_ptr<ASTUnit> *ErrAST,
1779 assert(Diags.get() && "no DiagnosticsEngine was provided");
1780
1781 // If no VFS was provided, create one that tracks the physical file system.
1782 // If '-working-directory' was passed as an argument, 'createInvocation' will
1783 // set this as the current working directory of the VFS.
1784 if (!VFS)
1785 VFS = llvm::vfs::createPhysicalFileSystem();
1786
1787 SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
1788
1789 std::shared_ptr<CompilerInvocation> CI;
1790
1791 {
1792 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
1793 &StoredDiagnostics, nullptr);
1794
1796 CIOpts.VFS = VFS;
1797 CIOpts.Diags = Diags;
1798 CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
1799 CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));
1800 if (!CI)
1801 return nullptr;
1802 }
1803
1804 // Override any files that need remapping
1805 for (const auto &RemappedFile : RemappedFiles) {
1806 CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1807 RemappedFile.second);
1808 }
1809 PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
1810 PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
1811 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
1812 PPOpts.SingleFileParseMode = SingleFileParse;
1813 PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
1814
1815 // Override the resources path.
1816 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1817
1818 CI->getFrontendOpts().SkipFunctionBodies =
1820
1821 if (ModuleFormat)
1822 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
1823
1824 // Create the AST unit.
1825 std::unique_ptr<ASTUnit> AST;
1826 AST.reset(new ASTUnit(false));
1827 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1828 AST->StoredDiagnostics.swap(StoredDiagnostics);
1829 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1830 AST->Diagnostics = Diags;
1831 AST->FileSystemOpts = CI->getFileSystemOpts();
1832 VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
1833 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
1834 AST->StorePreamblesInMemory = StorePreamblesInMemory;
1835 AST->PreambleStoragePath = PreambleStoragePath;
1836 AST->ModuleCache = new InMemoryModuleCache;
1837 AST->OnlyLocalDecls = OnlyLocalDecls;
1838 AST->CaptureDiagnostics = CaptureDiagnostics;
1839 AST->TUKind = TUKind;
1840 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1841 AST->IncludeBriefCommentsInCodeCompletion
1842 = IncludeBriefCommentsInCodeCompletion;
1843 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1844 AST->Invocation = CI;
1845 AST->SkipFunctionBodies = SkipFunctionBodies;
1846 if (ForSerialization)
1847 AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));
1848 // Zero out now to ease cleanup during crash recovery.
1849 CI = nullptr;
1850 Diags = nullptr;
1851
1852 // Recover resources if we crash before exiting this method.
1853 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1854 ASTUnitCleanup(AST.get());
1855
1856 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1857 PrecompilePreambleAfterNParses,
1858 VFS)) {
1859 // Some error occurred, if caller wants to examine diagnostics, pass it the
1860 // ASTUnit.
1861 if (ErrAST) {
1862 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1863 ErrAST->swap(AST);
1864 }
1865 return nullptr;
1866 }
1867
1868 return AST;
1869}
1870
1871bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1872 ArrayRef<RemappedFile> RemappedFiles,
1874 if (!Invocation)
1875 return true;
1876
1877 if (!VFS) {
1878 assert(FileMgr && "FileMgr is null on Reparse call");
1879 VFS = &FileMgr->getVirtualFileSystem();
1880 }
1881
1882 clearFileLevelDecls();
1883
1884 SimpleTimer ParsingTimer(WantTiming);
1885 ParsingTimer.setOutput("Reparsing " + getMainFileName());
1886
1887 // Remap files.
1888 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1889 for (const auto &RB : PPOpts.RemappedFileBuffers)
1890 delete RB.second;
1891
1892 Invocation->getPreprocessorOpts().clearRemappedFiles();
1893 for (const auto &RemappedFile : RemappedFiles) {
1894 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1895 RemappedFile.second);
1896 }
1897
1898 // If we have a preamble file lying around, or if we might try to
1899 // build a precompiled preamble, do so now.
1900 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1901 if (Preamble || PreambleRebuildCountdown > 0)
1902 OverrideMainBuffer =
1903 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1904
1905 // Clear out the diagnostics state.
1906 FileMgr.reset();
1908 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),
1909 *VFS);
1910 if (OverrideMainBuffer)
1911 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1912
1913 // Parse the sources
1914 bool Result =
1915 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1916
1917 // If we're caching global code-completion results, and the top-level
1918 // declarations have changed, clear out the code-completion cache.
1919 if (!Result && ShouldCacheCodeCompletionResults &&
1920 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1921 CacheCodeCompletionResults();
1922
1923 // We now need to clear out the completion info related to this translation
1924 // unit; it'll be recreated if necessary.
1925 CCTUInfo.reset();
1926
1927 return Result;
1928}
1929
1931 SavedMainFileBuffer.reset();
1932
1933 SourceMgr.reset();
1934 TheSema.reset();
1935 Ctx.reset();
1936 PP.reset();
1937 Reader.reset();
1938
1939 TopLevelDecls.clear();
1940 clearFileLevelDecls();
1941}
1942
1943//----------------------------------------------------------------------------//
1944// Code completion
1945//----------------------------------------------------------------------------//
1946
1947namespace {
1948
1949 /// Code completion consumer that combines the cached code-completion
1950 /// results from an ASTUnit with the code-completion results provided to it,
1951 /// then passes the result on to
1952 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
1953 uint64_t NormalContexts;
1954 ASTUnit &AST;
1956
1957 public:
1958 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
1959 const CodeCompleteOptions &CodeCompleteOpts)
1960 : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
1961 // Compute the set of contexts in which we will look when we don't have
1962 // any information about the specific context.
1963 NormalContexts
1977
1978 if (AST.getASTContext().getLangOpts().CPlusPlus)
1979 NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
1982 }
1983
1984 void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
1985 CodeCompletionResult *Results,
1986 unsigned NumResults) override;
1987
1988 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1989 OverloadCandidate *Candidates,
1990 unsigned NumCandidates,
1991 SourceLocation OpenParLoc,
1992 bool Braced) override {
1993 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
1994 OpenParLoc, Braced);
1995 }
1996
1997 CodeCompletionAllocator &getAllocator() override {
1998 return Next.getAllocator();
1999 }
2000
2001 CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
2002 return Next.getCodeCompletionTUInfo();
2003 }
2004 };
2005
2006} // namespace
2007
2008/// Helper function that computes which global names are hidden by the
2009/// local code-completion results.
2011 CodeCompletionResult *Results,
2012 unsigned NumResults,
2013 ASTContext &Ctx,
2014 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
2015 bool OnlyTagNames = false;
2016 switch (Context.getKind()) {
2036 break;
2037
2041 OnlyTagNames = true;
2042 break;
2043
2061 // We're looking for nothing, or we're looking for names that cannot
2062 // be hidden.
2063 return;
2064 }
2065
2067 for (unsigned I = 0; I != NumResults; ++I) {
2068 if (Results[I].Kind != Result::RK_Declaration)
2069 continue;
2070
2071 unsigned IDNS
2072 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
2073
2074 bool Hiding = false;
2075 if (OnlyTagNames)
2076 Hiding = (IDNS & Decl::IDNS_Tag);
2077 else {
2078 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
2081 if (Ctx.getLangOpts().CPlusPlus)
2082 HiddenIDNS |= Decl::IDNS_Tag;
2083 Hiding = (IDNS & HiddenIDNS);
2084 }
2085
2086 if (!Hiding)
2087 continue;
2088
2089 DeclarationName Name = Results[I].Declaration->getDeclName();
2090 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
2091 HiddenNames.insert(Identifier->getName());
2092 else
2093 HiddenNames.insert(Name.getAsString());
2094 }
2095}
2096
2097void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
2098 CodeCompletionContext Context,
2099 CodeCompletionResult *Results,
2100 unsigned NumResults) {
2101 // Merge the results we were given with the results we cached.
2102 bool AddedResult = false;
2103 uint64_t InContexts =
2104 Context.getKind() == CodeCompletionContext::CCC_Recovery
2105 ? NormalContexts : (1LL << Context.getKind());
2106 // Contains the set of names that are hidden by "local" completion results.
2107 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2109 SmallVector<Result, 8> AllResults;
2111 C = AST.cached_completion_begin(),
2112 CEnd = AST.cached_completion_end();
2113 C != CEnd; ++C) {
2114 // If the context we are in matches any of the contexts we are
2115 // interested in, we'll add this result.
2116 if ((C->ShowInContexts & InContexts) == 0)
2117 continue;
2118
2119 // If we haven't added any results previously, do so now.
2120 if (!AddedResult) {
2121 CalculateHiddenNames(Context, Results, NumResults, S.Context,
2122 HiddenNames);
2123 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2124 AddedResult = true;
2125 }
2126
2127 // Determine whether this global completion result is hidden by a local
2128 // completion result. If so, skip it.
2129 if (C->Kind != CXCursor_MacroDefinition &&
2130 HiddenNames.count(C->Completion->getTypedText()))
2131 continue;
2132
2133 // Adjust priority based on similar type classes.
2134 unsigned Priority = C->Priority;
2135 CodeCompletionString *Completion = C->Completion;
2136 if (!Context.getPreferredType().isNull()) {
2137 if (C->Kind == CXCursor_MacroDefinition) {
2138 Priority = getMacroUsagePriority(C->Completion->getTypedText(),
2139 S.getLangOpts(),
2140 Context.getPreferredType()->isAnyPointerType());
2141 } else if (C->Type) {
2144 Context.getPreferredType().getUnqualifiedType());
2146 if (ExpectedSTC == C->TypeClass) {
2147 // We know this type is similar; check for an exact match.
2148 llvm::StringMap<unsigned> &CachedCompletionTypes
2150 llvm::StringMap<unsigned>::iterator Pos
2151 = CachedCompletionTypes.find(QualType(Expected).getAsString());
2152 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
2154 else
2156 }
2157 }
2158 }
2159
2160 // Adjust the completion string, if required.
2161 if (C->Kind == CXCursor_MacroDefinition &&
2162 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
2163 // Create a new code-completion string that just contains the
2164 // macro name, without its arguments.
2165 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
2166 CCP_CodePattern, C->Availability);
2167 Builder.AddTypedTextChunk(C->Completion->getTypedText());
2169 Completion = Builder.TakeString();
2170 }
2171
2172 AllResults.push_back(Result(Completion, Priority, C->Kind,
2173 C->Availability));
2174 }
2175
2176 // If we did not add any cached completion results, just forward the
2177 // results we were given to the next consumer.
2178 if (!AddedResult) {
2179 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2180 return;
2181 }
2182
2183 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2184 AllResults.size());
2185}
2186
2188 StringRef File, unsigned Line, unsigned Column,
2189 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
2190 bool IncludeCodePatterns, bool IncludeBriefComments,
2191 CodeCompleteConsumer &Consumer,
2192 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2193 DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr,
2194 FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
2196 std::unique_ptr<SyntaxOnlyAction> Act) {
2197 if (!Invocation)
2198 return;
2199
2200 SimpleTimer CompletionTimer(WantTiming);
2201 CompletionTimer.setOutput("Code completion @ " + File + ":" +
2202 Twine(Line) + ":" + Twine(Column));
2203
2204 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2205
2206 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2207 CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
2208 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2209
2210 CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2211 CachedCompletionResults.empty();
2212 CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2213 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2214 CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2215 CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
2216 CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
2217
2218 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2219
2220 FrontendOpts.CodeCompletionAt.FileName = std::string(File);
2221 FrontendOpts.CodeCompletionAt.Line = Line;
2222 FrontendOpts.CodeCompletionAt.Column = Column;
2223
2224 // Set the language options appropriately.
2225 LangOpts = CCInvocation->getLangOpts();
2226
2227 // Spell-checking and warnings are wasteful during code-completion.
2228 LangOpts.SpellChecking = false;
2229 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
2230
2231 std::unique_ptr<CompilerInstance> Clang(
2232 new CompilerInstance(PCHContainerOps));
2233
2234 // Recover resources if we crash before exiting this method.
2235 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2236 CICleanup(Clang.get());
2237
2238 auto &Inv = *CCInvocation;
2239 Clang->setInvocation(std::move(CCInvocation));
2240 OriginalSourceFile =
2241 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2242
2243 // Set up diagnostics, capturing any diagnostics produced.
2244 Clang->setDiagnostics(&Diag);
2245 CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
2246 Clang->getDiagnostics(),
2247 &StoredDiagnostics, nullptr);
2248 ProcessWarningOptions(Diag, Inv.getDiagnosticOpts(),
2249 FileMgr.getVirtualFileSystem());
2250
2251 // Create the target instance.
2252 if (!Clang->createTarget()) {
2253 Clang->setInvocation(nullptr);
2254 return;
2255 }
2256
2257 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2258 "Invocation must have exactly one source file!");
2259 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2261 "FIXME: AST inputs not yet supported here!");
2262 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2264 "IR inputs not support here!");
2265
2266 // Use the source and file managers that we were given.
2267 Clang->setFileManager(&FileMgr);
2268 Clang->setSourceManager(&SourceMgr);
2269
2270 // Remap files.
2271 PreprocessorOpts.clearRemappedFiles();
2272 PreprocessorOpts.RetainRemappedFileBuffers = true;
2273 for (const auto &RemappedFile : RemappedFiles) {
2274 PreprocessorOpts.addRemappedFile(RemappedFile.first, RemappedFile.second);
2275 OwnedBuffers.push_back(RemappedFile.second);
2276 }
2277
2278 // Use the code completion consumer we were given, but adding any cached
2279 // code-completion results.
2280 AugmentedCodeCompleteConsumer *AugmentedConsumer
2281 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
2282 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2283
2284 auto getUniqueID =
2285 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2286 if (auto Status = FileMgr.getVirtualFileSystem().status(Filename))
2287 return Status->getUniqueID();
2288 return std::nullopt;
2289 };
2290
2291 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2292 if (LHS == RHS)
2293 return true;
2294 if (auto LHSID = getUniqueID(LHS))
2295 if (auto RHSID = getUniqueID(RHS))
2296 return *LHSID == *RHSID;
2297 return false;
2298 };
2299
2300 // If we have a precompiled preamble, try to use it. We only allow
2301 // the use of the precompiled preamble if we're if the completion
2302 // point is within the main file, after the end of the precompiled
2303 // preamble.
2304 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2305 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
2306 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2307 PCHContainerOps, Inv, &FileMgr.getVirtualFileSystem(), false, Line - 1);
2308 }
2309
2310 // If the main file has been overridden due to the use of a preamble,
2311 // make that override happen and introduce the preamble.
2312 if (OverrideMainBuffer) {
2313 assert(Preamble &&
2314 "No preamble was built, but OverrideMainBuffer is not null");
2315
2317 &FileMgr.getVirtualFileSystem();
2318 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2319 OverrideMainBuffer.get());
2320 // FIXME: there is no way to update VFS if it was changed by
2321 // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
2322 // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
2323 // PCH files are always readable.
2324 OwnedBuffers.push_back(OverrideMainBuffer.release());
2325 } else {
2326 PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2327 PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2328 }
2329
2330 // Disable the preprocessing record if modules are not enabled.
2331 if (!Clang->getLangOpts().Modules)
2332 PreprocessorOpts.DetailedRecord = false;
2333
2334 if (!Act)
2335 Act.reset(new SyntaxOnlyAction);
2336
2337 if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
2338 if (llvm::Error Err = Act->Execute()) {
2339 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
2340 }
2341 Act->EndSourceFile();
2342 }
2343}
2344
2345bool ASTUnit::Save(StringRef File) {
2346 if (HadModuleLoaderFatalFailure)
2347 return true;
2348
2349 // FIXME: Can we somehow regenerate the stat cache here, or do we need to
2350 // unconditionally create a stat cache when we parse the file?
2351
2352 if (llvm::Error Err = llvm::writeToOutput(
2353 File, [this](llvm::raw_ostream &Out) {
2354 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2355 "ASTUnit serialization failed",
2356 llvm::inconvertibleErrorCode())
2357 : llvm::Error::success();
2358 })) {
2359 consumeError(std::move(Err));
2360 return true;
2361 }
2362 return false;
2363}
2364
2365static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,
2366 Sema &S, raw_ostream &OS) {
2367 Writer.WriteAST(&S, std::string(), nullptr, "");
2368
2369 // Write the generated bitstream to "Out".
2370 if (!Buffer.empty())
2371 OS.write(Buffer.data(), Buffer.size());
2372
2373 return false;
2374}
2375
2376bool ASTUnit::serialize(raw_ostream &OS) {
2377 if (WriterData)
2378 return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS);
2379
2380 SmallString<128> Buffer;
2381 llvm::BitstreamWriter Stream(Buffer);
2382 InMemoryModuleCache ModuleCache;
2383 ASTWriter Writer(Stream, Buffer, ModuleCache, {});
2384 return serializeUnit(Writer, Buffer, getSema(), OS);
2385}
2386
2387void ASTUnit::TranslateStoredDiagnostics(
2388 FileManager &FileMgr,
2389 SourceManager &SrcMgr,
2392 // Map the standalone diagnostic into the new source manager. We also need to
2393 // remap all the locations to the new view. This includes the diag location,
2394 // any associated source ranges, and the source ranges of associated fix-its.
2395 // FIXME: There should be a cleaner way to do this.
2397 Result.reserve(Diags.size());
2398
2399 for (const auto &SD : Diags) {
2400 // Rebuild the StoredDiagnostic.
2401 if (SD.Filename.empty())
2402 continue;
2403 auto FE = FileMgr.getOptionalFileRef(SD.Filename);
2404 if (!FE)
2405 continue;
2406 SourceLocation FileLoc;
2407 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2408 if (ItFileID == PreambleSrcLocCache.end()) {
2409 FileID FID = SrcMgr.translateFile(*FE);
2410 FileLoc = SrcMgr.getLocForStartOfFile(FID);
2411 PreambleSrcLocCache[SD.Filename] = FileLoc;
2412 } else {
2413 FileLoc = ItFileID->getValue();
2414 }
2415
2416 if (FileLoc.isInvalid())
2417 continue;
2418 SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
2419 FullSourceLoc Loc(L, SrcMgr);
2420
2422 Ranges.reserve(SD.Ranges.size());
2423 for (const auto &Range : SD.Ranges) {
2424 SourceLocation BL = FileLoc.getLocWithOffset(Range.first);
2425 SourceLocation EL = FileLoc.getLocWithOffset(Range.second);
2426 Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
2427 }
2428
2430 FixIts.reserve(SD.FixIts.size());
2431 for (const auto &FixIt : SD.FixIts) {
2432 FixIts.push_back(FixItHint());
2433 FixItHint &FH = FixIts.back();
2434 FH.CodeToInsert = FixIt.CodeToInsert;
2435 SourceLocation BL = FileLoc.getLocWithOffset(FixIt.RemoveRange.first);
2436 SourceLocation EL = FileLoc.getLocWithOffset(FixIt.RemoveRange.second);
2438 }
2439
2440 Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
2441 SD.Message, Loc, Ranges, FixIts));
2442 }
2443 Result.swap(Out);
2444}
2445
2447 assert(D);
2448
2449 // We only care about local declarations.
2450 if (D->isFromASTFile())
2451 return;
2452
2453 SourceManager &SM = *SourceMgr;
2455 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2456 return;
2457
2458 // We only keep track of the file-level declarations of each file.
2460 return;
2461
2462 SourceLocation FileLoc = SM.getFileLoc(Loc);
2463 assert(SM.isLocalSourceLocation(FileLoc));
2464 FileID FID;
2465 unsigned Offset;
2466 std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
2467 if (FID.isInvalid())
2468 return;
2469
2470 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2471 if (!Decls)
2472 Decls = std::make_unique<LocDeclsTy>();
2473
2474 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2475
2476 if (Decls->empty() || Decls->back().first <= Offset) {
2477 Decls->push_back(LocDecl);
2478 return;
2479 }
2480
2481 LocDeclsTy::iterator I =
2482 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2483
2484 Decls->insert(I, LocDecl);
2485}
2486
2487void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2488 SmallVectorImpl<Decl *> &Decls) {
2489 if (File.isInvalid())
2490 return;
2491
2492 if (SourceMgr->isLoadedFileID(File)) {
2493 assert(Ctx->getExternalSource() && "No external source!");
2494 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2495 Decls);
2496 }
2497
2498 FileDeclsTy::iterator I = FileDecls.find(File);
2499 if (I == FileDecls.end())
2500 return;
2501
2502 LocDeclsTy &LocDecls = *I->second;
2503 if (LocDecls.empty())
2504 return;
2505
2506 LocDeclsTy::iterator BeginIt =
2507 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2508 return LD.first < Offset;
2509 });
2510 if (BeginIt != LocDecls.begin())
2511 --BeginIt;
2512
2513 // If we are pointing at a top-level decl inside an objc container, we need
2514 // to backtrack until we find it otherwise we will fail to report that the
2515 // region overlaps with an objc container.
2516 while (BeginIt != LocDecls.begin() &&
2517 BeginIt->second->isTopLevelDeclInObjCContainer())
2518 --BeginIt;
2519
2520 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2521 LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),
2522 llvm::less_first());
2523 if (EndIt != LocDecls.end())
2524 ++EndIt;
2525
2526 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2527 Decls.push_back(DIt->second);
2528}
2529
2531 unsigned Line, unsigned Col) const {
2533 SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);
2534 return SM.getMacroArgExpandedLocation(Loc);
2535}
2536
2538 unsigned Offset) const {
2540 SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);
2541 return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
2542}
2543
2544/// If \arg Loc is a loaded location from the preamble, returns
2545/// the corresponding local location of the main file, otherwise it returns
2546/// \arg Loc.
2548 FileID PreambleID;
2549 if (SourceMgr)
2550 PreambleID = SourceMgr->getPreambleFileID();
2551
2552 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2553 return Loc;
2554
2555 unsigned Offs;
2556 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2557 SourceLocation FileLoc
2558 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2559 return FileLoc.getLocWithOffset(Offs);
2560 }
2561
2562 return Loc;
2563}
2564
2565/// If \arg Loc is a local location of the main file but inside the
2566/// preamble chunk, returns the corresponding loaded location from the
2567/// preamble, otherwise it returns \arg Loc.
2569 FileID PreambleID;
2570 if (SourceMgr)
2571 PreambleID = SourceMgr->getPreambleFileID();
2572
2573 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2574 return Loc;
2575
2576 unsigned Offs;
2577 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2578 Offs < Preamble->getBounds().Size) {
2579 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2580 return FileLoc.getLocWithOffset(Offs);
2581 }
2582
2583 return Loc;
2584}
2585
2587 FileID FID;
2588 if (SourceMgr)
2589 FID = SourceMgr->getPreambleFileID();
2590
2591 if (Loc.isInvalid() || FID.isInvalid())
2592 return false;
2593
2594 return SourceMgr->isInFileID(Loc, FID);
2595}
2596
2598 FileID FID;
2599 if (SourceMgr)
2600 FID = SourceMgr->getMainFileID();
2601
2602 if (Loc.isInvalid() || FID.isInvalid())
2603 return false;
2604
2605 return SourceMgr->isInFileID(Loc, FID);
2606}
2607
2609 FileID FID;
2610 if (SourceMgr)
2611 FID = SourceMgr->getPreambleFileID();
2612
2613 if (FID.isInvalid())
2614 return {};
2615
2616 return SourceMgr->getLocForEndOfFile(FID);
2617}
2618
2620 FileID FID;
2621 if (SourceMgr)
2622 FID = SourceMgr->getMainFileID();
2623
2624 if (FID.isInvalid())
2625 return {};
2626
2627 return SourceMgr->getLocForStartOfFile(FID);
2628}
2629
2630llvm::iterator_range<PreprocessingRecord::iterator>
2632 if (isMainFileAST()) {
2634 Mod = Reader->getModuleManager().getPrimaryModule();
2635 return Reader->getModulePreprocessedEntities(Mod);
2636 }
2637
2639 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2640
2641 return llvm::make_range(PreprocessingRecord::iterator(),
2643}
2644
2646 if (isMainFileAST()) {
2648 Mod = Reader->getModuleManager().getPrimaryModule();
2649 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2650 if (!Fn(context, D))
2651 return false;
2652 }
2653
2654 return true;
2655 }
2656
2658 TLEnd = top_level_end();
2659 TL != TLEnd; ++TL) {
2660 if (!Fn(context, *TL))
2661 return false;
2662 }
2663
2664 return true;
2665}
2666
2668 if (!Reader)
2669 return std::nullopt;
2670
2671 serialization::ModuleFile *Mod = nullptr;
2672 Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
2673 switch (M.Kind) {
2674 case serialization::MK_ImplicitModule:
2675 case serialization::MK_ExplicitModule:
2676 case serialization::MK_PrebuiltModule:
2677 return true; // skip dependencies.
2678 case serialization::MK_PCH:
2679 Mod = &M;
2680 return true; // found it.
2681 case serialization::MK_Preamble:
2682 return false; // look in dependencies.
2683 case serialization::MK_MainFile:
2684 return false; // look in dependencies.
2685 }
2686
2687 return true;
2688 });
2689 if (Mod)
2690 return Mod->File;
2691
2692 return std::nullopt;
2693}
2694
2697}
2698
2700 auto &LangOpts = getLangOpts();
2701
2702 Language Lang;
2703 if (LangOpts.OpenCL)
2704 Lang = Language::OpenCL;
2705 else if (LangOpts.CUDA)
2706 Lang = Language::CUDA;
2707 else if (LangOpts.CPlusPlus)
2708 Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
2709 else
2710 Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
2711
2713 if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
2715
2716 // We don't know if input was preprocessed. Assume not.
2717 bool PP = false;
2718
2719 return InputKind(Lang, Fmt, PP);
2720}
2721
2722#ifndef NDEBUG
2723ASTUnit::ConcurrencyState::ConcurrencyState() {
2724 Mutex = new std::recursive_mutex;
2725}
2726
2727ASTUnit::ConcurrencyState::~ConcurrencyState() {
2728 delete static_cast<std::recursive_mutex *>(Mutex);
2729}
2730
2731void ASTUnit::ConcurrencyState::start() {
2732 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
2733 assert(acquired && "Concurrent access to ASTUnit!");
2734}
2735
2736void ASTUnit::ConcurrencyState::finish() {
2737 static_cast<std::recursive_mutex *>(Mutex)->unlock();
2738}
2739
2740#else // NDEBUG
2741
2742ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
2743ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2744void ASTUnit::ConcurrencyState::start() {}
2745void ASTUnit::ConcurrencyState::finish() {}
2746
2747#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:2010
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:2365
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:84
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:3036
StringRef Filename
Definition: Format.cpp:3032
StringRef Identifier
Definition: Format.cpp:3040
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:144
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:188
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:2716
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:998
const LangOptions & getLangOpts() const
Definition: ASTContext.h:834
void setPrintingPolicy(const clang::PrintingPolicy &Policy)
Definition: ASTContext.h:737
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:116
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:383
@ ARR_None
The client can't handle any AST loading failures.
Definition: ASTReader.h:1728
@ Success
The control block was read successfully.
Definition: ASTReader.h:406
@ ConfigurationMismatch
The AST file was written with a different language/target configuration.
Definition: ASTReader.h:423
@ OutOfDate
The AST file is out-of-date relative to its input files, and needs to be regenerated.
Definition: ASTReader.h:416
@ Failure
The AST file itself appears corrupted.
Definition: ASTReader.h:409
@ VersionMismatch
The AST file was written by a different version of Clang.
Definition: ASTReader.h:419
@ HadErrors
The AST file has errors.
Definition: ASTReader.h:426
@ Missing
The AST file was missing.
Definition: ASTReader.h:412
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:2446
const FileManager & getFileManager() const
Definition: ASTUnit.h:479
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:2187
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:2376
ASTDeserializationListener * getDeserializationListener()
Definition: ASTUnit.cpp:776
bool Reparse(std::shared_ptr< PCHContainerOperations > PCHContainerOps, ArrayRef< RemappedFile > RemappedFiles={}, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Reparse the source files using the same command-line options that were originally used to produce thi...
Definition: ASTUnit.cpp:1871
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:2530
void ResetForParse()
Free data that will be re-generated on the next parse.
Definition: ASTUnit.cpp:1930
InputKind getInputKind() const
Determine the input kind this AST unit represents.
Definition: ASTUnit.cpp:2699
OptionalFileEntryRef getPCHFile()
Get the PCH file if one was included.
Definition: ASTUnit.cpp:2667
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:2568
cached_completion_iterator cached_completion_begin()
Definition: ASTUnit.h:619
const LangOptions & getLangOpts() const
Definition: ASTUnit.h:464
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={}, 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:1765
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:2608
@ 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:2619
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:2645
llvm::iterator_range< PreprocessingRecord::iterator > getLocalPreprocessingEntities() const
Returns an iterator range for the local preprocessing entities of the local Preprocessor,...
Definition: ASTUnit.cpp:2631
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
static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef 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
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:2345
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:2597
bool isModuleFile() const
Returns true if the ASTUnit was constructed from a serialized module file.
Definition: ASTUnit.cpp:2695
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:2487
const ASTContext & getASTContext() const
Definition: ASTUnit.h:442
bool isInPreambleFileID(SourceLocation Loc) const
Definition: ASTUnit.cpp:2586
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:2547
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
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:89
LocalDeclID getDeclID(const Decl *D)
Determine the local declaration ID of an already-emitted declaration.
Definition: ASTWriter.cpp:6593
ASTFileSignature WriteAST(llvm::PointerUnion< Sema *, Preprocessor * > Subject, StringRef OutputFile, Module *WritingModule, StringRef isysroot, bool ShouldCacheASTInMemory=false)
Write a precompiled header or a module with the AST produced by the Sema object, or a dependency scan...
Definition: ASTWriter.cpp:5106
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:1435
bool isFileContext() const
Definition: DeclBase.h:2160
bool isTranslationUnit() const
Definition: DeclBase.h:2165
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
Definition: DeclBase.cpp:1285
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:786
bool isInvalidDecl() const
Definition: DeclBase.h:591
SourceLocation getLocation() const
Definition: DeclBase.h:442
@ 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:451
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:907
The name of a declaration.
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Definition: Diagnostic.h:1684
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
Definition: Diagnostic.h:1716
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:711
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:1708
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
Definition: Diagnostic.h:1512
SourceManager & getSourceManager() const
Definition: Diagnostic.h:1530
bool hasSourceManager() const
Definition: Diagnostic.h:1529
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:231
void setNumWarnings(unsigned NumWarnings)
Definition: Diagnostic.h:883
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
Definition: Diagnostic.cpp:105
std::unique_ptr< DiagnosticConsumer > takeClient()
Return the current diagnostic client along with ownership of that client.
Definition: Diagnostic.h:603
Level
The level of the diagnostic, after it has been through mapping.
Definition: Diagnostic.h:234
DiagnosticConsumer * getClient()
Definition: Diagnostic.h:595
unsigned getNumWarnings() const
Definition: Diagnostic.h:881
void Reset(bool soft=false)
Reset the state of the diagnostic object to its initial configuration.
Definition: Diagnostic.cpp:127
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:305
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:256
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
Definition: FileManager.h:245
FileSystemOptions & getFileSystemOpts()
Returns the current file system options.
Definition: FileManager.h:253
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
Definition: FileManager.h:258
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Definition: FileManager.h:266
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:75
bool BeforePreviousInsertions
Definition: Diagnostic.h:89
CharSourceRange RemoveRange
Code that should be replaced to correct the error.
Definition: Diagnostic.h:79
CharSourceRange InsertFromRange
Code in the specific range that should be inserted in the insertion location.
Definition: Diagnostic.h:83
std::string CodeToInsert
The actual code to insert at the insertion location, as a string.
Definition: Diagnostic.h:87
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:237
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:104
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
CommentOptions CommentOpts
Options for parsing comments.
Definition: LangOptions.h:563
bool isCompilingModule() const
Are we compiling a module?
Definition: LangOptions.h:649
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:954
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:115
bool isNamedModule() const
Does this Module is a named module of a standard named module?
Definition: Module.h:195
This represents a decl that may have a name.
Definition: Decl.h:253
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:466
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:138
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:929
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:996
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:8025
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1327
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:463
ASTContext & Context
Definition: Sema.h:908
const LangOptions & getLangOpts() const
Definition: Sema.h:524
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:1634
unsigned getID() const
Definition: Diagnostic.h:1655
ArrayRef< FixItHint > getFixIts() const
Definition: Diagnostic.h:1676
ArrayRef< CharSourceRange > getRanges() const
Definition: Diagnostic.h:1668
DiagnosticsEngine::Level getLevel() const
Definition: Diagnostic.h:1656
const FullSourceLoc & getLocation() const
Definition: Diagnostic.h:1657
StringRef getMessage() const
Definition: Diagnostic.h:1658
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
Definition: Targets.cpp:767
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:130
FileEntryRef File
The file entry for the module file.
Definition: ModuleFile.h:185
std::string FileName
The file name of the module file.
Definition: ModuleFile.h:145
ModuleKind Kind
The type of this module.
Definition: ModuleFile.h:142
@ CXCursor_MacroDefinition
Definition: Index.h:2264
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:57
@ 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.
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....
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, llvm::vfs::FileSystem &VFS, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
Definition: Warnings.cpp:46
TranslationUnitKind
Describes the kind of translation unit being processed.
Definition: LangOptions.h:1096
@ TU_Complete
The translation unit is a complete translation unit.
Definition: LangOptions.h:1098
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