clang 19.0.0git
ASTUnit.cpp
Go to the documentation of this file.
1//===- ASTUnit.cpp - ASTUnit utility --------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// ASTUnit Implementation.
10//
11//===----------------------------------------------------------------------===//
12
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclBase.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclGroup.h"
21#include "clang/AST/DeclObjC.h"
26#include "clang/AST/Type.h"
31#include "clang/Basic/LLVM.h"
34#include "clang/Basic/Module.h"
50#include "clang/Lex/Lexer.h"
55#include "clang/Lex/Token.h"
58#include "clang/Sema/Sema.h"
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, bool Complain,
540 bool AllowCompatibleDifferences) override {
541 if (InitializedLanguage)
542 return false;
543
544 // FIXME: We did similar things in ReadHeaderSearchOptions too. But such
545 // style is not scaling. Probably we need to invite some mechanism to
546 // handle such patterns generally.
547 auto PICLevel = LangOpt.PICLevel;
548 auto PIE = LangOpt.PIE;
549
550 LangOpt = LangOpts;
551
552 LangOpt.PICLevel = PICLevel;
553 LangOpt.PIE = PIE;
554
555 InitializedLanguage = true;
556
557 updated();
558 return false;
559 }
560
561 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
562 StringRef SpecificModuleCachePath,
563 bool Complain) override {
564 // llvm::SaveAndRestore doesn't support bit field.
565 auto ForceCheckCXX20ModulesInputFiles =
567 llvm::SaveAndRestore X(this->HSOpts.UserEntries);
570
571 this->HSOpts = HSOpts;
573 ForceCheckCXX20ModulesInputFiles;
574
575 return false;
576 }
577
578 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
579 bool Complain) override {
580 if (InitializedHeaderSearchPaths)
581 return false;
582
583 this->HSOpts.UserEntries = HSOpts.UserEntries;
584 this->HSOpts.SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;
585 this->HSOpts.VFSOverlayFiles = HSOpts.VFSOverlayFiles;
586
587 // Initialize the FileManager. We can't do this in update(), since that
588 // performs the initialization too late (once both target and language
589 // options are read).
591 HSOpts.VFSOverlayFiles, PP.getDiagnostics(),
593
594 InitializedHeaderSearchPaths = true;
595
596 return false;
597 }
598
599 bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
600 bool ReadMacros, bool Complain,
601 std::string &SuggestedPredefines) override {
602 this->PPOpts = PPOpts;
603 return false;
604 }
605
606 bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
607 bool AllowCompatibleDifferences) override {
608 // If we've already initialized the target, don't do it again.
609 if (Target)
610 return false;
611
612 this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
613 Target =
614 TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
615
616 updated();
617 return false;
618 }
619
620 void ReadCounter(const serialization::ModuleFile &M,
621 unsigned Value) override {
622 Counter = Value;
623 }
624
625private:
626 void updated() {
627 if (!Target || !InitializedLanguage)
628 return;
629
630 // Inform the target of the language options.
631 //
632 // FIXME: We shouldn't need to do this, the target should be immutable once
633 // created. This complexity should be lifted elsewhere.
634 Target->adjust(PP.getDiagnostics(), LangOpt);
635
636 // Initialize the preprocessor.
637 PP.Initialize(*Target);
638
639 if (!Context)
640 return;
641
642 // Initialize the ASTContext
643 Context->InitBuiltinTypes(*Target);
644
645 // Adjust printing policy based on language options.
646 Context->setPrintingPolicy(PrintingPolicy(LangOpt));
647
648 // We didn't have access to the comment options when the ASTContext was
649 // constructed, so register them now.
651 LangOpt.CommentOpts);
652 }
653};
654
655/// Diagnostic consumer that saves each diagnostic it is given.
656class FilterAndStoreDiagnosticConsumer : public DiagnosticConsumer {
659 bool CaptureNonErrorsFromIncludes = true;
660 const LangOptions *LangOpts = nullptr;
661 SourceManager *SourceMgr = nullptr;
662
663public:
664 FilterAndStoreDiagnosticConsumer(
667 bool CaptureNonErrorsFromIncludes)
668 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
669 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
670 assert((StoredDiags || StandaloneDiags) &&
671 "No output collections were passed to StoredDiagnosticConsumer.");
672 }
673
674 void BeginSourceFile(const LangOptions &LangOpts,
675 const Preprocessor *PP = nullptr) override {
676 this->LangOpts = &LangOpts;
677 if (PP)
678 SourceMgr = &PP->getSourceManager();
679 }
680
681 void HandleDiagnostic(DiagnosticsEngine::Level Level,
682 const Diagnostic &Info) override;
683};
684
685/// RAII object that optionally captures and filters diagnostics, if
686/// there is no diagnostic client to capture them already.
687class CaptureDroppedDiagnostics {
688 DiagnosticsEngine &Diags;
689 FilterAndStoreDiagnosticConsumer Client;
690 DiagnosticConsumer *PreviousClient = nullptr;
691 std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
692
693public:
694 CaptureDroppedDiagnostics(
695 CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
698 : Diags(Diags),
699 Client(StoredDiags, StandaloneDiags,
700 CaptureDiagnostics !=
702 if (CaptureDiagnostics != CaptureDiagsKind::None ||
703 Diags.getClient() == nullptr) {
704 OwningPreviousClient = Diags.takeClient();
705 PreviousClient = Diags.getClient();
706 Diags.setClient(&Client, false);
707 }
708 }
709
710 ~CaptureDroppedDiagnostics() {
711 if (Diags.getClient() == &Client)
712 Diags.setClient(PreviousClient, !!OwningPreviousClient.release());
713 }
714};
715
716} // namespace
717
720 const StoredDiagnostic &InDiag);
721
722static bool isInMainFile(const clang::Diagnostic &D) {
723 if (!D.hasSourceManager() || !D.getLocation().isValid())
724 return false;
725
726 auto &M = D.getSourceManager();
727 return M.isWrittenInMainFile(M.getExpansionLoc(D.getLocation()));
728}
729
730void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
731 DiagnosticsEngine::Level Level, const Diagnostic &Info) {
732 // Default implementation (Warnings/errors count).
734
735 // Only record the diagnostic if it's part of the source manager we know
736 // about. This effectively drops diagnostics from modules we're building.
737 // FIXME: In the long run, ee don't want to drop source managers from modules.
738 if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) {
739 if (!CaptureNonErrorsFromIncludes && Level <= DiagnosticsEngine::Warning &&
740 !isInMainFile(Info)) {
741 return;
742 }
743
744 StoredDiagnostic *ResultDiag = nullptr;
745 if (StoredDiags) {
746 StoredDiags->emplace_back(Level, Info);
747 ResultDiag = &StoredDiags->back();
748 }
749
750 if (StandaloneDiags) {
751 std::optional<StoredDiagnostic> StoredDiag;
752 if (!ResultDiag) {
753 StoredDiag.emplace(Level, Info);
754 ResultDiag = &*StoredDiag;
755 }
756 StandaloneDiags->push_back(
757 makeStandaloneDiagnostic(*LangOpts, *ResultDiag));
758 }
759 }
760}
761
763 return Reader;
764}
765
767 if (WriterData)
768 return &WriterData->Writer;
769 return nullptr;
770}
771
773 if (WriterData)
774 return &WriterData->Writer;
775 return nullptr;
776}
777
778std::unique_ptr<llvm::MemoryBuffer>
779ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
780 assert(FileMgr);
781 auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
782 if (Buffer)
783 return std::move(*Buffer);
784 if (ErrorStr)
785 *ErrorStr = Buffer.getError().message();
786 return nullptr;
787}
788
789/// Configure the diagnostics object for use with ASTUnit.
790void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
791 ASTUnit &AST,
792 CaptureDiagsKind CaptureDiagnostics) {
793 assert(Diags.get() && "no DiagnosticsEngine was provided");
794 if (CaptureDiagnostics != CaptureDiagsKind::None)
795 Diags->setClient(new FilterAndStoreDiagnosticConsumer(
796 &AST.StoredDiagnostics, nullptr,
798}
799
800std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
801 const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
803 const FileSystemOptions &FileSystemOpts,
804 std::shared_ptr<HeaderSearchOptions> HSOpts,
805 std::shared_ptr<LangOptions> LangOpts, bool OnlyLocalDecls,
806 CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,
807 bool UserFilesAreVolatile, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
808 std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
809
810 // Recover resources if we crash before exiting this method.
811 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
812 ASTUnitCleanup(AST.get());
813 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
814 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
815 DiagCleanup(Diags.get());
816
817 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
818
819 AST->LangOpts = LangOpts ? LangOpts : std::make_shared<LangOptions>();
820 AST->OnlyLocalDecls = OnlyLocalDecls;
821 AST->CaptureDiagnostics = CaptureDiagnostics;
822 AST->Diagnostics = Diags;
823 AST->FileMgr = new FileManager(FileSystemOpts, VFS);
824 AST->UserFilesAreVolatile = UserFilesAreVolatile;
825 AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
826 AST->getFileManager(),
827 UserFilesAreVolatile);
828 AST->ModuleCache = new InMemoryModuleCache;
829 AST->HSOpts = HSOpts ? HSOpts : std::make_shared<HeaderSearchOptions>();
830 AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
831 AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
832 AST->getSourceManager(),
833 AST->getDiagnostics(),
834 AST->getLangOpts(),
835 /*Target=*/nullptr));
836 AST->PPOpts = std::make_shared<PreprocessorOptions>();
837
838 // Gather Info for preprocessor construction later on.
839
840 HeaderSearch &HeaderInfo = *AST->HeaderInfo;
841
842 AST->PP = std::make_shared<Preprocessor>(
843 AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
844 AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,
845 /*IILookup=*/nullptr,
846 /*OwnsHeaderSearch=*/false);
847 Preprocessor &PP = *AST->PP;
848
849 if (ToLoad >= LoadASTOnly)
850 AST->Ctx = new ASTContext(*AST->LangOpts, AST->getSourceManager(),
852 PP.getBuiltinInfo(),
853 AST->getTranslationUnitKind());
854
855 DisableValidationForModuleKind disableValid =
857 if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
859 AST->Reader = new ASTReader(
860 PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
861 /*isysroot=*/"",
862 /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);
863
864 unsigned Counter = 0;
865 AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
866 *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
867 AST->TargetOpts, AST->Target, Counter));
868
869 // Attach the AST reader to the AST context as an external AST
870 // source, so that declarations will be deserialized from the
871 // AST file as needed.
872 // We need the external source to be set up before we read the AST, because
873 // eagerly-deserialized declarations may use it.
874 if (AST->Ctx)
875 AST->Ctx->setExternalSource(AST->Reader);
876
877 switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,
880 break;
881
888 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
889 return nullptr;
890 }
891
892 AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());
893
894 PP.setCounterValue(Counter);
895
896 Module *M = HeaderInfo.lookupModule(AST->getLangOpts().CurrentModule);
897 if (M && AST->getLangOpts().isCompilingModule() && M->isNamedModule())
898 AST->Ctx->setCurrentNamedModule(M);
899
900 // Create an AST consumer, even though it isn't used.
901 if (ToLoad >= LoadASTOnly)
902 AST->Consumer.reset(new ASTConsumer);
903
904 // Create a semantic analysis object and tell the AST reader about it.
905 if (ToLoad >= LoadEverything) {
906 AST->TheSema.reset(new Sema(PP, *AST->Ctx, *AST->Consumer));
907 AST->TheSema->Initialize();
908 AST->Reader->InitializeSema(*AST->TheSema);
909 }
910
911 // Tell the diagnostic client that we have started a source file.
912 AST->getDiagnostics().getClient()->BeginSourceFile(PP.getLangOpts(), &PP);
913
914 return AST;
915}
916
917/// Add the given macro to the hash of all top-level entities.
918static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
919 Hash = llvm::djbHash(MacroNameTok.getIdentifierInfo()->getName(), Hash);
920}
921
922namespace {
923
924/// Preprocessor callback class that updates a hash value with the names
925/// of all macros that have been defined by the translation unit.
926class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {
927 unsigned &Hash;
928
929public:
930 explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}
931
932 void MacroDefined(const Token &MacroNameTok,
933 const MacroDirective *MD) override {
934 AddDefinedMacroToHash(MacroNameTok, Hash);
935 }
936};
937
938} // namespace
939
940/// Add the given declaration to the hash of all top-level entities.
941static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
942 if (!D)
943 return;
944
945 DeclContext *DC = D->getDeclContext();
946 if (!DC)
947 return;
948
949 if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))
950 return;
951
952 if (const auto *ND = dyn_cast<NamedDecl>(D)) {
953 if (const auto *EnumD = dyn_cast<EnumDecl>(D)) {
954 // For an unscoped enum include the enumerators in the hash since they
955 // enter the top-level namespace.
956 if (!EnumD->isScoped()) {
957 for (const auto *EI : EnumD->enumerators()) {
958 if (EI->getIdentifier())
959 Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
960 }
961 }
962 }
963
964 if (ND->getIdentifier())
965 Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
966 else if (DeclarationName Name = ND->getDeclName()) {
967 std::string NameStr = Name.getAsString();
968 Hash = llvm::djbHash(NameStr, Hash);
969 }
970 return;
971 }
972
973 if (const auto *ImportD = dyn_cast<ImportDecl>(D)) {
974 if (const Module *Mod = ImportD->getImportedModule()) {
975 std::string ModName = Mod->getFullModuleName();
976 Hash = llvm::djbHash(ModName, Hash);
977 }
978 return;
979 }
980}
981
982namespace {
983
984class TopLevelDeclTrackerConsumer : public ASTConsumer {
985 ASTUnit &Unit;
986 unsigned &Hash;
987
988public:
989 TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)
990 : Unit(_Unit), Hash(Hash) {
991 Hash = 0;
992 }
993
994 void handleTopLevelDecl(Decl *D) {
995 if (!D)
996 return;
997
998 // FIXME: Currently ObjC method declarations are incorrectly being
999 // reported as top-level declarations, even though their DeclContext
1000 // is the containing ObjC @interface/@implementation. This is a
1001 // fundamental problem in the parser right now.
1002 if (isa<ObjCMethodDecl>(D))
1003 return;
1004
1006 Unit.addTopLevelDecl(D);
1007
1008 handleFileLevelDecl(D);
1009 }
1010
1011 void handleFileLevelDecl(Decl *D) {
1012 Unit.addFileLevelDecl(D);
1013 if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {
1014 for (auto *I : NSD->decls())
1015 handleFileLevelDecl(I);
1016 }
1017 }
1018
1019 bool HandleTopLevelDecl(DeclGroupRef D) override {
1020 for (auto *TopLevelDecl : D)
1021 handleTopLevelDecl(TopLevelDecl);
1022 return true;
1023 }
1024
1025 // We're not interested in "interesting" decls.
1026 void HandleInterestingDecl(DeclGroupRef) override {}
1027
1028 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
1029 for (auto *TopLevelDecl : D)
1030 handleTopLevelDecl(TopLevelDecl);
1031 }
1032
1033 ASTMutationListener *GetASTMutationListener() override {
1034 return Unit.getASTMutationListener();
1035 }
1036
1037 ASTDeserializationListener *GetASTDeserializationListener() override {
1038 return Unit.getDeserializationListener();
1039 }
1040};
1041
1042class TopLevelDeclTrackerAction : public ASTFrontendAction {
1043public:
1044 ASTUnit &Unit;
1045
1046 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
1047 StringRef InFile) override {
1049 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1051 return std::make_unique<TopLevelDeclTrackerConsumer>(
1052 Unit, Unit.getCurrentTopLevelHashValue());
1053 }
1054
1055public:
1056 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
1057
1058 bool hasCodeCompletionSupport() const override { return false; }
1059
1060 TranslationUnitKind getTranslationUnitKind() override {
1061 return Unit.getTranslationUnitKind();
1062 }
1063};
1064
1065class ASTUnitPreambleCallbacks : public PreambleCallbacks {
1066public:
1067 unsigned getHash() const { return Hash; }
1068
1069 std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
1070
1071 std::vector<LocalDeclID> takeTopLevelDeclIDs() {
1072 return std::move(TopLevelDeclIDs);
1073 }
1074
1075 void AfterPCHEmitted(ASTWriter &Writer) override {
1076 TopLevelDeclIDs.reserve(TopLevelDecls.size());
1077 for (const auto *D : TopLevelDecls) {
1078 // Invalid top-level decls may not have been serialized.
1079 if (D->isInvalidDecl())
1080 continue;
1081 TopLevelDeclIDs.push_back(Writer.getDeclID(D));
1082 }
1083 }
1084
1085 void HandleTopLevelDecl(DeclGroupRef DG) override {
1086 for (auto *D : DG) {
1087 // FIXME: Currently ObjC method declarations are incorrectly being
1088 // reported as top-level declarations, even though their DeclContext
1089 // is the containing ObjC @interface/@implementation. This is a
1090 // fundamental problem in the parser right now.
1091 if (isa<ObjCMethodDecl>(D))
1092 continue;
1094 TopLevelDecls.push_back(D);
1095 }
1096 }
1097
1098 std::unique_ptr<PPCallbacks> createPPCallbacks() override {
1099 return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);
1100 }
1101
1102private:
1103 unsigned Hash = 0;
1104 std::vector<Decl *> TopLevelDecls;
1105 std::vector<LocalDeclID> TopLevelDeclIDs;
1107};
1108
1109} // namespace
1110
1111static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
1112 return StoredDiag.getLocation().isValid();
1113}
1114
1115static void
1117 // Get rid of stored diagnostics except the ones from the driver which do not
1118 // have a source location.
1119 llvm::erase_if(StoredDiags, isNonDriverDiag);
1120}
1121
1123 StoredDiagnostics,
1124 SourceManager &SM) {
1125 // The stored diagnostic has the old source manager in it; update
1126 // the locations to refer into the new source manager. Since we've
1127 // been careful to make sure that the source manager's state
1128 // before and after are identical, so that we can reuse the source
1129 // location itself.
1130 for (auto &SD : StoredDiagnostics) {
1131 if (SD.getLocation().isValid()) {
1132 FullSourceLoc Loc(SD.getLocation(), SM);
1133 SD.setLocation(Loc);
1134 }
1135 }
1136}
1137
1138/// Parse the source file into a translation unit using the given compiler
1139/// invocation, replacing the current translation unit.
1140///
1141/// \returns True if a failure occurred that causes the ASTUnit not to
1142/// contain any translation-unit information, false otherwise.
1143bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1144 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
1146 if (!Invocation)
1147 return true;
1148
1149 if (VFS && FileMgr)
1150 assert(VFS == &FileMgr->getVirtualFileSystem() &&
1151 "VFS passed to Parse and VFS in FileMgr are different");
1152
1153 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
1154 if (OverrideMainBuffer) {
1155 assert(Preamble &&
1156 "No preamble was built, but OverrideMainBuffer is not null");
1157 Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
1158 // VFS may have changed...
1159 }
1160
1161 // Create the compiler instance to use for building the AST.
1162 std::unique_ptr<CompilerInstance> Clang(
1163 new CompilerInstance(std::move(PCHContainerOps)));
1164 Clang->setInvocation(CCInvocation);
1165
1166 // Clean up on error, disengage it if the function returns successfully.
1167 auto CleanOnError = llvm::make_scope_exit([&]() {
1168 // Remove the overridden buffer we used for the preamble.
1169 SavedMainFileBuffer = nullptr;
1170
1171 // Keep the ownership of the data in the ASTUnit because the client may
1172 // want to see the diagnostics.
1173 transferASTDataFromCompilerInstance(*Clang);
1174 FailedParseDiagnostics.swap(StoredDiagnostics);
1175 StoredDiagnostics.clear();
1176 NumStoredDiagnosticsFromDriver = 0;
1177 });
1178
1179 // Ensure that Clang has a FileManager with the right VFS, which may have
1180 // changed above in AddImplicitPreamble. If VFS is nullptr, rely on
1181 // createFileManager to create one.
1182 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS)
1183 Clang->setFileManager(&*FileMgr);
1184 else
1185 FileMgr = Clang->createFileManager(std::move(VFS));
1186
1187 // Recover resources if we crash before exiting this method.
1188 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1189 CICleanup(Clang.get());
1190
1191 OriginalSourceFile =
1192 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1193
1194 // Set up diagnostics, capturing any diagnostics that would
1195 // otherwise be dropped.
1196 Clang->setDiagnostics(&getDiagnostics());
1197
1198 // Create the target instance.
1199 if (!Clang->createTarget())
1200 return true;
1201
1202 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1203 "Invocation must have exactly one source file!");
1204 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1206 "FIXME: AST inputs not yet supported here!");
1207 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1209 "IR inputs not support here!");
1210
1211 // Configure the various subsystems.
1212 LangOpts = Clang->getInvocation().LangOpts;
1213 FileSystemOpts = Clang->getFileSystemOpts();
1214
1215 ResetForParse();
1216
1217 SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
1218 UserFilesAreVolatile);
1219 if (!OverrideMainBuffer) {
1220 checkAndRemoveNonDriverDiags(StoredDiagnostics);
1221 TopLevelDeclsInPreamble.clear();
1222 }
1223
1224 // Create the source manager.
1225 Clang->setSourceManager(&getSourceManager());
1226
1227 // If the main file has been overridden due to the use of a preamble,
1228 // make that override happen and introduce the preamble.
1229 if (OverrideMainBuffer) {
1230 // The stored diagnostic has the old source manager in it; update
1231 // the locations to refer into the new source manager. Since we've
1232 // been careful to make sure that the source manager's state
1233 // before and after are identical, so that we can reuse the source
1234 // location itself.
1235 checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
1236
1237 // Keep track of the override buffer;
1238 SavedMainFileBuffer = std::move(OverrideMainBuffer);
1239 }
1240
1241 std::unique_ptr<TopLevelDeclTrackerAction> Act(
1242 new TopLevelDeclTrackerAction(*this));
1243
1244 // Recover resources if we crash before exiting this method.
1245 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1246 ActCleanup(Act.get());
1247
1248 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
1249 return true;
1250
1251 if (SavedMainFileBuffer)
1252 TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
1253 PreambleDiagnostics, StoredDiagnostics);
1254 else
1255 PreambleSrcLocCache.clear();
1256
1257 if (llvm::Error Err = Act->Execute()) {
1258 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1259 return true;
1260 }
1261
1262 transferASTDataFromCompilerInstance(*Clang);
1263
1264 Act->EndSourceFile();
1265
1266 FailedParseDiagnostics.clear();
1267
1268 CleanOnError.release();
1269
1270 return false;
1271}
1272
1273static std::pair<unsigned, unsigned>
1275 const LangOptions &LangOpts) {
1276 CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts);
1277 unsigned Offset = SM.getFileOffset(FileRange.getBegin());
1278 unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());
1279 return std::make_pair(Offset, EndOffset);
1280}
1281
1283 const LangOptions &LangOpts,
1284 const FixItHint &InFix) {
1286 OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);
1288 LangOpts);
1289 OutFix.CodeToInsert = InFix.CodeToInsert;
1291 return OutFix;
1292}
1293
1296 const StoredDiagnostic &InDiag) {
1298 OutDiag.ID = InDiag.getID();
1299 OutDiag.Level = InDiag.getLevel();
1300 OutDiag.Message = std::string(InDiag.getMessage());
1301 OutDiag.LocOffset = 0;
1302 if (InDiag.getLocation().isInvalid())
1303 return OutDiag;
1304 const SourceManager &SM = InDiag.getLocation().getManager();
1305 SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());
1306 OutDiag.Filename = std::string(SM.getFilename(FileLoc));
1307 if (OutDiag.Filename.empty())
1308 return OutDiag;
1309 OutDiag.LocOffset = SM.getFileOffset(FileLoc);
1310 for (const auto &Range : InDiag.getRanges())
1311 OutDiag.Ranges.push_back(makeStandaloneRange(Range, SM, LangOpts));
1312 for (const auto &FixIt : InDiag.getFixIts())
1313 OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, FixIt));
1314
1315 return OutDiag;
1316}
1317
1318/// Attempt to build or re-use a precompiled preamble when (re-)parsing
1319/// the source file.
1320///
1321/// This routine will compute the preamble of the main source file. If a
1322/// non-trivial preamble is found, it will precompile that preamble into a
1323/// precompiled header so that the precompiled preamble can be used to reduce
1324/// reparsing time. If a precompiled preamble has already been constructed,
1325/// this routine will determine if it is still valid and, if so, avoid
1326/// rebuilding the precompiled preamble.
1327///
1328/// \param AllowRebuild When true (the default), this routine is
1329/// allowed to rebuild the precompiled preamble if it is found to be
1330/// out-of-date.
1331///
1332/// \param MaxLines When non-zero, the maximum number of lines that
1333/// can occur within the preamble.
1334///
1335/// \returns If the precompiled preamble can be used, returns a newly-allocated
1336/// buffer that should be used in place of the main file when doing so.
1337/// Otherwise, returns a NULL pointer.
1338std::unique_ptr<llvm::MemoryBuffer>
1339ASTUnit::getMainBufferWithPrecompiledPreamble(
1340 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1341 CompilerInvocation &PreambleInvocationIn,
1342 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild,
1343 unsigned MaxLines) {
1344 auto MainFilePath =
1345 PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
1346 std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
1347 getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
1348 MainFilePath, UserFilesAreVolatile);
1349 if (!MainFileBuffer)
1350 return nullptr;
1351
1353 PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines);
1354 if (!Bounds.Size)
1355 return nullptr;
1356
1357 if (Preamble) {
1358 if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
1359 *VFS)) {
1360 // Okay! We can re-use the precompiled preamble.
1361
1362 // Set the state of the diagnostic object to mimic its state
1363 // after parsing the preamble.
1366 PreambleInvocationIn.getDiagnosticOpts());
1367 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1368
1369 PreambleRebuildCountdown = 1;
1370 return MainFileBuffer;
1371 } else {
1372 Preamble.reset();
1373 PreambleDiagnostics.clear();
1374 TopLevelDeclsInPreamble.clear();
1375 PreambleSrcLocCache.clear();
1376 PreambleRebuildCountdown = 1;
1377 }
1378 }
1379
1380 // If the preamble rebuild counter > 1, it's because we previously
1381 // failed to build a preamble and we're not yet ready to try
1382 // again. Decrement the counter and return a failure.
1383 if (PreambleRebuildCountdown > 1) {
1384 --PreambleRebuildCountdown;
1385 return nullptr;
1386 }
1387
1388 assert(!Preamble && "No Preamble should be stored at that point");
1389 // If we aren't allowed to rebuild the precompiled preamble, just
1390 // return now.
1391 if (!AllowRebuild)
1392 return nullptr;
1393
1394 ++PreambleCounter;
1395
1396 SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;
1397 SmallVector<StoredDiagnostic, 4> NewPreambleDiags;
1398 ASTUnitPreambleCallbacks Callbacks;
1399 {
1400 std::optional<CaptureDroppedDiagnostics> Capture;
1401 if (CaptureDiagnostics != CaptureDiagsKind::None)
1402 Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,
1403 &NewPreambleDiagsStandalone);
1404
1405 // We did not previously compute a preamble, or it can't be reused anyway.
1406 SimpleTimer PreambleTimer(WantTiming);
1407 PreambleTimer.setOutput("Precompiling preamble");
1408
1409 const bool PreviousSkipFunctionBodies =
1410 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;
1411 if (SkipFunctionBodies == SkipFunctionBodiesScope::Preamble)
1412 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true;
1413
1414 llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(
1415 PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,
1416 PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,
1417 Callbacks);
1418
1419 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
1420 PreviousSkipFunctionBodies;
1421
1422 if (NewPreamble) {
1423 Preamble = std::move(*NewPreamble);
1424 PreambleRebuildCountdown = 1;
1425 } else {
1426 switch (static_cast<BuildPreambleError>(NewPreamble.getError().value())) {
1428 // Try again next time.
1429 PreambleRebuildCountdown = 1;
1430 return nullptr;
1435 // These erros are more likely to repeat, retry after some period.
1436 PreambleRebuildCountdown = DefaultPreambleRebuildInterval;
1437 return nullptr;
1438 }
1439 llvm_unreachable("unexpected BuildPreambleError");
1440 }
1441 }
1442
1443 assert(Preamble && "Preamble wasn't built");
1444
1445 TopLevelDecls.clear();
1446 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
1447 PreambleTopLevelHashValue = Callbacks.getHash();
1448
1449 NumWarningsInPreamble = getDiagnostics().getNumWarnings();
1450
1451 checkAndRemoveNonDriverDiags(NewPreambleDiags);
1452 StoredDiagnostics = std::move(NewPreambleDiags);
1453 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
1454
1455 // If the hash of top-level entities differs from the hash of the top-level
1456 // entities the last time we rebuilt the preamble, clear out the completion
1457 // cache.
1458 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
1459 CompletionCacheTopLevelHashValue = 0;
1460 PreambleTopLevelHashValue = CurrentTopLevelHashValue;
1461 }
1462
1463 return MainFileBuffer;
1464}
1465
1466void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1467 assert(Preamble && "Should only be called when preamble was built");
1468
1469 std::vector<Decl *> Resolved;
1470 Resolved.reserve(TopLevelDeclsInPreamble.size());
1471 // The module file of the preamble.
1472 serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();
1473 for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1474 // Resolve the declaration ID to an actual declaration, possibly
1475 // deserializing the declaration in the process.
1476 if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))
1477 Resolved.push_back(D);
1478 }
1479 TopLevelDeclsInPreamble.clear();
1480 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1481}
1482
1483void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
1484 // Steal the created target, context, and preprocessor if they have been
1485 // created.
1486 assert(CI.hasInvocation() && "missing invocation");
1487 LangOpts = CI.getInvocation().LangOpts;
1488 TheSema = CI.takeSema();
1489 Consumer = CI.takeASTConsumer();
1490 if (CI.hasASTContext())
1491 Ctx = &CI.getASTContext();
1492 if (CI.hasPreprocessor())
1493 PP = CI.getPreprocessorPtr();
1494 CI.setSourceManager(nullptr);
1495 CI.setFileManager(nullptr);
1496 if (CI.hasTarget())
1497 Target = &CI.getTarget();
1498 Reader = CI.getASTReader();
1499 HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
1500}
1501
1502StringRef ASTUnit::getMainFileName() const {
1503 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1504 const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];
1505 if (Input.isFile())
1506 return Input.getFile();
1507 else
1508 return Input.getBuffer().getBufferIdentifier();
1509 }
1510
1511 if (SourceMgr) {
1512 if (OptionalFileEntryRef FE =
1513 SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID()))
1514 return FE->getName();
1515 }
1516
1517 return {};
1518}
1519
1520StringRef ASTUnit::getASTFileName() const {
1521 if (!isMainFileAST())
1522 return {};
1523
1525 Mod = Reader->getModuleManager().getPrimaryModule();
1526 return Mod.FileName;
1527}
1528
1529std::unique_ptr<ASTUnit>
1530ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
1532 CaptureDiagsKind CaptureDiagnostics,
1533 bool UserFilesAreVolatile) {
1534 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1535 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1538 AST->Diagnostics = Diags;
1539 AST->FileSystemOpts = CI->getFileSystemOpts();
1540 AST->Invocation = std::move(CI);
1541 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
1542 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1543 AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
1544 UserFilesAreVolatile);
1545 AST->ModuleCache = new InMemoryModuleCache;
1546
1547 return AST;
1548}
1549
1551 std::shared_ptr<CompilerInvocation> CI,
1552 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1554 ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
1555 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1556 unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
1557 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1558 assert(CI && "A CompilerInvocation is required");
1559
1560 std::unique_ptr<ASTUnit> OwnAST;
1561 ASTUnit *AST = Unit;
1562 if (!AST) {
1563 // Create the AST unit.
1564 OwnAST = create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1565 AST = OwnAST.get();
1566 if (!AST)
1567 return nullptr;
1568 }
1569
1570 if (!ResourceFilesPath.empty()) {
1571 // Override the resources path.
1572 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1573 }
1574 AST->OnlyLocalDecls = OnlyLocalDecls;
1575 AST->CaptureDiagnostics = CaptureDiagnostics;
1576 if (PrecompilePreambleAfterNParses > 0)
1577 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1578 AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
1579 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1580 AST->IncludeBriefCommentsInCodeCompletion = false;
1581
1582 // Recover resources if we crash before exiting this method.
1583 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1584 ASTUnitCleanup(OwnAST.get());
1585 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1586 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1587 DiagCleanup(Diags.get());
1588
1589 // We'll manage file buffers ourselves.
1590 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1591 CI->getFrontendOpts().DisableFree = false;
1592 ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
1593
1594 // Create the compiler instance to use for building the AST.
1595 std::unique_ptr<CompilerInstance> Clang(
1596 new CompilerInstance(std::move(PCHContainerOps)));
1597
1598 // Recover resources if we crash before exiting this method.
1599 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1600 CICleanup(Clang.get());
1601
1602 Clang->setInvocation(std::move(CI));
1603 AST->OriginalSourceFile =
1604 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1605
1606 // Set up diagnostics, capturing any diagnostics that would
1607 // otherwise be dropped.
1608 Clang->setDiagnostics(&AST->getDiagnostics());
1609
1610 // Create the target instance.
1611 if (!Clang->createTarget())
1612 return nullptr;
1613
1614 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1615 "Invocation must have exactly one source file!");
1616 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1618 "FIXME: AST inputs not yet supported here!");
1619 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1621 "IR inputs not support here!");
1622
1623 // Configure the various subsystems.
1624 AST->TheSema.reset();
1625 AST->Ctx = nullptr;
1626 AST->PP = nullptr;
1627 AST->Reader = nullptr;
1628
1629 // Create a file manager object to provide access to and cache the filesystem.
1630 Clang->setFileManager(&AST->getFileManager());
1631
1632 // Create the source manager.
1633 Clang->setSourceManager(&AST->getSourceManager());
1634
1635 FrontendAction *Act = Action;
1636
1637 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1638 if (!Act) {
1639 TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
1640 Act = TrackerAct.get();
1641 }
1642
1643 // Recover resources if we crash before exiting this method.
1644 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1645 ActCleanup(TrackerAct.get());
1646
1647 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
1648 AST->transferASTDataFromCompilerInstance(*Clang);
1649 if (OwnAST && ErrAST)
1650 ErrAST->swap(OwnAST);
1651
1652 return nullptr;
1653 }
1654
1655 if (Persistent && !TrackerAct) {
1656 Clang->getPreprocessor().addPPCallbacks(
1657 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1659 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1660 if (Clang->hasASTConsumer())
1661 Consumers.push_back(Clang->takeASTConsumer());
1662 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1663 *AST, AST->getCurrentTopLevelHashValue()));
1664 Clang->setASTConsumer(
1665 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1666 }
1667 if (llvm::Error Err = Act->Execute()) {
1668 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1669 AST->transferASTDataFromCompilerInstance(*Clang);
1670 if (OwnAST && ErrAST)
1671 ErrAST->swap(OwnAST);
1672
1673 return nullptr;
1674 }
1675
1676 // Steal the created target, context, and preprocessor.
1677 AST->transferASTDataFromCompilerInstance(*Clang);
1678
1679 Act->EndSourceFile();
1680
1681 if (OwnAST)
1682 return OwnAST.release();
1683 else
1684 return AST;
1685}
1686
1687bool ASTUnit::LoadFromCompilerInvocation(
1688 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1689 unsigned PrecompilePreambleAfterNParses,
1691 if (!Invocation)
1692 return true;
1693
1694 assert(VFS && "VFS is null");
1695
1696 // We'll manage file buffers ourselves.
1697 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1698 Invocation->getFrontendOpts().DisableFree = false;
1700 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
1701
1702 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1703 if (PrecompilePreambleAfterNParses > 0) {
1704 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1705 OverrideMainBuffer =
1706 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1708 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
1709 }
1710
1711 SimpleTimer ParsingTimer(WantTiming);
1712 ParsingTimer.setOutput("Parsing " + getMainFileName());
1713
1714 // Recover resources if we crash before exiting this method.
1715 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1716 MemBufferCleanup(OverrideMainBuffer.get());
1717
1718 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1719}
1720
1721std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1722 std::shared_ptr<CompilerInvocation> CI,
1723 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1725 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1726 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1727 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1728 bool UserFilesAreVolatile) {
1729 // Create the AST unit.
1730 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1731 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1732 AST->Diagnostics = Diags;
1733 AST->OnlyLocalDecls = OnlyLocalDecls;
1734 AST->CaptureDiagnostics = CaptureDiagnostics;
1735 AST->TUKind = TUKind;
1736 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1737 AST->IncludeBriefCommentsInCodeCompletion
1738 = IncludeBriefCommentsInCodeCompletion;
1739 AST->Invocation = std::move(CI);
1740 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1741 AST->FileMgr = FileMgr;
1742 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1743
1744 // Recover resources if we crash before exiting this method.
1745 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1746 ASTUnitCleanup(AST.get());
1747 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1748 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1749 DiagCleanup(Diags.get());
1750
1751 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1752 PrecompilePreambleAfterNParses,
1753 &AST->FileMgr->getVirtualFileSystem()))
1754 return nullptr;
1755 return AST;
1756}
1757
1758std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
1759 const char **ArgBegin, const char **ArgEnd,
1760 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1761 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
1762 bool StorePreamblesInMemory, StringRef PreambleStoragePath,
1763 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1764 ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
1765 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1766 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1767 bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
1768 bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
1769 bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
1770 std::unique_ptr<ASTUnit> *ErrAST,
1772 assert(Diags.get() && "no DiagnosticsEngine was provided");
1773
1774 // If no VFS was provided, create one that tracks the physical file system.
1775 // If '-working-directory' was passed as an argument, 'createInvocation' will
1776 // set this as the current working directory of the VFS.
1777 if (!VFS)
1778 VFS = llvm::vfs::createPhysicalFileSystem();
1779
1780 SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
1781
1782 std::shared_ptr<CompilerInvocation> CI;
1783
1784 {
1785 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
1786 &StoredDiagnostics, nullptr);
1787
1789 CIOpts.VFS = VFS;
1790 CIOpts.Diags = Diags;
1791 CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
1792 CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));
1793 if (!CI)
1794 return nullptr;
1795 }
1796
1797 // Override any files that need remapping
1798 for (const auto &RemappedFile : RemappedFiles) {
1799 CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1800 RemappedFile.second);
1801 }
1802 PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
1803 PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
1804 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
1805 PPOpts.SingleFileParseMode = SingleFileParse;
1806 PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
1807
1808 // Override the resources path.
1809 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1810
1811 CI->getFrontendOpts().SkipFunctionBodies =
1813
1814 if (ModuleFormat)
1815 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
1816
1817 // Create the AST unit.
1818 std::unique_ptr<ASTUnit> AST;
1819 AST.reset(new ASTUnit(false));
1820 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1821 AST->StoredDiagnostics.swap(StoredDiagnostics);
1822 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1823 AST->Diagnostics = Diags;
1824 AST->FileSystemOpts = CI->getFileSystemOpts();
1825 VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
1826 AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
1827 AST->StorePreamblesInMemory = StorePreamblesInMemory;
1828 AST->PreambleStoragePath = PreambleStoragePath;
1829 AST->ModuleCache = new InMemoryModuleCache;
1830 AST->OnlyLocalDecls = OnlyLocalDecls;
1831 AST->CaptureDiagnostics = CaptureDiagnostics;
1832 AST->TUKind = TUKind;
1833 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1834 AST->IncludeBriefCommentsInCodeCompletion
1835 = IncludeBriefCommentsInCodeCompletion;
1836 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1837 AST->Invocation = CI;
1838 AST->SkipFunctionBodies = SkipFunctionBodies;
1839 if (ForSerialization)
1840 AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));
1841 // Zero out now to ease cleanup during crash recovery.
1842 CI = nullptr;
1843 Diags = nullptr;
1844
1845 // Recover resources if we crash before exiting this method.
1846 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1847 ASTUnitCleanup(AST.get());
1848
1849 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1850 PrecompilePreambleAfterNParses,
1851 VFS)) {
1852 // Some error occurred, if caller wants to examine diagnostics, pass it the
1853 // ASTUnit.
1854 if (ErrAST) {
1855 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1856 ErrAST->swap(AST);
1857 }
1858 return nullptr;
1859 }
1860
1861 return AST;
1862}
1863
1864bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1865 ArrayRef<RemappedFile> RemappedFiles,
1867 if (!Invocation)
1868 return true;
1869
1870 if (!VFS) {
1871 assert(FileMgr && "FileMgr is null on Reparse call");
1872 VFS = &FileMgr->getVirtualFileSystem();
1873 }
1874
1875 clearFileLevelDecls();
1876
1877 SimpleTimer ParsingTimer(WantTiming);
1878 ParsingTimer.setOutput("Reparsing " + getMainFileName());
1879
1880 // Remap files.
1881 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1882 for (const auto &RB : PPOpts.RemappedFileBuffers)
1883 delete RB.second;
1884
1885 Invocation->getPreprocessorOpts().clearRemappedFiles();
1886 for (const auto &RemappedFile : RemappedFiles) {
1887 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
1888 RemappedFile.second);
1889 }
1890
1891 // If we have a preamble file lying around, or if we might try to
1892 // build a precompiled preamble, do so now.
1893 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1894 if (Preamble || PreambleRebuildCountdown > 0)
1895 OverrideMainBuffer =
1896 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1897
1898 // Clear out the diagnostics state.
1899 FileMgr.reset();
1901 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
1902 if (OverrideMainBuffer)
1903 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1904
1905 // Parse the sources
1906 bool Result =
1907 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1908
1909 // If we're caching global code-completion results, and the top-level
1910 // declarations have changed, clear out the code-completion cache.
1911 if (!Result && ShouldCacheCodeCompletionResults &&
1912 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1913 CacheCodeCompletionResults();
1914
1915 // We now need to clear out the completion info related to this translation
1916 // unit; it'll be recreated if necessary.
1917 CCTUInfo.reset();
1918
1919 return Result;
1920}
1921
1923 SavedMainFileBuffer.reset();
1924
1925 SourceMgr.reset();
1926 TheSema.reset();
1927 Ctx.reset();
1928 PP.reset();
1929 Reader.reset();
1930
1931 TopLevelDecls.clear();
1932 clearFileLevelDecls();
1933}
1934
1935//----------------------------------------------------------------------------//
1936// Code completion
1937//----------------------------------------------------------------------------//
1938
1939namespace {
1940
1941 /// Code completion consumer that combines the cached code-completion
1942 /// results from an ASTUnit with the code-completion results provided to it,
1943 /// then passes the result on to
1944 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
1945 uint64_t NormalContexts;
1946 ASTUnit &AST;
1948
1949 public:
1950 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
1951 const CodeCompleteOptions &CodeCompleteOpts)
1952 : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
1953 // Compute the set of contexts in which we will look when we don't have
1954 // any information about the specific context.
1955 NormalContexts
1969
1970 if (AST.getASTContext().getLangOpts().CPlusPlus)
1971 NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
1974 }
1975
1976 void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
1977 CodeCompletionResult *Results,
1978 unsigned NumResults) override;
1979
1980 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1981 OverloadCandidate *Candidates,
1982 unsigned NumCandidates,
1983 SourceLocation OpenParLoc,
1984 bool Braced) override {
1985 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
1986 OpenParLoc, Braced);
1987 }
1988
1989 CodeCompletionAllocator &getAllocator() override {
1990 return Next.getAllocator();
1991 }
1992
1993 CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
1994 return Next.getCodeCompletionTUInfo();
1995 }
1996 };
1997
1998} // namespace
1999
2000/// Helper function that computes which global names are hidden by the
2001/// local code-completion results.
2003 CodeCompletionResult *Results,
2004 unsigned NumResults,
2005 ASTContext &Ctx,
2006 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
2007 bool OnlyTagNames = false;
2008 switch (Context.getKind()) {
2028 break;
2029
2033 OnlyTagNames = true;
2034 break;
2035
2053 // We're looking for nothing, or we're looking for names that cannot
2054 // be hidden.
2055 return;
2056 }
2057
2059 for (unsigned I = 0; I != NumResults; ++I) {
2060 if (Results[I].Kind != Result::RK_Declaration)
2061 continue;
2062
2063 unsigned IDNS
2064 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
2065
2066 bool Hiding = false;
2067 if (OnlyTagNames)
2068 Hiding = (IDNS & Decl::IDNS_Tag);
2069 else {
2070 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
2073 if (Ctx.getLangOpts().CPlusPlus)
2074 HiddenIDNS |= Decl::IDNS_Tag;
2075 Hiding = (IDNS & HiddenIDNS);
2076 }
2077
2078 if (!Hiding)
2079 continue;
2080
2081 DeclarationName Name = Results[I].Declaration->getDeclName();
2082 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
2083 HiddenNames.insert(Identifier->getName());
2084 else
2085 HiddenNames.insert(Name.getAsString());
2086 }
2087}
2088
2089void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
2090 CodeCompletionContext Context,
2091 CodeCompletionResult *Results,
2092 unsigned NumResults) {
2093 // Merge the results we were given with the results we cached.
2094 bool AddedResult = false;
2095 uint64_t InContexts =
2096 Context.getKind() == CodeCompletionContext::CCC_Recovery
2097 ? NormalContexts : (1LL << Context.getKind());
2098 // Contains the set of names that are hidden by "local" completion results.
2099 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2101 SmallVector<Result, 8> AllResults;
2103 C = AST.cached_completion_begin(),
2104 CEnd = AST.cached_completion_end();
2105 C != CEnd; ++C) {
2106 // If the context we are in matches any of the contexts we are
2107 // interested in, we'll add this result.
2108 if ((C->ShowInContexts & InContexts) == 0)
2109 continue;
2110
2111 // If we haven't added any results previously, do so now.
2112 if (!AddedResult) {
2113 CalculateHiddenNames(Context, Results, NumResults, S.Context,
2114 HiddenNames);
2115 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2116 AddedResult = true;
2117 }
2118
2119 // Determine whether this global completion result is hidden by a local
2120 // completion result. If so, skip it.
2121 if (C->Kind != CXCursor_MacroDefinition &&
2122 HiddenNames.count(C->Completion->getTypedText()))
2123 continue;
2124
2125 // Adjust priority based on similar type classes.
2126 unsigned Priority = C->Priority;
2127 CodeCompletionString *Completion = C->Completion;
2128 if (!Context.getPreferredType().isNull()) {
2129 if (C->Kind == CXCursor_MacroDefinition) {
2130 Priority = getMacroUsagePriority(C->Completion->getTypedText(),
2131 S.getLangOpts(),
2132 Context.getPreferredType()->isAnyPointerType());
2133 } else if (C->Type) {
2136 Context.getPreferredType().getUnqualifiedType());
2138 if (ExpectedSTC == C->TypeClass) {
2139 // We know this type is similar; check for an exact match.
2140 llvm::StringMap<unsigned> &CachedCompletionTypes
2142 llvm::StringMap<unsigned>::iterator Pos
2143 = CachedCompletionTypes.find(QualType(Expected).getAsString());
2144 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
2146 else
2148 }
2149 }
2150 }
2151
2152 // Adjust the completion string, if required.
2153 if (C->Kind == CXCursor_MacroDefinition &&
2154 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
2155 // Create a new code-completion string that just contains the
2156 // macro name, without its arguments.
2157 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
2158 CCP_CodePattern, C->Availability);
2159 Builder.AddTypedTextChunk(C->Completion->getTypedText());
2161 Completion = Builder.TakeString();
2162 }
2163
2164 AllResults.push_back(Result(Completion, Priority, C->Kind,
2165 C->Availability));
2166 }
2167
2168 // If we did not add any cached completion results, just forward the
2169 // results we were given to the next consumer.
2170 if (!AddedResult) {
2171 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2172 return;
2173 }
2174
2175 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2176 AllResults.size());
2177}
2178
2180 StringRef File, unsigned Line, unsigned Column,
2181 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
2182 bool IncludeCodePatterns, bool IncludeBriefComments,
2183 CodeCompleteConsumer &Consumer,
2184 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2185 DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr,
2186 FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
2188 std::unique_ptr<SyntaxOnlyAction> Act) {
2189 if (!Invocation)
2190 return;
2191
2192 SimpleTimer CompletionTimer(WantTiming);
2193 CompletionTimer.setOutput("Code completion @ " + File + ":" +
2194 Twine(Line) + ":" + Twine(Column));
2195
2196 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2197
2198 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2199 CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
2200 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2201
2202 CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2203 CachedCompletionResults.empty();
2204 CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2205 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2206 CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2207 CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
2208 CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
2209
2210 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2211
2212 FrontendOpts.CodeCompletionAt.FileName = std::string(File);
2213 FrontendOpts.CodeCompletionAt.Line = Line;
2214 FrontendOpts.CodeCompletionAt.Column = Column;
2215
2216 // Set the language options appropriately.
2217 LangOpts = CCInvocation->getLangOpts();
2218
2219 // Spell-checking and warnings are wasteful during code-completion.
2220 LangOpts.SpellChecking = false;
2221 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
2222
2223 std::unique_ptr<CompilerInstance> Clang(
2224 new CompilerInstance(PCHContainerOps));
2225
2226 // Recover resources if we crash before exiting this method.
2227 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2228 CICleanup(Clang.get());
2229
2230 auto &Inv = *CCInvocation;
2231 Clang->setInvocation(std::move(CCInvocation));
2232 OriginalSourceFile =
2233 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2234
2235 // Set up diagnostics, capturing any diagnostics produced.
2236 Clang->setDiagnostics(&Diag);
2237 CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
2238 Clang->getDiagnostics(),
2239 &StoredDiagnostics, nullptr);
2240 ProcessWarningOptions(Diag, Inv.getDiagnosticOpts());
2241
2242 // Create the target instance.
2243 if (!Clang->createTarget()) {
2244 Clang->setInvocation(nullptr);
2245 return;
2246 }
2247
2248 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2249 "Invocation must have exactly one source file!");
2250 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2252 "FIXME: AST inputs not yet supported here!");
2253 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2255 "IR inputs not support here!");
2256
2257 // Use the source and file managers that we were given.
2258 Clang->setFileManager(&FileMgr);
2259 Clang->setSourceManager(&SourceMgr);
2260
2261 // Remap files.
2262 PreprocessorOpts.clearRemappedFiles();
2263 PreprocessorOpts.RetainRemappedFileBuffers = true;
2264 for (const auto &RemappedFile : RemappedFiles) {
2265 PreprocessorOpts.addRemappedFile(RemappedFile.first, RemappedFile.second);
2266 OwnedBuffers.push_back(RemappedFile.second);
2267 }
2268
2269 // Use the code completion consumer we were given, but adding any cached
2270 // code-completion results.
2271 AugmentedCodeCompleteConsumer *AugmentedConsumer
2272 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
2273 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2274
2275 auto getUniqueID =
2276 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2277 if (auto Status = FileMgr.getVirtualFileSystem().status(Filename))
2278 return Status->getUniqueID();
2279 return std::nullopt;
2280 };
2281
2282 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2283 if (LHS == RHS)
2284 return true;
2285 if (auto LHSID = getUniqueID(LHS))
2286 if (auto RHSID = getUniqueID(RHS))
2287 return *LHSID == *RHSID;
2288 return false;
2289 };
2290
2291 // If we have a precompiled preamble, try to use it. We only allow
2292 // the use of the precompiled preamble if we're if the completion
2293 // point is within the main file, after the end of the precompiled
2294 // preamble.
2295 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2296 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
2297 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2298 PCHContainerOps, Inv, &FileMgr.getVirtualFileSystem(), false, Line - 1);
2299 }
2300
2301 // If the main file has been overridden due to the use of a preamble,
2302 // make that override happen and introduce the preamble.
2303 if (OverrideMainBuffer) {
2304 assert(Preamble &&
2305 "No preamble was built, but OverrideMainBuffer is not null");
2306
2308 &FileMgr.getVirtualFileSystem();
2309 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2310 OverrideMainBuffer.get());
2311 // FIXME: there is no way to update VFS if it was changed by
2312 // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
2313 // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
2314 // PCH files are always readable.
2315 OwnedBuffers.push_back(OverrideMainBuffer.release());
2316 } else {
2317 PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2318 PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2319 }
2320
2321 // Disable the preprocessing record if modules are not enabled.
2322 if (!Clang->getLangOpts().Modules)
2323 PreprocessorOpts.DetailedRecord = false;
2324
2325 if (!Act)
2326 Act.reset(new SyntaxOnlyAction);
2327
2328 if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
2329 if (llvm::Error Err = Act->Execute()) {
2330 consumeError(std::move(Err)); // FIXME this drops errors on the floor.
2331 }
2332 Act->EndSourceFile();
2333 }
2334}
2335
2336bool ASTUnit::Save(StringRef File) {
2337 if (HadModuleLoaderFatalFailure)
2338 return true;
2339
2340 // FIXME: Can we somehow regenerate the stat cache here, or do we need to
2341 // unconditionally create a stat cache when we parse the file?
2342
2343 if (llvm::Error Err = llvm::writeToOutput(
2344 File, [this](llvm::raw_ostream &Out) {
2345 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2346 "ASTUnit serialization failed",
2347 llvm::inconvertibleErrorCode())
2348 : llvm::Error::success();
2349 })) {
2350 consumeError(std::move(Err));
2351 return true;
2352 }
2353 return false;
2354}
2355
2356static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,
2357 Sema &S, raw_ostream &OS) {
2358 Writer.WriteAST(S, std::string(), nullptr, "");
2359
2360 // Write the generated bitstream to "Out".
2361 if (!Buffer.empty())
2362 OS.write(Buffer.data(), Buffer.size());
2363
2364 return false;
2365}
2366
2367bool ASTUnit::serialize(raw_ostream &OS) {
2368 if (WriterData)
2369 return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS);
2370
2371 SmallString<128> Buffer;
2372 llvm::BitstreamWriter Stream(Buffer);
2373 InMemoryModuleCache ModuleCache;
2374 ASTWriter Writer(Stream, Buffer, ModuleCache, {});
2375 return serializeUnit(Writer, Buffer, getSema(), OS);
2376}
2377
2378void ASTUnit::TranslateStoredDiagnostics(
2379 FileManager &FileMgr,
2380 SourceManager &SrcMgr,
2383 // Map the standalone diagnostic into the new source manager. We also need to
2384 // remap all the locations to the new view. This includes the diag location,
2385 // any associated source ranges, and the source ranges of associated fix-its.
2386 // FIXME: There should be a cleaner way to do this.
2388 Result.reserve(Diags.size());
2389
2390 for (const auto &SD : Diags) {
2391 // Rebuild the StoredDiagnostic.
2392 if (SD.Filename.empty())
2393 continue;
2394 auto FE = FileMgr.getFile(SD.Filename);
2395 if (!FE)
2396 continue;
2397 SourceLocation FileLoc;
2398 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2399 if (ItFileID == PreambleSrcLocCache.end()) {
2400 FileID FID = SrcMgr.translateFile(*FE);
2401 FileLoc = SrcMgr.getLocForStartOfFile(FID);
2402 PreambleSrcLocCache[SD.Filename] = FileLoc;
2403 } else {
2404 FileLoc = ItFileID->getValue();
2405 }
2406
2407 if (FileLoc.isInvalid())
2408 continue;
2409 SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
2410 FullSourceLoc Loc(L, SrcMgr);
2411
2413 Ranges.reserve(SD.Ranges.size());
2414 for (const auto &Range : SD.Ranges) {
2415 SourceLocation BL = FileLoc.getLocWithOffset(Range.first);
2416 SourceLocation EL = FileLoc.getLocWithOffset(Range.second);
2417 Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
2418 }
2419
2421 FixIts.reserve(SD.FixIts.size());
2422 for (const auto &FixIt : SD.FixIts) {
2423 FixIts.push_back(FixItHint());
2424 FixItHint &FH = FixIts.back();
2425 FH.CodeToInsert = FixIt.CodeToInsert;
2426 SourceLocation BL = FileLoc.getLocWithOffset(FixIt.RemoveRange.first);
2427 SourceLocation EL = FileLoc.getLocWithOffset(FixIt.RemoveRange.second);
2429 }
2430
2431 Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
2432 SD.Message, Loc, Ranges, FixIts));
2433 }
2434 Result.swap(Out);
2435}
2436
2438 assert(D);
2439
2440 // We only care about local declarations.
2441 if (D->isFromASTFile())
2442 return;
2443
2444 SourceManager &SM = *SourceMgr;
2446 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2447 return;
2448
2449 // We only keep track of the file-level declarations of each file.
2451 return;
2452
2453 SourceLocation FileLoc = SM.getFileLoc(Loc);
2454 assert(SM.isLocalSourceLocation(FileLoc));
2455 FileID FID;
2456 unsigned Offset;
2457 std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
2458 if (FID.isInvalid())
2459 return;
2460
2461 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2462 if (!Decls)
2463 Decls = std::make_unique<LocDeclsTy>();
2464
2465 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2466
2467 if (Decls->empty() || Decls->back().first <= Offset) {
2468 Decls->push_back(LocDecl);
2469 return;
2470 }
2471
2472 LocDeclsTy::iterator I =
2473 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2474
2475 Decls->insert(I, LocDecl);
2476}
2477
2478void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2479 SmallVectorImpl<Decl *> &Decls) {
2480 if (File.isInvalid())
2481 return;
2482
2483 if (SourceMgr->isLoadedFileID(File)) {
2484 assert(Ctx->getExternalSource() && "No external source!");
2485 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2486 Decls);
2487 }
2488
2489 FileDeclsTy::iterator I = FileDecls.find(File);
2490 if (I == FileDecls.end())
2491 return;
2492
2493 LocDeclsTy &LocDecls = *I->second;
2494 if (LocDecls.empty())
2495 return;
2496
2497 LocDeclsTy::iterator BeginIt =
2498 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2499 return LD.first < Offset;
2500 });
2501 if (BeginIt != LocDecls.begin())
2502 --BeginIt;
2503
2504 // If we are pointing at a top-level decl inside an objc container, we need
2505 // to backtrack until we find it otherwise we will fail to report that the
2506 // region overlaps with an objc container.
2507 while (BeginIt != LocDecls.begin() &&
2508 BeginIt->second->isTopLevelDeclInObjCContainer())
2509 --BeginIt;
2510
2511 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2512 LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),
2513 llvm::less_first());
2514 if (EndIt != LocDecls.end())
2515 ++EndIt;
2516
2517 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2518 Decls.push_back(DIt->second);
2519}
2520
2522 unsigned Line, unsigned Col) const {
2524 SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);
2525 return SM.getMacroArgExpandedLocation(Loc);
2526}
2527
2529 unsigned Offset) const {
2531 SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);
2532 return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
2533}
2534
2535/// If \arg Loc is a loaded location from the preamble, returns
2536/// the corresponding local location of the main file, otherwise it returns
2537/// \arg Loc.
2539 FileID PreambleID;
2540 if (SourceMgr)
2541 PreambleID = SourceMgr->getPreambleFileID();
2542
2543 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2544 return Loc;
2545
2546 unsigned Offs;
2547 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2548 SourceLocation FileLoc
2549 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2550 return FileLoc.getLocWithOffset(Offs);
2551 }
2552
2553 return Loc;
2554}
2555
2556/// If \arg Loc is a local location of the main file but inside the
2557/// preamble chunk, returns the corresponding loaded location from the
2558/// preamble, otherwise it returns \arg Loc.
2560 FileID PreambleID;
2561 if (SourceMgr)
2562 PreambleID = SourceMgr->getPreambleFileID();
2563
2564 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2565 return Loc;
2566
2567 unsigned Offs;
2568 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2569 Offs < Preamble->getBounds().Size) {
2570 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2571 return FileLoc.getLocWithOffset(Offs);
2572 }
2573
2574 return Loc;
2575}
2576
2578 FileID FID;
2579 if (SourceMgr)
2580 FID = SourceMgr->getPreambleFileID();
2581
2582 if (Loc.isInvalid() || FID.isInvalid())
2583 return false;
2584
2585 return SourceMgr->isInFileID(Loc, FID);
2586}
2587
2589 FileID FID;
2590 if (SourceMgr)
2591 FID = SourceMgr->getMainFileID();
2592
2593 if (Loc.isInvalid() || FID.isInvalid())
2594 return false;
2595
2596 return SourceMgr->isInFileID(Loc, FID);
2597}
2598
2600 FileID FID;
2601 if (SourceMgr)
2602 FID = SourceMgr->getPreambleFileID();
2603
2604 if (FID.isInvalid())
2605 return {};
2606
2607 return SourceMgr->getLocForEndOfFile(FID);
2608}
2609
2611 FileID FID;
2612 if (SourceMgr)
2613 FID = SourceMgr->getMainFileID();
2614
2615 if (FID.isInvalid())
2616 return {};
2617
2618 return SourceMgr->getLocForStartOfFile(FID);
2619}
2620
2621llvm::iterator_range<PreprocessingRecord::iterator>
2623 if (isMainFileAST()) {
2625 Mod = Reader->getModuleManager().getPrimaryModule();
2626 return Reader->getModulePreprocessedEntities(Mod);
2627 }
2628
2630 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2631
2632 return llvm::make_range(PreprocessingRecord::iterator(),
2634}
2635
2637 if (isMainFileAST()) {
2639 Mod = Reader->getModuleManager().getPrimaryModule();
2640 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2641 if (!Fn(context, D))
2642 return false;
2643 }
2644
2645 return true;
2646 }
2647
2649 TLEnd = top_level_end();
2650 TL != TLEnd; ++TL) {
2651 if (!Fn(context, *TL))
2652 return false;
2653 }
2654
2655 return true;
2656}
2657
2659 if (!Reader)
2660 return std::nullopt;
2661
2662 serialization::ModuleFile *Mod = nullptr;
2663 Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
2664 switch (M.Kind) {
2665 case serialization::MK_ImplicitModule:
2666 case serialization::MK_ExplicitModule:
2667 case serialization::MK_PrebuiltModule:
2668 return true; // skip dependencies.
2669 case serialization::MK_PCH:
2670 Mod = &M;
2671 return true; // found it.
2672 case serialization::MK_Preamble:
2673 return false; // look in dependencies.
2674 case serialization::MK_MainFile:
2675 return false; // look in dependencies.
2676 }
2677
2678 return true;
2679 });
2680 if (Mod)
2681 return Mod->File;
2682
2683 return std::nullopt;
2684}
2685
2688}
2689
2691 auto &LangOpts = getLangOpts();
2692
2693 Language Lang;
2694 if (LangOpts.OpenCL)
2695 Lang = Language::OpenCL;
2696 else if (LangOpts.CUDA)
2697 Lang = Language::CUDA;
2698 else if (LangOpts.RenderScript)
2700 else if (LangOpts.CPlusPlus)
2701 Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
2702 else
2703 Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
2704
2706 if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
2708
2709 // We don't know if input was preprocessed. Assume not.
2710 bool PP = false;
2711
2712 return InputKind(Lang, Fmt, PP);
2713}
2714
2715#ifndef NDEBUG
2716ASTUnit::ConcurrencyState::ConcurrencyState() {
2717 Mutex = new std::recursive_mutex;
2718}
2719
2720ASTUnit::ConcurrencyState::~ConcurrencyState() {
2721 delete static_cast<std::recursive_mutex *>(Mutex);
2722}
2723
2724void ASTUnit::ConcurrencyState::start() {
2725 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
2726 assert(acquired && "Concurrent access to ASTUnit!");
2727}
2728
2729void ASTUnit::ConcurrencyState::finish() {
2730 static_cast<std::recursive_mutex *>(Mutex)->unlock();
2731}
2732
2733#else // NDEBUG
2734
2735ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
2736ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2737void ASTUnit::ConcurrencyState::start() {}
2738void ASTUnit::ConcurrencyState::finish() {}
2739
2740#endif // NDEBUG
Defines the clang::ASTContext interface.
static void checkAndSanitizeDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiagnostics, SourceManager &SM)
Definition: ASTUnit.cpp:1122
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:2002
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:941
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:1274
static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl< char > &Buffer, Sema &S, raw_ostream &OS)
Definition: ASTUnit.cpp:2356
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:1116
static bool isInMainFile(const clang::Diagnostic &D)
Definition: ASTUnit.cpp:722
static ASTUnit::StandaloneDiagnostic makeStandaloneDiagnostic(const LangOptions &LangOpts, const StoredDiagnostic &InDiag)
Definition: ASTUnit.cpp:1295
static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag)
Definition: ASTUnit.cpp:1111
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:1282
static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash)
Add the given macro to the hash of all top-level entities.
Definition: ASTUnit.cpp:918
#define SM(sm)
Definition: Cuda.cpp:84
Defines the Diagnostic-related interfaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::FileManager interface and associated types.
int Priority
Definition: Format.cpp:2980
StringRef Filename
Definition: Format.cpp:2976
StringRef Identifier
Definition: Format.cpp:2984
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
#define X(type, name)
Definition: Value.h:143
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Definition: MachO.h:51
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
This file declares facilities that support code completion.
SourceRange Range
Definition: SemaObjC.cpp:757
SourceLocation Loc
Definition: SemaObjC.cpp:758
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines the clang::TargetOptions class.
Allows QualTypes to be sorted and hence used in maps and sets.
C Language Family Type Representation.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Definition: ASTConsumer.h:33
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
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:2593
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:939
const LangOptions & getLangOpts() const
Definition: ASTContext.h:778
void setPrintingPolicy(const clang::PrintingPolicy &Policy)
Definition: ASTContext.h:704
Abstract base class to use for AST consumer-based frontend actions.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Abstract interface for callback invocations by the ASTReader.
Definition: ASTReader.h:114
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:366
@ ARR_None
The client can't handle any AST loading failures.
Definition: ASTReader.h:1611
@ Success
The control block was read successfully.
Definition: ASTReader.h:388
@ ConfigurationMismatch
The AST file was written with a different language/target configuration.
Definition: ASTReader.h:405
@ OutOfDate
The AST file is out-of-date relative to its input files, and needs to be regenerated.
Definition: ASTReader.h:398
@ Failure
The AST file itself appears corrupted.
Definition: ASTReader.h:391
@ VersionMismatch
The AST file was written by a different version of Clang.
Definition: ASTReader.h:401
@ HadErrors
The AST file has errors.
Definition: ASTReader.h:408
@ Missing
The AST file was missing.
Definition: ASTReader.h:394
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:2437
const FileManager & getFileManager() const
Definition: ASTUnit.h:479
static std::unique_ptr< ASTUnit > LoadFromCommandLine(const char **ArgBegin, const char **ArgEnd, std::shared_ptr< PCHContainerOperations > PCHContainerOps, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, StringRef ResourceFilesPath, bool StorePreamblesInMemory=false, StringRef PreambleStoragePath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, ArrayRef< RemappedFile > RemappedFiles=std::nullopt, bool RemappedFilesKeepOriginalName=true, unsigned PrecompilePreambleAfterNParses=0, TranslationUnitKind TUKind=TU_Complete, bool CacheCodeCompletionResults=false, bool IncludeBriefCommentsInCodeCompletion=false, bool AllowPCHWithCompilerErrors=false, SkipFunctionBodiesScope SkipFunctionBodies=SkipFunctionBodiesScope::None, bool SingleFileParse=false, bool UserFilesAreVolatile=false, bool ForSerialization=false, bool RetainExcludedConditionalBlocks=false, std::optional< StringRef > ModuleFormat=std::nullopt, std::unique_ptr< ASTUnit > *ErrAST=nullptr, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
LoadFromCommandLine - Create an ASTUnit from a vector of command line arguments, which must specify e...
Definition: ASTUnit.cpp:1758
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:2179
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:2367
ASTDeserializationListener * getDeserializationListener()
Definition: ASTUnit.cpp:772
bool Reparse(std::shared_ptr< PCHContainerOperations > PCHContainerOps, ArrayRef< RemappedFile > RemappedFiles=std::nullopt, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Reparse the source files using the same command-line options that were originally used to produce thi...
Definition: ASTUnit.cpp:1864
std::unique_ptr< llvm::MemoryBuffer > getBufferForFile(StringRef Filename, std::string *ErrorStr=nullptr)
Definition: ASTUnit.cpp:779
llvm::StringMap< unsigned > & getCachedCompletionTypes()
Retrieve the mapping from formatted type names to unique type identifiers.
Definition: ASTUnit.h:308
const DiagnosticsEngine & getDiagnostics() const
Definition: ASTUnit.h:432
SourceLocation getLocation(const FileEntry *File, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
Definition: ASTUnit.cpp:2521
void ResetForParse()
Free data that will be re-generated on the next parse.
Definition: ASTUnit.cpp:1922
InputKind getInputKind() const
Determine the input kind this AST unit represents.
Definition: ASTUnit.cpp:2690
OptionalFileEntryRef getPCHFile()
Get the PCH file if one was included.
Definition: ASTUnit.cpp:2658
StringRef getMainFileName() const
Definition: ASTUnit.cpp:1502
Sema & getSema() const
Definition: ASTUnit.h:459
SourceLocation mapLocationToPreamble(SourceLocation Loc) const
If Loc is a local location of the main file but inside the preamble chunk, returns the corresponding ...
Definition: ASTUnit.cpp:2559
cached_completion_iterator cached_completion_begin()
Definition: ASTUnit.h:619
const LangOptions & getLangOpts() const
Definition: ASTUnit.h:464
bool isMainFileAST() const
Definition: ASTUnit.h:427
std::vector< Decl * >::iterator top_level_iterator
Definition: ASTUnit.h:503
const SourceManager & getSourceManager() const
Definition: ASTUnit.h:435
SourceLocation getEndOfPreambleFileID() const
Definition: ASTUnit.cpp:2599
@ LoadASTOnly
Load the AST, but do not restore Sema state.
Definition: ASTUnit.h:678
@ LoadEverything
Load everything, including Sema.
Definition: ASTUnit.h:681
top_level_iterator top_level_end()
Definition: ASTUnit.h:512
SourceLocation getStartOfMainFileID() const
Definition: ASTUnit.cpp:2610
IntrusiveRefCntPtr< ASTReader > getASTReader() const
Definition: ASTUnit.cpp:762
bool(*)(void *context, const Decl *D) DeclVisitorFn
Type for a function iterating over a number of declarations.
Definition: ASTUnit.h:639
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn)
Iterate over local declarations (locally parsed if this is a parsed source file or the loaded declara...
Definition: ASTUnit.cpp:2636
llvm::iterator_range< PreprocessingRecord::iterator > getLocalPreprocessingEntities() const
Returns an iterator range for the local preprocessing entities of the local Preprocessor,...
Definition: ASTUnit.cpp:2622
top_level_iterator top_level_begin()
Definition: ASTUnit.h:505
std::vector< CachedCodeCompletionResult >::iterator cached_completion_iterator
Definition: ASTUnit.h:617
ASTMutationListener * getASTMutationListener()
Definition: ASTUnit.cpp:766
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:1520
bool Save(StringRef File)
Save this translation unit to a file with the given name.
Definition: ASTUnit.cpp:2336
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:1530
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:1550
bool isInMainFileID(SourceLocation Loc) const
Definition: ASTUnit.cpp:2588
bool isModuleFile() const
Returns true if the ASTUnit was constructed from a serialized module file.
Definition: ASTUnit.cpp:2686
void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, SmallVectorImpl< Decl * > &Decls)
Get the decls that are contained in a file in the Offset/Length range.
Definition: ASTUnit.cpp:2478
const ASTContext & getASTContext() const
Definition: ASTUnit.h:442
bool isInPreambleFileID(SourceLocation Loc) const
Definition: ASTUnit.cpp:2577
SourceLocation mapLocationFromPreamble(SourceLocation Loc) const
If Loc is a loaded location from the preamble, returns the corresponding local location of the main f...
Definition: ASTUnit.cpp:2538
std::pair< std::string, llvm::MemoryBuffer * > RemappedFile
A mapping from a file name to the memory buffer that stores the remapped contents of that file.
Definition: ASTUnit.h:665
static std::unique_ptr< ASTUnit > LoadFromASTFile(const std::string &Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, std::shared_ptr< HeaderSearchOptions > HSOpts, std::shared_ptr< LangOptions > LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=llvm::vfs::getRealFileSystem())
Create a ASTUnit from an AST file.
Definition: ASTUnit.cpp:800
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:89
ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile, Module *WritingModule, StringRef isysroot, bool ShouldCacheASTInMemory=false)
Write a precompiled header for the given semantic analysis.
Definition: ASTWriter.cpp:4857
LocalDeclID getDeclID(const Decl *D)
Determine the local declaration ID of an already-emitted declaration.
Definition: ASTWriter.cpp:6246
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:2136
bool isTranslationUnit() const
Definition: DeclBase.h:2141
DeclContext * getLookupParent()
Find the parent context of this context that will be used for unqualified name lookup.
Definition: DeclBase.cpp:1264
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:783
SourceLocation getLocation() const
Definition: DeclBase.h:445
@ IDNS_NonMemberOperator
This declaration is a C++ operator declared in a non-class context.
Definition: DeclBase.h:168
@ IDNS_Ordinary
Ordinary names.
Definition: DeclBase.h:144
@ IDNS_Type
Types, declared with 'struct foo', typedefs, etc.
Definition: DeclBase.h:130
@ IDNS_Member
Members, declared with object declarations within tag definitions.
Definition: DeclBase.h:136
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
Definition: DeclBase.h:140
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
Definition: DeclBase.h:125
DeclContext * getDeclContext()
Definition: DeclBase.h:454
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:907
The name of a declaration.
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Definition: Diagnostic.h:1745
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
Definition: Diagnostic.h:1777
virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info)
Handle this diagnostic, reporting it to the user or capturing it to a log as needed.
Definition: Diagnostic.cpp:561
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
Definition: Diagnostic.h:1769
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine) ...
Definition: Diagnostic.h:1571
const SourceLocation & getLocation() const
Definition: Diagnostic.h:1582
SourceManager & getSourceManager() const
Definition: Diagnostic.h:1584
bool hasSourceManager() const
Definition: Diagnostic.h:1583
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
void setNumWarnings(unsigned NumWarnings)
Definition: Diagnostic.h:860
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
Definition: Diagnostic.cpp:96
std::unique_ptr< DiagnosticConsumer > takeClient()
Return the current diagnostic client along with ownership of that client.
Definition: Diagnostic.h:580
Level
The level of the diagnostic, after it has been through mapping.
Definition: Diagnostic.h:195
DiagnosticConsumer * getClient()
Definition: Diagnostic.h:572
unsigned getNumWarnings() const
Definition: Diagnostic.h:858
void Reset(bool soft=false)
Reset the state of the diagnostic object to its initial configuration.
Definition: Diagnostic.cpp:118
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:300
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isInvalid() const
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
llvm::vfs::FileSystem & getVirtualFileSystem() const
Definition: FileManager.h:251
FileSystemOptions & getFileSystemOpts()
Returns the current file system options.
Definition: FileManager.h:248
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
Definition: FileManager.h:253
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Definition: FileManager.h:261
Keeps track of options that affect how file operations are performed.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
Definition: Diagnostic.h:71
bool BeforePreviousInsertions
Definition: Diagnostic.h:85
CharSourceRange RemoveRange
Code that should be replaced to correct the error.
Definition: Diagnostic.h:75
CharSourceRange InsertFromRange
Code in the specific range that should be inserted in the insertion location.
Definition: Diagnostic.h:79
std::string CodeToInsert
The actual code to insert at the insertion location, as a string.
Definition: Diagnostic.h:83
Abstract base class for actions which can be performed by the frontend.
virtual void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
llvm::Error Execute()
Set the source manager's main input file, and run the action.
virtual TranslationUnitKind getTranslationUnitKind()
For AST-based actions, the kind of translation unit we're handling.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
An input file for the front end.
llvm::MemoryBufferRef getBuffer() const
StringRef getFile() const
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned SkipFunctionBodies
Skip over function bodies to speed up parsing in cases you do not need them (e.g.
CodeCompleteOptions CodeCompleteOpts
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
A SourceLocation and its associated SourceManager.
const SourceManager & getManager() const
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
std::vector< SystemHeaderPrefix > SystemHeaderPrefixes
User-specified system header prefixes.
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
std::vector< Entry > UserEntries
User specified include entries.
std::string ResourceDir
The directory which holds the compiler resource files (builtin includes, etc.).
Encapsulates the information needed to find the file referenced by a #include or #include_next,...
Definition: HeaderSearch.h:249
Module * lookupModule(StringRef ModuleName, SourceLocation ImportLoc=SourceLocation(), bool AllowSearch=true, bool AllowExtraModuleMapSearch=false)
Lookup a module Search for a module with the given name.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
In-memory cache for modules.
The kind of a file that we've been handed as an input.
Format
The input file format.
@ CMK_ModuleMap
Compiling a module from a module map.
Definition: LangOptions.h:102
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:461
CommentOptions CommentOpts
Options for parsing comments.
Definition: LangOptions.h:525
bool isCompilingModule() const
Are we compiling a module?
Definition: LangOptions.h:602
static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Accepts a range and returns a character range with file locations.
Definition: Lexer.cpp:955
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition: MacroInfo.h:313
Describes a module or submodule.
Definition: Module.h:105
bool isNamedModule() const
Does this Module is a named module of a standard named module?
Definition: Module.h:185
This represents a decl that may have a name.
Definition: Decl.h:249
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:462
This abstract interface provides operations for unwrapping containers for serialized ASTs (precompile...
virtual llvm::ArrayRef< llvm::StringRef > getFormats() const =0
Equivalent to the format passed to -fmodule-format=.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition: PPCallbacks.h:36
A set of callbacks to gather useful information while building a preamble.
static llvm::ErrorOr< PrecompiledPreamble > Build(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, bool StoreInMemory, StringRef StoragePath, PreambleCallbacks &Callbacks)
Try to build PrecompiledPreamble for Invocation.
Iteration over the preprocessed entities.
A record of the steps taken while preprocessing a source file, including the various preprocessing di...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
bool RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
bool SingleFileParseMode
When enabled, preprocessor is in a mode for parsing a single file only.
bool DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
bool RetainExcludedConditionalBlocks
When enabled, excluded conditional blocks retain in the main file.
void addRemappedFile(StringRef From, StringRef To)
bool AllowPCHWithCompilerErrors
When true, a PCH with compiler errors will not be rejected.
std::vector< std::pair< std::string, llvm::MemoryBuffer * > > RemappedFileBuffers
The set of file-to-buffer remappings, which take existing files on the system (the first part of each...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:137
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
SourceManager & getSourceManager() const
FileManager & getFileManager() const
void Initialize(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)
Initialize the preprocessor using information about the target.
IdentifierTable & getIdentifierTable()
Builtin::Context & getBuiltinInfo()
const LangOptions & getLangOpts() const
void setCounterValue(unsigned V)
PreprocessingRecord * getPreprocessingRecord() const
Retrieve the preprocessing record, or NULL if there is no preprocessing record.
DiagnosticsEngine & getDiagnostics() const
SelectorTable & getSelectorTable()
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7469
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1341
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:478
ASTContext & Context
Definition: Sema.h:873
const LangOptions & getLangOpts() const
Definition: Sema.h:535
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
SourceLocation getLocForEndOfFile(FileID FID) const
Return the source location corresponding to the last byte of the specified file.
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const
Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...
FileID getPreambleFileID() const
Get the file ID for the precompiled preamble if there is one.
bool isLoadedFileID(FileID FID) const
Returns true if FID came from a PCH/Module.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
Represents a diagnostic in a form that can be retained until its corresponding source manager is dest...
Definition: Diagnostic.h:1695
unsigned getID() const
Definition: Diagnostic.h:1716
ArrayRef< FixItHint > getFixIts() const
Definition: Diagnostic.h:1737
ArrayRef< CharSourceRange > getRanges() const
Definition: Diagnostic.h:1729
DiagnosticsEngine::Level getLevel() const
Definition: Diagnostic.h:1717
const FullSourceLoc & getLocation() const
Definition: Diagnostic.h:1718
StringRef getMessage() const
Definition: Diagnostic.h:1719
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
Definition: Targets.cpp:764
Options for controlling the target.
Definition: TargetOptions.h:26
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:187
void registerCommentOptions(const CommentOptions &CommentOptions)
Information about a module that has been loaded by the ASTReader.
Definition: ModuleFile.h:124
FileEntryRef File
The file entry for the module file.
Definition: ModuleFile.h:179
std::string FileName
The file name of the module file.
Definition: ModuleFile.h:139
ModuleKind Kind
The type of this module.
Definition: ModuleFile.h:136
@ CXCursor_MacroDefinition
Definition: Index.h:2220
Defines the clang::TargetInfo interface.
@ FixIt
Parse and apply any fixits to the source.
@ MK_MainFile
File is a PCH file treated as the actual main file.
Definition: ModuleFile.h:56
@ VFS
Remove unused -ivfsoverlay arguments.
The JSON file list parser is used to communicate input to InstallAPI.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromOverlayFiles(ArrayRef< std::string > VFSOverlayFiles, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)
QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND)
Determine the type that this declaration will have if it is used as a type or in an expression.
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
Definition: Warnings.cpp:44
SkipFunctionBodiesScope
Enumerates the available scopes for skipping function bodies.
Definition: ASTUnit.h:83
std::unique_ptr< CompilerInvocation > createInvocation(ArrayRef< const char * > Args, CreateInvocationOptions Opts={})
Interpret clang arguments in preparation to parse a file.
Language
The language for the input, used to select and validate the language standard and possible actions.
Definition: LangStandard.h:23
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
SimplifiedTypeClass
A simplified classification of types used when determining "similar" types for code completion.
CaptureDiagsKind
Enumerates the available kinds for capturing diagnostics.
Definition: ASTUnit.h:86
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
@ CCF_ExactTypeMatch
Divide by this factor when a code-completion result's type exactly matches the type we expect.
@ CCF_SimilarTypeMatch
Divide by this factor when a code-completion result's type is similar to the type we expect (e....
TranslationUnitKind
Describes the kind of translation unit being processed.
Definition: LangOptions.h:1033
@ TU_Complete
The translation unit is a complete translation unit.
Definition: LangOptions.h:1035
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:848
Describes the bounds (start, size) of the preamble and a flag required by PreprocessorOptions::Precom...
Definition: Lexer.h:60
unsigned Size
Size of the preamble in bytes.
Definition: Lexer.h:62
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57