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