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