Thanks to visit codestin.com
Credit goes to clang.llvm.org

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