brintos

brintos / llvm-project-archived public Read only

0
0
Text · 90.1 KiB · e72317d Raw
2526 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// ASTUnit Implementation.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Frontend/ASTUnit.h"14#include "clang/AST/ASTConsumer.h"15#include "clang/AST/ASTContext.h"16#include "clang/AST/CommentCommandTraits.h"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"22#include "clang/AST/DeclTemplate.h"23#include "clang/AST/DeclarationName.h"24#include "clang/AST/ExternalASTSource.h"25#include "clang/AST/PrettyPrinter.h"26#include "clang/AST/Type.h"27#include "clang/AST/TypeOrdering.h"28#include "clang/Basic/Diagnostic.h"29#include "clang/Basic/DiagnosticFrontend.h"30#include "clang/Basic/FileManager.h"31#include "clang/Basic/IdentifierTable.h"32#include "clang/Basic/LLVM.h"33#include "clang/Basic/LangOptions.h"34#include "clang/Basic/LangStandard.h"35#include "clang/Basic/Module.h"36#include "clang/Basic/SourceLocation.h"37#include "clang/Basic/SourceManager.h"38#include "clang/Basic/TargetInfo.h"39#include "clang/Basic/TargetOptions.h"40#include "clang/Frontend/CompilerInstance.h"41#include "clang/Frontend/CompilerInvocation.h"42#include "clang/Frontend/FrontendAction.h"43#include "clang/Frontend/FrontendActions.h"44#include "clang/Frontend/FrontendOptions.h"45#include "clang/Frontend/MultiplexConsumer.h"46#include "clang/Frontend/PrecompiledPreamble.h"47#include "clang/Frontend/StandaloneDiagnostic.h"48#include "clang/Frontend/Utils.h"49#include "clang/Lex/HeaderSearch.h"50#include "clang/Lex/HeaderSearchOptions.h"51#include "clang/Lex/Lexer.h"52#include "clang/Lex/PPCallbacks.h"53#include "clang/Lex/PreprocessingRecord.h"54#include "clang/Lex/Preprocessor.h"55#include "clang/Lex/PreprocessorOptions.h"56#include "clang/Lex/Token.h"57#include "clang/Sema/CodeCompleteConsumer.h"58#include "clang/Sema/CodeCompleteOptions.h"59#include "clang/Sema/Sema.h"60#include "clang/Sema/SemaCodeCompletion.h"61#include "clang/Serialization/ASTReader.h"62#include "clang/Serialization/ASTWriter.h"63#include "clang/Serialization/ModuleCache.h"64#include "clang/Serialization/ModuleFile.h"65#include "clang/Serialization/PCHContainerOperations.h"66#include "llvm/ADT/ArrayRef.h"67#include "llvm/ADT/DenseMap.h"68#include "llvm/ADT/IntrusiveRefCntPtr.h"69#include "llvm/ADT/STLExtras.h"70#include "llvm/ADT/ScopeExit.h"71#include "llvm/ADT/SmallVector.h"72#include "llvm/ADT/StringMap.h"73#include "llvm/ADT/StringRef.h"74#include "llvm/ADT/StringSet.h"75#include "llvm/ADT/Twine.h"76#include "llvm/ADT/iterator_range.h"77#include "llvm/Bitstream/BitstreamWriter.h"78#include "llvm/Support/Allocator.h"79#include "llvm/Support/CrashRecoveryContext.h"80#include "llvm/Support/DJB.h"81#include "llvm/Support/ErrorHandling.h"82#include "llvm/Support/ErrorOr.h"83#include "llvm/Support/MemoryBuffer.h"84#include "llvm/Support/SaveAndRestore.h"85#include "llvm/Support/Timer.h"86#include "llvm/Support/VirtualFileSystem.h"87#include "llvm/Support/raw_ostream.h"88#include <algorithm>89#include <atomic>90#include <cassert>91#include <cstdint>92#include <cstdio>93#include <cstdlib>94#include <memory>95#include <mutex>96#include <optional>97#include <string>98#include <tuple>99#include <utility>100#include <vector>101 102using namespace clang;103 104using llvm::TimeRecord;105 106namespace {107 108  class SimpleTimer {109    bool WantTiming;110    TimeRecord Start;111    std::string Output;112 113  public:114    explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {115      if (WantTiming)116        Start = TimeRecord::getCurrentTime();117    }118 119    ~SimpleTimer() {120      if (WantTiming) {121        TimeRecord Elapsed = TimeRecord::getCurrentTime();122        Elapsed -= Start;123        llvm::errs() << Output << ':';124        Elapsed.print(Elapsed, llvm::errs());125        llvm::errs() << '\n';126      }127    }128 129    void setOutput(const Twine &Output) {130      if (WantTiming)131        this->Output = Output.str();132    }133  };134 135} // namespace136 137template <class T>138static std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {139  if (!Val)140    return nullptr;141  return std::move(*Val);142}143 144template <class T>145static bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {146  if (!Val)147    return false;148  Output = std::move(*Val);149  return true;150}151 152/// Get a source buffer for \p MainFilePath, handling all file-to-file153/// and file-to-buffer remappings inside \p Invocation.154static std::unique_ptr<llvm::MemoryBuffer>155getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,156                                  llvm::vfs::FileSystem *VFS,157                                  StringRef FilePath, bool isVolatile) {158  const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();159 160  // Try to determine if the main file has been remapped, either from the161  // command line (to another file) or directly through the compiler162  // invocation (to a memory buffer).163  llvm::MemoryBuffer *Buffer = nullptr;164  std::unique_ptr<llvm::MemoryBuffer> BufferOwner;165  auto FileStatus = VFS->status(FilePath);166  if (FileStatus) {167    llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();168 169    // Check whether there is a file-file remapping of the main file170    for (const auto &RF : PreprocessorOpts.RemappedFiles) {171      std::string MPath(RF.first);172      auto MPathStatus = VFS->status(MPath);173      if (MPathStatus) {174        llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();175        if (MainFileID == MID) {176          // We found a remapping. Try to load the resulting, remapped source.177          BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second, -1, true, isVolatile));178          if (!BufferOwner)179            return nullptr;180        }181      }182    }183 184    // Check whether there is a file-buffer remapping. It supercedes the185    // file-file remapping.186    for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {187      std::string MPath(RB.first);188      auto MPathStatus = VFS->status(MPath);189      if (MPathStatus) {190        llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();191        if (MainFileID == MID) {192          // We found a remapping.193          BufferOwner.reset();194          Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);195        }196      }197    }198  }199 200  // If the main source file was not remapped, load it now.201  if (!Buffer && !BufferOwner) {202    BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));203    if (!BufferOwner)204      return nullptr;205  }206 207  if (BufferOwner)208    return BufferOwner;209  if (!Buffer)210    return nullptr;211  return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);212}213 214void ASTUnit::clearFileLevelDecls() {215  FileDecls.clear();216}217 218/// After failing to build a precompiled preamble (due to219/// errors in the source that occurs in the preamble), the number of220/// reparses during which we'll skip even trying to precompile the221/// preamble.222const unsigned DefaultPreambleRebuildInterval = 5;223 224/// Tracks the number of ASTUnit objects that are currently active.225///226/// Used for debugging purposes only.227static std::atomic<unsigned> ActiveASTUnitObjects;228 229ASTUnit::ASTUnit(bool _MainFileIsAST)230    : CodeGenOpts(std::make_unique<CodeGenOptions>()),231      MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),232      ShouldCacheCodeCompletionResults(false),233      IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),234      UnsafeToFree(false) {235  if (getenv("LIBCLANG_OBJTRACKING"))236    fprintf(stderr, "+++ %u translation units\n", ++ActiveASTUnitObjects);237}238 239ASTUnit::~ASTUnit() {240  // If we loaded from an AST file, balance out the BeginSourceFile call.241  if (MainFileIsAST && getDiagnostics().getClient()) {242    getDiagnostics().getClient()->EndSourceFile();243  }244 245  clearFileLevelDecls();246 247  // Free the buffers associated with remapped files. We are required to248  // perform this operation here because we explicitly request that the249  // compiler instance *not* free these buffers for each invocation of the250  // parser.251  if (Invocation && OwnsRemappedFileBuffers) {252    PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();253    for (const auto &RB : PPOpts.RemappedFileBuffers)254      delete RB.second;255  }256 257  ClearCachedCompletionResults();258 259  if (getenv("LIBCLANG_OBJTRACKING"))260    fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects);261}262 263void ASTUnit::setPreprocessor(std::shared_ptr<Preprocessor> PP) {264  this->PP = std::move(PP);265}266 267void ASTUnit::enableSourceFileDiagnostics() {268  assert(getDiagnostics().getClient() && Ctx &&269      "Bad context for source file");270  getDiagnostics().getClient()->BeginSourceFile(Ctx->getLangOpts(), PP.get());271}272 273/// Determine the set of code-completion contexts in which this274/// declaration should be shown.275static uint64_t getDeclShowContexts(const NamedDecl *ND,276                                    const LangOptions &LangOpts,277                                    bool &IsNestedNameSpecifier) {278  IsNestedNameSpecifier = false;279 280  if (isa<UsingShadowDecl>(ND))281    ND = ND->getUnderlyingDecl();282  if (!ND)283    return 0;284 285  uint64_t Contexts = 0;286  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||287      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) ||288      isa<TypeAliasTemplateDecl>(ND)) {289    // Types can appear in these contexts.290    if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))291      Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)292               |  (1LL << CodeCompletionContext::CCC_ObjCIvarList)293               |  (1LL << CodeCompletionContext::CCC_ClassStructUnion)294               |  (1LL << CodeCompletionContext::CCC_Statement)295               |  (1LL << CodeCompletionContext::CCC_Type)296               |  (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);297 298    // In C++, types can appear in expressions contexts (for functional casts).299    if (LangOpts.CPlusPlus)300      Contexts |= (1LL << CodeCompletionContext::CCC_Expression);301 302    // In Objective-C, message sends can send interfaces. In Objective-C++,303    // all types are available due to functional casts.304    if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))305      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);306 307    // In Objective-C, you can only be a subclass of another Objective-C class308    if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {309      // Objective-C interfaces can be used in a class property expression.310      if (ID->getDefinition())311        Contexts |= (1LL << CodeCompletionContext::CCC_Expression);312      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);313      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCClassForwardDecl);314    }315 316    // Deal with tag names.317    if (isa<EnumDecl>(ND)) {318      Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);319 320      // Part of the nested-name-specifier in C++0x.321      if (LangOpts.CPlusPlus11)322        IsNestedNameSpecifier = true;323    } else if (const auto *Record = dyn_cast<RecordDecl>(ND)) {324      if (Record->isUnion())325        Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);326      else327        Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag);328 329      if (LangOpts.CPlusPlus)330        IsNestedNameSpecifier = true;331    } else if (isa<ClassTemplateDecl>(ND))332      IsNestedNameSpecifier = true;333  } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {334    // Values can appear in these contexts.335    Contexts = (1LL << CodeCompletionContext::CCC_Statement)336             | (1LL << CodeCompletionContext::CCC_Expression)337             | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)338             | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);339  } else if (isa<ObjCProtocolDecl>(ND)) {340    Contexts = (1LL << CodeCompletionContext::CCC_ObjCProtocolName);341  } else if (isa<ObjCCategoryDecl>(ND)) {342    Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName);343  } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {344    Contexts = (1LL << CodeCompletionContext::CCC_Namespace);345 346    // Part of the nested-name-specifier.347    IsNestedNameSpecifier = true;348  }349 350  return Contexts;351}352 353void ASTUnit::CacheCodeCompletionResults() {354  if (!TheSema)355    return;356 357  SimpleTimer Timer(WantTiming);358  Timer.setOutput("Cache global code completions for " + getMainFileName());359 360  // Clear out the previous results.361  ClearCachedCompletionResults();362 363  // Gather the set of global code completions.364  using Result = CodeCompletionResult;365  SmallVector<Result, 8> Results;366  CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();367  CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);368  TheSema->CodeCompletion().GatherGlobalCodeCompletions(369      *CachedCompletionAllocator, CCTUInfo, Results);370 371  // Translate global code completions into cached completions.372  llvm::DenseMap<CanQualType, unsigned> CompletionTypes;373  CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel);374 375  for (auto &R : Results) {376    switch (R.Kind) {377    case Result::RK_Declaration: {378      bool IsNestedNameSpecifier = false;379      CachedCodeCompletionResult CachedResult;380      CachedResult.Completion = R.CreateCodeCompletionString(381          *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,382          IncludeBriefCommentsInCodeCompletion);383      CachedResult.ShowInContexts = getDeclShowContexts(384          R.Declaration, Ctx->getLangOpts(), IsNestedNameSpecifier);385      CachedResult.Priority = R.Priority;386      CachedResult.Kind = R.CursorKind;387      CachedResult.Availability = R.Availability;388 389      // Keep track of the type of this completion in an ASTContext-agnostic390      // way.391      QualType UsageType = getDeclUsageType(*Ctx, R.Qualifier, R.Declaration);392      if (UsageType.isNull()) {393        CachedResult.TypeClass = STC_Void;394        CachedResult.Type = 0;395      } else {396        CanQualType CanUsageType397          = Ctx->getCanonicalType(UsageType.getUnqualifiedType());398        CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);399 400        // Determine whether we have already seen this type. If so, we save401        // ourselves the work of formatting the type string by using the402        // temporary, CanQualType-based hash table to find the associated value.403        unsigned &TypeValue = CompletionTypes[CanUsageType];404        if (TypeValue == 0) {405          TypeValue = CompletionTypes.size();406          CachedCompletionTypes[QualType(CanUsageType).getAsString()]407            = TypeValue;408        }409 410        CachedResult.Type = TypeValue;411      }412 413      CachedCompletionResults.push_back(CachedResult);414 415      /// Handle nested-name-specifiers in C++.416      if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&417          !R.StartsNestedNameSpecifier) {418        // The contexts in which a nested-name-specifier can appear in C++.419        uint64_t NNSContexts420          = (1LL << CodeCompletionContext::CCC_TopLevel)421          | (1LL << CodeCompletionContext::CCC_ObjCIvarList)422          | (1LL << CodeCompletionContext::CCC_ClassStructUnion)423          | (1LL << CodeCompletionContext::CCC_Statement)424          | (1LL << CodeCompletionContext::CCC_Expression)425          | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)426          | (1LL << CodeCompletionContext::CCC_EnumTag)427          | (1LL << CodeCompletionContext::CCC_UnionTag)428          | (1LL << CodeCompletionContext::CCC_ClassOrStructTag)429          | (1LL << CodeCompletionContext::CCC_Type)430          | (1LL << CodeCompletionContext::CCC_SymbolOrNewName)431          | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);432 433        if (isa<NamespaceDecl>(R.Declaration) ||434            isa<NamespaceAliasDecl>(R.Declaration))435          NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);436 437        if (uint64_t RemainingContexts438                                = NNSContexts & ~CachedResult.ShowInContexts) {439          // If there any contexts where this completion can be a440          // nested-name-specifier but isn't already an option, create a441          // nested-name-specifier completion.442          R.StartsNestedNameSpecifier = true;443          CachedResult.Completion = R.CreateCodeCompletionString(444              *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,445              IncludeBriefCommentsInCodeCompletion);446          CachedResult.ShowInContexts = RemainingContexts;447          CachedResult.Priority = CCP_NestedNameSpecifier;448          CachedResult.TypeClass = STC_Void;449          CachedResult.Type = 0;450          CachedCompletionResults.push_back(CachedResult);451        }452      }453      break;454    }455 456    case Result::RK_Keyword:457    case Result::RK_Pattern:458      // Ignore keywords and patterns; we don't care, since they are so459      // easily regenerated.460      break;461 462    case Result::RK_Macro: {463      CachedCodeCompletionResult CachedResult;464      CachedResult.Completion = R.CreateCodeCompletionString(465          *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,466          IncludeBriefCommentsInCodeCompletion);467      CachedResult.ShowInContexts468        = (1LL << CodeCompletionContext::CCC_TopLevel)469        | (1LL << CodeCompletionContext::CCC_ObjCInterface)470        | (1LL << CodeCompletionContext::CCC_ObjCImplementation)471        | (1LL << CodeCompletionContext::CCC_ObjCIvarList)472        | (1LL << CodeCompletionContext::CCC_ClassStructUnion)473        | (1LL << CodeCompletionContext::CCC_Statement)474        | (1LL << CodeCompletionContext::CCC_Expression)475        | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)476        | (1LL << CodeCompletionContext::CCC_MacroNameUse)477        | (1LL << CodeCompletionContext::CCC_PreprocessorExpression)478        | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)479        | (1LL << CodeCompletionContext::CCC_OtherWithMacros);480 481      CachedResult.Priority = R.Priority;482      CachedResult.Kind = R.CursorKind;483      CachedResult.Availability = R.Availability;484      CachedResult.TypeClass = STC_Void;485      CachedResult.Type = 0;486      CachedCompletionResults.push_back(CachedResult);487      break;488    }489    }490  }491 492  // Save the current top-level hash value.493  CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;494}495 496void ASTUnit::ClearCachedCompletionResults() {497  CachedCompletionResults.clear();498  CachedCompletionTypes.clear();499  CachedCompletionAllocator = nullptr;500}501 502namespace {503 504/// Gathers information from ASTReader that will be used to initialize505/// a Preprocessor.506class ASTInfoCollector : public ASTReaderListener {507  HeaderSearchOptions &HSOpts;508  std::string &SpecificModuleCachePath;509  PreprocessorOptions &PPOpts;510  LangOptions &LangOpts;511  CodeGenOptions &CodeGenOpts;512  TargetOptions &TargetOpts;513  uint32_t &Counter;514 515public:516  ASTInfoCollector(HeaderSearchOptions &HSOpts,517                   std::string &SpecificModuleCachePath,518                   PreprocessorOptions &PPOpts, LangOptions &LangOpts,519                   CodeGenOptions &CodeGenOpts, TargetOptions &TargetOpts,520                   uint32_t &Counter)521      : HSOpts(HSOpts), SpecificModuleCachePath(SpecificModuleCachePath),522        PPOpts(PPOpts), LangOpts(LangOpts), CodeGenOpts(CodeGenOpts),523        TargetOpts(TargetOpts), Counter(Counter) {}524 525  bool ReadLanguageOptions(const LangOptions &NewLangOpts,526                           StringRef ModuleFilename, bool Complain,527                           bool AllowCompatibleDifferences) override {528    LangOpts = NewLangOpts;529    return false;530  }531 532  bool ReadCodeGenOptions(const CodeGenOptions &NewCodeGenOpts,533                          StringRef ModuleFilename, bool Complain,534                          bool AllowCompatibleDifferences) override {535    CodeGenOpts = NewCodeGenOpts;536    return false;537  }538 539  bool ReadHeaderSearchOptions(const HeaderSearchOptions &NewHSOpts,540                               StringRef ModuleFilename,541                               StringRef NewSpecificModuleCachePath,542                               bool Complain) override {543    HSOpts = NewHSOpts;544    SpecificModuleCachePath = NewSpecificModuleCachePath;545    return false;546  }547 548  bool ReadHeaderSearchPaths(const HeaderSearchOptions &NewHSOpts,549                             bool Complain) override {550    HSOpts.UserEntries = NewHSOpts.UserEntries;551    HSOpts.SystemHeaderPrefixes = NewHSOpts.SystemHeaderPrefixes;552    HSOpts.VFSOverlayFiles = NewHSOpts.VFSOverlayFiles;553    return false;554  }555 556  bool ReadPreprocessorOptions(const PreprocessorOptions &NewPPOpts,557                               StringRef ModuleFilename, bool ReadMacros,558                               bool Complain,559                               std::string &SuggestedPredefines) override {560    PPOpts = NewPPOpts;561    return false;562  }563 564  bool ReadTargetOptions(const TargetOptions &NewTargetOpts,565                         StringRef ModuleFilename, bool Complain,566                         bool AllowCompatibleDifferences) override {567    TargetOpts = NewTargetOpts;568    return false;569  }570 571  void ReadCounter(const serialization::ModuleFile &M,572                   uint32_t NewCounter) override {573    Counter = NewCounter;574  }575};576} // anonymous namespace577 578FilterAndStoreDiagnosticConsumer::FilterAndStoreDiagnosticConsumer(579    SmallVectorImpl<StoredDiagnostic> *StoredDiags,580    SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags,581    bool CaptureNonErrorsFromIncludes)582    : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),583      CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {584  assert((StoredDiags || StandaloneDiags) &&585         "No output collections were passed to StoredDiagnosticConsumer.");586}587 588void FilterAndStoreDiagnosticConsumer::BeginSourceFile(589    const LangOptions &LangOpts, const Preprocessor *PP) {590  this->LangOpts = &LangOpts;591  if (PP)592    SourceMgr = &PP->getSourceManager();593}594 595static bool isInMainFile(const clang::Diagnostic &D) {596  if (!D.hasSourceManager() || !D.getLocation().isValid())597    return false;598 599  auto &M = D.getSourceManager();600  return M.isWrittenInMainFile(M.getExpansionLoc(D.getLocation()));601}602 603void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(604    DiagnosticsEngine::Level Level, const Diagnostic &Info) {605  // Default implementation (Warnings/errors count).606  DiagnosticConsumer::HandleDiagnostic(Level, Info);607 608  // Only record the diagnostic if it's part of the source manager we know609  // about. This effectively drops diagnostics from modules we're building.610  // FIXME: In the long run, ee don't want to drop source managers from modules.611  if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) {612    if (!CaptureNonErrorsFromIncludes && Level <= DiagnosticsEngine::Warning &&613        !isInMainFile(Info)) {614      return;615    }616 617    StoredDiagnostic *ResultDiag = nullptr;618    if (StoredDiags) {619      StoredDiags->emplace_back(Level, Info);620      ResultDiag = &StoredDiags->back();621    }622 623    if (StandaloneDiags) {624      std::optional<StoredDiagnostic> StoredDiag;625      if (!ResultDiag) {626        StoredDiag.emplace(Level, Info);627        ResultDiag = &*StoredDiag;628      }629      StandaloneDiags->emplace_back(*LangOpts, *ResultDiag);630    }631  }632}633 634CaptureDroppedDiagnostics::CaptureDroppedDiagnostics(635    CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,636    SmallVectorImpl<StoredDiagnostic> *StoredDiags,637    SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags)638    : Diags(Diags),639      Client(StoredDiags, StandaloneDiags,640             CaptureDiagnostics !=641                 CaptureDiagsKind::AllWithoutNonErrorsFromIncludes) {642  if (CaptureDiagnostics != CaptureDiagsKind::None ||643      Diags.getClient() == nullptr) {644    OwningPreviousClient = Diags.takeClient();645    PreviousClient = Diags.getClient();646    Diags.setClient(&Client, false);647  }648}649 650CaptureDroppedDiagnostics::~CaptureDroppedDiagnostics() {651  if (Diags.getClient() == &Client)652    Diags.setClient(PreviousClient, !!OwningPreviousClient.release());653}654 655IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {656  return Reader;657}658 659ASTMutationListener *ASTUnit::getASTMutationListener() {660  if (WriterData)661    return &WriterData->Writer;662  return nullptr;663}664 665ASTDeserializationListener *ASTUnit::getDeserializationListener() {666  if (WriterData)667    return &WriterData->Writer;668  return nullptr;669}670 671std::unique_ptr<llvm::MemoryBuffer>672ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {673  assert(FileMgr);674  auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);675  if (Buffer)676    return std::move(*Buffer);677  if (ErrorStr)678    *ErrorStr = Buffer.getError().message();679  return nullptr;680}681 682/// Configure the diagnostics object for use with ASTUnit.683void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,684                             ASTUnit &AST,685                             CaptureDiagsKind CaptureDiagnostics) {686  assert(Diags.get() && "no DiagnosticsEngine was provided");687  if (CaptureDiagnostics != CaptureDiagsKind::None)688    Diags->setClient(new FilterAndStoreDiagnosticConsumer(689        &AST.StoredDiagnostics, nullptr,690        CaptureDiagnostics != CaptureDiagsKind::AllWithoutNonErrorsFromIncludes));691}692 693std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(694    StringRef Filename, const PCHContainerReader &PCHContainerRdr,695    WhatToLoad ToLoad, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,696    std::shared_ptr<DiagnosticOptions> DiagOpts,697    IntrusiveRefCntPtr<DiagnosticsEngine> Diags,698    const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts,699    const LangOptions *ProvidedLangOpts, bool OnlyLocalDecls,700    CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,701    bool UserFilesAreVolatile) {702  std::unique_ptr<ASTUnit> AST(new ASTUnit(true));703 704  // Recover resources if we crash before exiting this method.705  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>706    ASTUnitCleanup(AST.get());707  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,708    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>709    DiagCleanup(Diags.get());710 711  ConfigureDiags(Diags, *AST, CaptureDiagnostics);712 713  std::unique_ptr<LangOptions> LocalLangOpts;714  const LangOptions &LangOpts = [&]() -> const LangOptions & {715    if (ProvidedLangOpts)716      return *ProvidedLangOpts;717    LocalLangOpts = std::make_unique<LangOptions>();718    return *LocalLangOpts;719  }();720 721  AST->LangOpts = std::make_unique<LangOptions>(LangOpts);722  AST->OnlyLocalDecls = OnlyLocalDecls;723  AST->CaptureDiagnostics = CaptureDiagnostics;724  AST->DiagOpts = DiagOpts;725  AST->Diagnostics = Diags;726  AST->UserFilesAreVolatile = UserFilesAreVolatile;727  AST->HSOpts = std::make_unique<HeaderSearchOptions>(HSOpts);728  AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());729  AST->PPOpts = std::make_shared<PreprocessorOptions>();730  AST->CodeGenOpts = std::make_unique<CodeGenOptions>();731  AST->TargetOpts = std::make_shared<TargetOptions>();732 733  AST->ModCache = createCrossProcessModuleCache();734 735  // Gather info for preprocessor construction later on.736  std::string SpecificModuleCachePath;737  unsigned Counter = 0;738  // Using a temporary FileManager since the AST file might specify custom739  // HeaderSearchOptions::VFSOverlayFiles that affect the underlying VFS.740  FileManager TmpFileMgr(FileSystemOpts, VFS);741  ASTInfoCollector Collector(*AST->HSOpts, SpecificModuleCachePath,742                             *AST->PPOpts, *AST->LangOpts, *AST->CodeGenOpts,743                             *AST->TargetOpts, Counter);744  if (ASTReader::readASTFileControlBlock(745          Filename, TmpFileMgr, *AST->ModCache, PCHContainerRdr,746          /*FindModuleFileExtensions=*/true, Collector,747          /*ValidateDiagnosticOptions=*/true, ASTReader::ARR_None)) {748    AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);749    return nullptr;750  }751 752  VFS = createVFSFromOverlayFiles(AST->HSOpts->VFSOverlayFiles,753                                  *AST->Diagnostics, std::move(VFS));754 755  AST->FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOpts, VFS);756 757  AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(758      AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile);759 760  AST->HSOpts->PrebuiltModuleFiles = HSOpts.PrebuiltModuleFiles;761  AST->HSOpts->PrebuiltModulePaths = HSOpts.PrebuiltModulePaths;762  AST->HeaderInfo = std::make_unique<HeaderSearch>(763      AST->getHeaderSearchOpts(), AST->getSourceManager(),764      AST->getDiagnostics(), AST->getLangOpts(),765      /*Target=*/nullptr);766  AST->HeaderInfo->setModuleCachePath(SpecificModuleCachePath);767 768  AST->PP = std::make_shared<Preprocessor>(769      *AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,770      AST->getSourceManager(), *AST->HeaderInfo, AST->ModuleLoader,771      /*IILookup=*/nullptr,772      /*OwnsHeaderSearch=*/false);773 774  if (ToLoad >= LoadASTOnly)775    AST->Ctx = llvm::makeIntrusiveRefCnt<ASTContext>(776        *AST->LangOpts, AST->getSourceManager(), AST->PP->getIdentifierTable(),777        AST->PP->getSelectorTable(), AST->PP->getBuiltinInfo(),778        AST->getTranslationUnitKind());779 780  DisableValidationForModuleKind disableValid =781      DisableValidationForModuleKind::None;782  if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))783    disableValid = DisableValidationForModuleKind::All;784  AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(785      *AST->PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr,786      *AST->CodeGenOpts, ArrayRef<std::shared_ptr<ModuleFileExtension>>(),787      /*isysroot=*/"",788      /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);789 790  // Attach the AST reader to the AST context as an external AST source, so that791  // declarations will be deserialized from the AST file as needed.792  // We need the external source to be set up before we read the AST, because793  // eagerly-deserialized declarations may use it.794  if (AST->Ctx)795    AST->Ctx->setExternalSource(AST->Reader);796 797  AST->Target =798      TargetInfo::CreateTargetInfo(AST->PP->getDiagnostics(), *AST->TargetOpts);799  // Inform the target of the language options.800  //801  // FIXME: We shouldn't need to do this, the target should be immutable once802  // created. This complexity should be lifted elsewhere.803  AST->Target->adjust(AST->PP->getDiagnostics(), *AST->LangOpts,804                      /*AuxTarget=*/nullptr);805 806  // Initialize the preprocessor.807  AST->PP->Initialize(*AST->Target);808 809  AST->PP->setCounterValue(Counter);810 811  if (AST->Ctx) {812    // Initialize the ASTContext813    AST->Ctx->InitBuiltinTypes(*AST->Target);814 815    // Adjust printing policy based on language options.816    AST->Ctx->setPrintingPolicy(PrintingPolicy(*AST->LangOpts));817 818    // We didn't have access to the comment options when the ASTContext was819    // constructed, so register them now.820    AST->Ctx->getCommentCommandTraits().registerCommentOptions(821        AST->LangOpts->CommentOpts);822  }823 824  // The temporary FileManager we used for ASTReader::readASTFileControlBlock()825  // might have already read stdin, and reading it again will fail. Let's826  // explicitly forward the buffer.827  if (Filename == "-")828    if (auto FE = llvm::expectedToOptional(TmpFileMgr.getSTDIN()))829      if (auto BufRef = TmpFileMgr.getBufferForFile(*FE)) {830        auto Buf = llvm::MemoryBuffer::getMemBufferCopy(831            (*BufRef)->getBuffer(), (*BufRef)->getBufferIdentifier());832        AST->Reader->getModuleManager().addInMemoryBuffer("-", std::move(Buf));833      }834 835  // Reinstate the provided options that are relevant for reading AST files.836  AST->HSOpts->ForceCheckCXX20ModulesInputFiles =837      HSOpts.ForceCheckCXX20ModulesInputFiles;838 839  switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,840                               SourceLocation(), ASTReader::ARR_None)) {841  case ASTReader::Success:842    break;843 844  case ASTReader::Failure:845  case ASTReader::Missing:846  case ASTReader::OutOfDate:847  case ASTReader::VersionMismatch:848  case ASTReader::ConfigurationMismatch:849  case ASTReader::HadErrors:850    AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);851    return nullptr;852  }853 854  // Now that we have successfully loaded the AST file, we can reinstate some855  // options that the clients expect us to preserve (but would trip AST file856  // validation, so we couldn't set them earlier).857  AST->HSOpts->UserEntries = HSOpts.UserEntries;858  AST->HSOpts->SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;859  AST->HSOpts->VFSOverlayFiles = HSOpts.VFSOverlayFiles;860  AST->LangOpts->PICLevel = LangOpts.PICLevel;861  AST->LangOpts->PIE = LangOpts.PIE;862 863  AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());864 865  Module *M = AST->HeaderInfo->lookupModule(AST->getLangOpts().CurrentModule);866  if (M && AST->getLangOpts().isCompilingModule() && M->isNamedModule())867    AST->Ctx->setCurrentNamedModule(M);868 869  // Create an AST consumer, even though it isn't used.870  if (ToLoad >= LoadASTOnly)871    AST->Consumer.reset(new ASTConsumer);872 873  // Create a semantic analysis object and tell the AST reader about it.874  if (ToLoad >= LoadEverything) {875    AST->TheSema = std::make_unique<Sema>(*AST->PP, *AST->Ctx, *AST->Consumer);876    AST->TheSema->Initialize();877    AST->Reader->InitializeSema(*AST->TheSema);878  }879 880  // Tell the diagnostic client that we have started a source file.881  AST->getDiagnostics().getClient()->BeginSourceFile(AST->PP->getLangOpts(),882                                                     AST->PP.get());883 884  return AST;885}886 887/// Add the given macro to the hash of all top-level entities.888static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {889  Hash = llvm::djbHash(MacroNameTok.getIdentifierInfo()->getName(), Hash);890}891 892namespace {893 894/// Preprocessor callback class that updates a hash value with the names895/// of all macros that have been defined by the translation unit.896class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {897  unsigned &Hash;898 899public:900  explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}901 902  void MacroDefined(const Token &MacroNameTok,903                    const MacroDirective *MD) override {904    AddDefinedMacroToHash(MacroNameTok, Hash);905  }906};907 908} // namespace909 910/// Add the given declaration to the hash of all top-level entities.911static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {912  if (!D)913    return;914 915  DeclContext *DC = D->getDeclContext();916  if (!DC)917    return;918 919  if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))920    return;921 922  if (const auto *ND = dyn_cast<NamedDecl>(D)) {923    if (const auto *EnumD = dyn_cast<EnumDecl>(D)) {924      // For an unscoped enum include the enumerators in the hash since they925      // enter the top-level namespace.926      if (!EnumD->isScoped()) {927        for (const auto *EI : EnumD->enumerators()) {928          if (EI->getIdentifier())929            Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);930        }931      }932    }933 934    if (ND->getIdentifier())935      Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);936    else if (DeclarationName Name = ND->getDeclName()) {937      std::string NameStr = Name.getAsString();938      Hash = llvm::djbHash(NameStr, Hash);939    }940    return;941  }942 943  if (const auto *ImportD = dyn_cast<ImportDecl>(D)) {944    if (const Module *Mod = ImportD->getImportedModule()) {945      std::string ModName = Mod->getFullModuleName();946      Hash = llvm::djbHash(ModName, Hash);947    }948    return;949  }950}951 952namespace {953 954class TopLevelDeclTrackerConsumer : public ASTConsumer {955  ASTUnit &Unit;956  unsigned &Hash;957 958public:959  TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)960      : Unit(_Unit), Hash(Hash) {961    Hash = 0;962  }963 964  void handleTopLevelDecl(Decl *D) {965    if (!D)966      return;967 968    // FIXME: Currently ObjC method declarations are incorrectly being969    // reported as top-level declarations, even though their DeclContext970    // is the containing ObjC @interface/@implementation.  This is a971    // fundamental problem in the parser right now.972    if (isa<ObjCMethodDecl>(D))973      return;974 975    AddTopLevelDeclarationToHash(D, Hash);976    Unit.addTopLevelDecl(D);977 978    handleFileLevelDecl(D);979  }980 981  void handleFileLevelDecl(Decl *D) {982    Unit.addFileLevelDecl(D);983    if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {984      for (auto *I : NSD->decls())985        handleFileLevelDecl(I);986    }987  }988 989  bool HandleTopLevelDecl(DeclGroupRef D) override {990    for (auto *TopLevelDecl : D)991      handleTopLevelDecl(TopLevelDecl);992    return true;993  }994 995  // We're not interested in "interesting" decls.996  void HandleInterestingDecl(DeclGroupRef) override {}997 998  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {999    for (auto *TopLevelDecl : D)1000      handleTopLevelDecl(TopLevelDecl);1001  }1002 1003  ASTMutationListener *GetASTMutationListener() override {1004    return Unit.getASTMutationListener();1005  }1006 1007  ASTDeserializationListener *GetASTDeserializationListener() override {1008    return Unit.getDeserializationListener();1009  }1010};1011 1012class TopLevelDeclTrackerAction : public ASTFrontendAction {1013public:1014  ASTUnit &Unit;1015 1016  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,1017                                                 StringRef InFile) override {1018    CI.getPreprocessor().addPPCallbacks(1019        std::make_unique<MacroDefinitionTrackerPPCallbacks>(1020                                           Unit.getCurrentTopLevelHashValue()));1021    return std::make_unique<TopLevelDeclTrackerConsumer>(1022        Unit, Unit.getCurrentTopLevelHashValue());1023  }1024 1025public:1026  TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}1027 1028  bool hasCodeCompletionSupport() const override { return false; }1029 1030  TranslationUnitKind getTranslationUnitKind() override {1031    return Unit.getTranslationUnitKind();1032  }1033};1034 1035class ASTUnitPreambleCallbacks : public PreambleCallbacks {1036public:1037  unsigned getHash() const { return Hash; }1038 1039  std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }1040 1041  std::vector<LocalDeclID> takeTopLevelDeclIDs() {1042    return std::move(TopLevelDeclIDs);1043  }1044 1045  void AfterPCHEmitted(ASTWriter &Writer) override {1046    TopLevelDeclIDs.reserve(TopLevelDecls.size());1047    for (const auto *D : TopLevelDecls) {1048      // Invalid top-level decls may not have been serialized.1049      if (D->isInvalidDecl())1050        continue;1051      TopLevelDeclIDs.push_back(Writer.getDeclID(D));1052    }1053  }1054 1055  void HandleTopLevelDecl(DeclGroupRef DG) override {1056    for (auto *D : DG) {1057      // FIXME: Currently ObjC method declarations are incorrectly being1058      // reported as top-level declarations, even though their DeclContext1059      // is the containing ObjC @interface/@implementation.  This is a1060      // fundamental problem in the parser right now.1061      if (isa<ObjCMethodDecl>(D))1062        continue;1063      AddTopLevelDeclarationToHash(D, Hash);1064      TopLevelDecls.push_back(D);1065    }1066  }1067 1068  std::unique_ptr<PPCallbacks> createPPCallbacks() override {1069    return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);1070  }1071 1072private:1073  unsigned Hash = 0;1074  std::vector<Decl *> TopLevelDecls;1075  std::vector<LocalDeclID> TopLevelDeclIDs;1076  llvm::SmallVector<StandaloneDiagnostic, 4> PreambleDiags;1077};1078 1079} // namespace1080 1081static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {1082  return StoredDiag.getLocation().isValid();1083}1084 1085static void1086checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &StoredDiags) {1087  // Get rid of stored diagnostics except the ones from the driver which do not1088  // have a source location.1089  llvm::erase_if(StoredDiags, isNonDriverDiag);1090}1091 1092static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &1093                                                              StoredDiagnostics,1094                                  SourceManager &SM) {1095  // The stored diagnostic has the old source manager in it; update1096  // the locations to refer into the new source manager. Since we've1097  // been careful to make sure that the source manager's state1098  // before and after are identical, so that we can reuse the source1099  // location itself.1100  for (auto &SD : StoredDiagnostics) {1101    if (SD.getLocation().isValid()) {1102      FullSourceLoc Loc(SD.getLocation(), SM);1103      SD.setLocation(Loc);1104    }1105  }1106}1107 1108/// Parse the source file into a translation unit using the given compiler1109/// invocation, replacing the current translation unit.1110///1111/// \returns True if a failure occurred that causes the ASTUnit not to1112/// contain any translation-unit information, false otherwise.1113bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,1114                    std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,1115                    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {1116  if (!Invocation)1117    return true;1118 1119  if (VFS && FileMgr)1120    assert(VFS == &FileMgr->getVirtualFileSystem() &&1121           "VFS passed to Parse and VFS in FileMgr are different");1122 1123  CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);1124  if (OverrideMainBuffer) {1125    assert(Preamble &&1126           "No preamble was built, but OverrideMainBuffer is not null");1127    Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());1128    // VFS may have changed...1129  }1130 1131  // Create the compiler instance to use for building the AST.1132  auto Clang = std::make_unique<CompilerInstance>(CCInvocation,1133                                                  std::move(PCHContainerOps));1134 1135  // Clean up on error, disengage it if the function returns successfully.1136  auto CleanOnError = llvm::make_scope_exit([&]() {1137    // Remove the overridden buffer we used for the preamble.1138    SavedMainFileBuffer = nullptr;1139 1140    // Keep the ownership of the data in the ASTUnit because the client may1141    // want to see the diagnostics.1142    transferASTDataFromCompilerInstance(*Clang);1143    FailedParseDiagnostics.swap(StoredDiagnostics);1144    StoredDiagnostics.clear();1145    NumStoredDiagnosticsFromDriver = 0;1146  });1147 1148  // Ensure that Clang has a FileManager with the right VFS, which may have1149  // changed above in AddImplicitPreamble.  If VFS is nullptr, rely on1150  // createFileManager to create one.1151  if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS) {1152    Clang->setVirtualFileSystem(std::move(VFS));1153    Clang->setFileManager(FileMgr);1154  } else {1155    Clang->setVirtualFileSystem(std::move(VFS));1156    Clang->createFileManager();1157    FileMgr = Clang->getFileManagerPtr();1158  }1159 1160  // Recover resources if we crash before exiting this method.1161  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>1162    CICleanup(Clang.get());1163 1164  OriginalSourceFile =1165      std::string(Clang->getFrontendOpts().Inputs[0].getFile());1166 1167  // Set up diagnostics, capturing any diagnostics that would1168  // otherwise be dropped.1169  Clang->setDiagnostics(getDiagnosticsPtr());1170 1171  // Create the target instance.1172  if (!Clang->createTarget())1173    return true;1174 1175  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&1176         "Invocation must have exactly one source file!");1177  assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==1178             InputKind::Source &&1179         "FIXME: AST inputs not yet supported here!");1180  assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=1181             Language::LLVM_IR &&1182         "IR inputs not support here!");1183 1184  // Configure the various subsystems.1185  LangOpts =1186      std::make_unique<LangOptions>(Clang->getInvocation().getLangOpts());1187  FileSystemOpts = Clang->getFileSystemOpts();1188 1189  ResetForParse();1190 1191  SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(1192      getDiagnostics(), *FileMgr, +UserFilesAreVolatile);1193  if (!OverrideMainBuffer) {1194    checkAndRemoveNonDriverDiags(StoredDiagnostics);1195    TopLevelDeclsInPreamble.clear();1196  }1197 1198  // Create the source manager.1199  Clang->setSourceManager(getSourceManagerPtr());1200 1201  // If the main file has been overridden due to the use of a preamble,1202  // make that override happen and introduce the preamble.1203  if (OverrideMainBuffer) {1204    // The stored diagnostic has the old source manager in it; update1205    // the locations to refer into the new source manager. Since we've1206    // been careful to make sure that the source manager's state1207    // before and after are identical, so that we can reuse the source1208    // location itself.1209    checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());1210 1211    // Keep track of the override buffer;1212    SavedMainFileBuffer = std::move(OverrideMainBuffer);1213  }1214 1215  std::unique_ptr<TopLevelDeclTrackerAction> Act(1216      new TopLevelDeclTrackerAction(*this));1217 1218  // Recover resources if we crash before exiting this method.1219  llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>1220    ActCleanup(Act.get());1221 1222  if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))1223    return true;1224 1225  if (SavedMainFileBuffer) {1226    StoredDiagnostics.clear();1227    StoredDiagnostics.reserve(PreambleDiagnostics.size());1228    llvm::transform(std::move(PreambleDiagnostics),1229                    std::back_inserter(StoredDiagnostics),1230                    [&](auto &&StandaloneDiag) {1231                      return translateStandaloneDiag(1232                          getFileManager(), getSourceManager(),1233                          std::move(StandaloneDiag), PreambleSrcLocCache);1234                    });1235  } else1236    PreambleSrcLocCache.clear();1237 1238  if (llvm::Error Err = Act->Execute()) {1239    consumeError(std::move(Err)); // FIXME this drops errors on the floor.1240    return true;1241  }1242 1243  transferASTDataFromCompilerInstance(*Clang);1244 1245  Act->EndSourceFile();1246 1247  FailedParseDiagnostics.clear();1248 1249  CleanOnError.release();1250 1251  return false;1252}1253 1254/// Attempt to build or re-use a precompiled preamble when (re-)parsing1255/// the source file.1256///1257/// This routine will compute the preamble of the main source file. If a1258/// non-trivial preamble is found, it will precompile that preamble into a1259/// precompiled header so that the precompiled preamble can be used to reduce1260/// reparsing time. If a precompiled preamble has already been constructed,1261/// this routine will determine if it is still valid and, if so, avoid1262/// rebuilding the precompiled preamble.1263///1264/// \param AllowRebuild When true (the default), this routine is1265/// allowed to rebuild the precompiled preamble if it is found to be1266/// out-of-date.1267///1268/// \param MaxLines When non-zero, the maximum number of lines that1269/// can occur within the preamble.1270///1271/// \returns If the precompiled preamble can be used, returns a newly-allocated1272/// buffer that should be used in place of the main file when doing so.1273/// Otherwise, returns a NULL pointer.1274std::unique_ptr<llvm::MemoryBuffer>1275ASTUnit::getMainBufferWithPrecompiledPreamble(1276    std::shared_ptr<PCHContainerOperations> PCHContainerOps,1277    CompilerInvocation &PreambleInvocationIn,1278    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild,1279    unsigned MaxLines) {1280  auto MainFilePath =1281      PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();1282  std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =1283      getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),1284                                        MainFilePath, UserFilesAreVolatile);1285  if (!MainFileBuffer)1286    return nullptr;1287 1288  PreambleBounds Bounds = ComputePreambleBounds(1289      PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines);1290  if (!Bounds.Size)1291    return nullptr;1292 1293  if (Preamble) {1294    if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,1295                           *VFS)) {1296      // Okay! We can re-use the precompiled preamble.1297 1298      // Set the state of the diagnostic object to mimic its state1299      // after parsing the preamble.1300      getDiagnostics().Reset();1301      ProcessWarningOptions(getDiagnostics(),1302                            PreambleInvocationIn.getDiagnosticOpts(), *VFS);1303      getDiagnostics().setNumWarnings(NumWarningsInPreamble);1304 1305      PreambleRebuildCountdown = 1;1306      return MainFileBuffer;1307    } else {1308      Preamble.reset();1309      PreambleDiagnostics.clear();1310      TopLevelDeclsInPreamble.clear();1311      PreambleSrcLocCache.clear();1312      PreambleRebuildCountdown = 1;1313    }1314  }1315 1316  // If the preamble rebuild counter > 1, it's because we previously1317  // failed to build a preamble and we're not yet ready to try1318  // again. Decrement the counter and return a failure.1319  if (PreambleRebuildCountdown > 1) {1320    --PreambleRebuildCountdown;1321    return nullptr;1322  }1323 1324  assert(!Preamble && "No Preamble should be stored at that point");1325  // If we aren't allowed to rebuild the precompiled preamble, just1326  // return now.1327  if (!AllowRebuild)1328    return nullptr;1329 1330  ++PreambleCounter;1331 1332  SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;1333  SmallVector<StoredDiagnostic, 4> NewPreambleDiags;1334  ASTUnitPreambleCallbacks Callbacks;1335  {1336    std::optional<CaptureDroppedDiagnostics> Capture;1337    if (CaptureDiagnostics != CaptureDiagsKind::None)1338      Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,1339                      &NewPreambleDiagsStandalone);1340 1341    // We did not previously compute a preamble, or it can't be reused anyway.1342    SimpleTimer PreambleTimer(WantTiming);1343    PreambleTimer.setOutput("Precompiling preamble");1344 1345    const bool PreviousSkipFunctionBodies =1346        PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;1347    if (SkipFunctionBodies == SkipFunctionBodiesScope::Preamble)1348      PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true;1349 1350    llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(1351        PreambleInvocationIn, MainFileBuffer.get(), Bounds, Diagnostics, VFS,1352        PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,1353        Callbacks);1354 1355    PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =1356        PreviousSkipFunctionBodies;1357 1358    if (NewPreamble) {1359      Preamble = std::move(*NewPreamble);1360      PreambleRebuildCountdown = 1;1361    } else {1362      switch (static_cast<BuildPreambleError>(NewPreamble.getError().value())) {1363      case BuildPreambleError::CouldntCreateTempFile:1364        // Try again next time.1365        PreambleRebuildCountdown = 1;1366        return nullptr;1367      case BuildPreambleError::CouldntCreateTargetInfo:1368      case BuildPreambleError::BeginSourceFileFailed:1369      case BuildPreambleError::CouldntEmitPCH:1370      case BuildPreambleError::BadInputs:1371        // These erros are more likely to repeat, retry after some period.1372        PreambleRebuildCountdown = DefaultPreambleRebuildInterval;1373        return nullptr;1374      }1375      llvm_unreachable("unexpected BuildPreambleError");1376    }1377  }1378 1379  assert(Preamble && "Preamble wasn't built");1380 1381  TopLevelDecls.clear();1382  TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();1383  PreambleTopLevelHashValue = Callbacks.getHash();1384 1385  NumWarningsInPreamble = getDiagnostics().getNumWarnings();1386 1387  checkAndRemoveNonDriverDiags(NewPreambleDiags);1388  StoredDiagnostics = std::move(NewPreambleDiags);1389  PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);1390 1391  // If the hash of top-level entities differs from the hash of the top-level1392  // entities the last time we rebuilt the preamble, clear out the completion1393  // cache.1394  if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {1395    CompletionCacheTopLevelHashValue = 0;1396    PreambleTopLevelHashValue = CurrentTopLevelHashValue;1397  }1398 1399  return MainFileBuffer;1400}1401 1402void ASTUnit::RealizeTopLevelDeclsFromPreamble() {1403  assert(Preamble && "Should only be called when preamble was built");1404 1405  std::vector<Decl *> Resolved;1406  Resolved.reserve(TopLevelDeclsInPreamble.size());1407  // The module file of the preamble.1408  serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();1409  for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {1410    // Resolve the declaration ID to an actual declaration, possibly1411    // deserializing the declaration in the process.1412    if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))1413      Resolved.push_back(D);1414  }1415  TopLevelDeclsInPreamble.clear();1416  TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());1417}1418 1419void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {1420  // Steal the created target, context, and preprocessor if they have been1421  // created.1422  LangOpts = std::make_unique<LangOptions>(CI.getInvocation().getLangOpts());1423  TheSema = CI.takeSema();1424  Consumer = CI.takeASTConsumer();1425  if (CI.hasASTContext())1426    Ctx = CI.getASTContextPtr();1427  if (CI.hasPreprocessor())1428    PP = CI.getPreprocessorPtr();1429  CI.setSourceManager(nullptr);1430  CI.setFileManager(nullptr);1431  if (CI.hasTarget())1432    Target = CI.getTargetPtr();1433  Reader = CI.getASTReader();1434  HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();1435  if (Invocation != CI.getInvocationPtr()) {1436    // This happens when Parse creates a copy of \c Invocation to modify.1437    ModifiedInvocation = CI.getInvocationPtr();1438  }1439}1440 1441StringRef ASTUnit::getMainFileName() const {1442  if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {1443    const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];1444    if (Input.isFile())1445      return Input.getFile();1446    else1447      return Input.getBuffer().getBufferIdentifier();1448  }1449 1450  if (SourceMgr) {1451    if (OptionalFileEntryRef FE =1452            SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID()))1453      return FE->getName();1454  }1455 1456  return {};1457}1458 1459StringRef ASTUnit::getASTFileName() const {1460  if (!isMainFileAST())1461    return {};1462 1463  serialization::ModuleFile &1464    Mod = Reader->getModuleManager().getPrimaryModule();1465  return Mod.FileName;1466}1467 1468std::unique_ptr<ASTUnit>1469ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,1470                std::shared_ptr<DiagnosticOptions> DiagOpts,1471                IntrusiveRefCntPtr<DiagnosticsEngine> Diags,1472                CaptureDiagsKind CaptureDiagnostics,1473                bool UserFilesAreVolatile) {1474  std::unique_ptr<ASTUnit> AST(new ASTUnit(false));1475  ConfigureDiags(Diags, *AST, CaptureDiagnostics);1476  IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =1477      createVFSFromCompilerInvocation(*CI, *Diags);1478  AST->DiagOpts = DiagOpts;1479  AST->Diagnostics = Diags;1480  AST->FileSystemOpts = CI->getFileSystemOpts();1481  AST->Invocation = std::move(CI);1482  AST->FileMgr =1483      llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);1484  AST->UserFilesAreVolatile = UserFilesAreVolatile;1485  AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(1486      AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile);1487  AST->ModCache = createCrossProcessModuleCache();1488 1489  return AST;1490}1491 1492ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(1493    std::shared_ptr<CompilerInvocation> CI,1494    std::shared_ptr<PCHContainerOperations> PCHContainerOps,1495    std::shared_ptr<DiagnosticOptions> DiagOpts,1496    IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action,1497    ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,1498    bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,1499    unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,1500    bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {1501  assert(CI && "A CompilerInvocation is required");1502 1503  std::unique_ptr<ASTUnit> OwnAST;1504  ASTUnit *AST = Unit;1505  if (!AST) {1506    // Create the AST unit.1507    OwnAST =1508        create(CI, DiagOpts, Diags, CaptureDiagnostics, UserFilesAreVolatile);1509    AST = OwnAST.get();1510    if (!AST)1511      return nullptr;1512  }1513 1514  if (!ResourceFilesPath.empty()) {1515    // Override the resources path.1516    CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);1517  }1518  AST->OnlyLocalDecls = OnlyLocalDecls;1519  AST->CaptureDiagnostics = CaptureDiagnostics;1520  if (PrecompilePreambleAfterNParses > 0)1521    AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;1522  AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;1523  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;1524  AST->IncludeBriefCommentsInCodeCompletion = false;1525 1526  // Recover resources if we crash before exiting this method.1527  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>1528    ASTUnitCleanup(OwnAST.get());1529  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,1530    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>1531    DiagCleanup(Diags.get());1532 1533  // We'll manage file buffers ourselves.1534  CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;1535  CI->getFrontendOpts().DisableFree = false;1536  ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts(),1537                        AST->getFileManager().getVirtualFileSystem());1538 1539  // Create the compiler instance to use for building the AST.1540  auto Clang = std::make_unique<CompilerInstance>(std::move(CI),1541                                                  std::move(PCHContainerOps));1542 1543  // Recover resources if we crash before exiting this method.1544  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>1545    CICleanup(Clang.get());1546 1547  AST->OriginalSourceFile =1548      std::string(Clang->getFrontendOpts().Inputs[0].getFile());1549 1550  // Set up diagnostics, capturing any diagnostics that would1551  // otherwise be dropped.1552  Clang->setDiagnostics(AST->getDiagnosticsPtr());1553 1554  // Create the target instance.1555  if (!Clang->createTarget())1556    return nullptr;1557 1558  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&1559         "Invocation must have exactly one source file!");1560  assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==1561             InputKind::Source &&1562         "FIXME: AST inputs not yet supported here!");1563  assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=1564             Language::LLVM_IR &&1565         "IR inputs not support here!");1566 1567  // Configure the various subsystems.1568  AST->TheSema.reset();1569  AST->Ctx = nullptr;1570  AST->PP = nullptr;1571  AST->Reader = nullptr;1572 1573  // Create a file manager object to provide access to and cache the filesystem.1574  Clang->setVirtualFileSystem(AST->getVirtualFileSystemPtr());1575  Clang->setFileManager(AST->getFileManagerPtr());1576 1577  // Create the source manager.1578  Clang->setSourceManager(AST->getSourceManagerPtr());1579 1580  FrontendAction *Act = Action;1581 1582  std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;1583  if (!Act) {1584    TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));1585    Act = TrackerAct.get();1586  }1587 1588  // Recover resources if we crash before exiting this method.1589  llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>1590    ActCleanup(TrackerAct.get());1591 1592  if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {1593    AST->transferASTDataFromCompilerInstance(*Clang);1594    if (OwnAST && ErrAST)1595      ErrAST->swap(OwnAST);1596 1597    return nullptr;1598  }1599 1600  if (Persistent && !TrackerAct) {1601    Clang->getPreprocessor().addPPCallbacks(1602        std::make_unique<MacroDefinitionTrackerPPCallbacks>(1603                                           AST->getCurrentTopLevelHashValue()));1604    std::vector<std::unique_ptr<ASTConsumer>> Consumers;1605    if (Clang->hasASTConsumer())1606      Consumers.push_back(Clang->takeASTConsumer());1607    Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(1608        *AST, AST->getCurrentTopLevelHashValue()));1609    Clang->setASTConsumer(1610        std::make_unique<MultiplexConsumer>(std::move(Consumers)));1611  }1612  if (llvm::Error Err = Act->Execute()) {1613    consumeError(std::move(Err)); // FIXME this drops errors on the floor.1614    AST->transferASTDataFromCompilerInstance(*Clang);1615    if (OwnAST && ErrAST)1616      ErrAST->swap(OwnAST);1617 1618    return nullptr;1619  }1620 1621  // Steal the created target, context, and preprocessor.1622  AST->transferASTDataFromCompilerInstance(*Clang);1623 1624  Act->EndSourceFile();1625 1626  if (OwnAST)1627    return OwnAST.release();1628  else1629    return AST;1630}1631 1632bool ASTUnit::LoadFromCompilerInvocation(1633    std::shared_ptr<PCHContainerOperations> PCHContainerOps,1634    unsigned PrecompilePreambleAfterNParses,1635    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {1636  if (!Invocation)1637    return true;1638 1639  assert(VFS && "VFS is null");1640 1641  // We'll manage file buffers ourselves.1642  Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;1643  Invocation->getFrontendOpts().DisableFree = false;1644  getDiagnostics().Reset();1645  ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),1646                        *VFS);1647 1648  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;1649  if (PrecompilePreambleAfterNParses > 0) {1650    PreambleRebuildCountdown = PrecompilePreambleAfterNParses;1651    OverrideMainBuffer =1652        getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);1653    getDiagnostics().Reset();1654    ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),1655                          *VFS);1656  }1657 1658  SimpleTimer ParsingTimer(WantTiming);1659  ParsingTimer.setOutput("Parsing " + getMainFileName());1660 1661  // Recover resources if we crash before exiting this method.1662  llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>1663    MemBufferCleanup(OverrideMainBuffer.get());1664 1665  return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);1666}1667 1668std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(1669    std::shared_ptr<CompilerInvocation> CI,1670    std::shared_ptr<PCHContainerOperations> PCHContainerOps,1671    std::shared_ptr<DiagnosticOptions> DiagOpts,1672    IntrusiveRefCntPtr<DiagnosticsEngine> Diags,1673    IntrusiveRefCntPtr<FileManager> FileMgr, bool OnlyLocalDecls,1674    CaptureDiagsKind CaptureDiagnostics,1675    unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,1676    bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,1677    bool UserFilesAreVolatile) {1678  // Create the AST unit.1679  std::unique_ptr<ASTUnit> AST(new ASTUnit(false));1680  ConfigureDiags(Diags, *AST, CaptureDiagnostics);1681  AST->DiagOpts = DiagOpts;1682  AST->Diagnostics = Diags;1683  AST->OnlyLocalDecls = OnlyLocalDecls;1684  AST->CaptureDiagnostics = CaptureDiagnostics;1685  AST->TUKind = TUKind;1686  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;1687  AST->IncludeBriefCommentsInCodeCompletion1688    = IncludeBriefCommentsInCodeCompletion;1689  AST->Invocation = std::move(CI);1690  AST->FileSystemOpts = FileMgr->getFileSystemOpts();1691  AST->FileMgr = FileMgr;1692  AST->UserFilesAreVolatile = UserFilesAreVolatile;1693 1694  // Recover resources if we crash before exiting this method.1695  llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>1696    ASTUnitCleanup(AST.get());1697  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,1698    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>1699    DiagCleanup(Diags.get());1700 1701  if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),1702                                      PrecompilePreambleAfterNParses,1703                                      AST->FileMgr->getVirtualFileSystemPtr()))1704    return nullptr;1705  return AST;1706}1707 1708bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,1709                      ArrayRef<RemappedFile> RemappedFiles,1710                      IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {1711  if (!Invocation)1712    return true;1713 1714  if (!VFS) {1715    assert(FileMgr && "FileMgr is null on Reparse call");1716    VFS = FileMgr->getVirtualFileSystemPtr();1717  }1718 1719  clearFileLevelDecls();1720 1721  SimpleTimer ParsingTimer(WantTiming);1722  ParsingTimer.setOutput("Reparsing " + getMainFileName());1723 1724  // Remap files.1725  PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();1726  for (const auto &RB : PPOpts.RemappedFileBuffers)1727    delete RB.second;1728 1729  Invocation->getPreprocessorOpts().clearRemappedFiles();1730  for (const auto &RemappedFile : RemappedFiles) {1731    Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,1732                                                      RemappedFile.second);1733  }1734 1735  // If we have a preamble file lying around, or if we might try to1736  // build a precompiled preamble, do so now.1737  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;1738  if (Preamble || PreambleRebuildCountdown > 0)1739    OverrideMainBuffer =1740        getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);1741 1742  // Clear out the diagnostics state.1743  FileMgr.reset();1744  getDiagnostics().Reset();1745  ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts(),1746                        *VFS);1747  if (OverrideMainBuffer)1748    getDiagnostics().setNumWarnings(NumWarningsInPreamble);1749 1750  // Parse the sources1751  bool Result =1752      Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);1753 1754  // If we're caching global code-completion results, and the top-level1755  // declarations have changed, clear out the code-completion cache.1756  if (!Result && ShouldCacheCodeCompletionResults &&1757      CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)1758    CacheCodeCompletionResults();1759 1760  // We now need to clear out the completion info related to this translation1761  // unit; it'll be recreated if necessary.1762  CCTUInfo.reset();1763 1764  return Result;1765}1766 1767void ASTUnit::ResetForParse() {1768  SavedMainFileBuffer.reset();1769 1770  SourceMgr.reset();1771  TheSema.reset();1772  Ctx.reset();1773  PP.reset();1774  Reader.reset();1775 1776  TopLevelDecls.clear();1777  clearFileLevelDecls();1778}1779 1780//----------------------------------------------------------------------------//1781// Code completion1782//----------------------------------------------------------------------------//1783 1784namespace {1785 1786  /// Code completion consumer that combines the cached code-completion1787  /// results from an ASTUnit with the code-completion results provided to it,1788  /// then passes the result on to1789  class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {1790    uint64_t NormalContexts;1791    ASTUnit &AST;1792    CodeCompleteConsumer &Next;1793 1794  public:1795    AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,1796                                  const CodeCompleteOptions &CodeCompleteOpts)1797        : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {1798      // Compute the set of contexts in which we will look when we don't have1799      // any information about the specific context.1800      NormalContexts1801        = (1LL << CodeCompletionContext::CCC_TopLevel)1802        | (1LL << CodeCompletionContext::CCC_ObjCInterface)1803        | (1LL << CodeCompletionContext::CCC_ObjCImplementation)1804        | (1LL << CodeCompletionContext::CCC_ObjCIvarList)1805        | (1LL << CodeCompletionContext::CCC_Statement)1806        | (1LL << CodeCompletionContext::CCC_Expression)1807        | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)1808        | (1LL << CodeCompletionContext::CCC_DotMemberAccess)1809        | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess)1810        | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess)1811        | (1LL << CodeCompletionContext::CCC_ObjCProtocolName)1812        | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)1813        | (1LL << CodeCompletionContext::CCC_Recovery);1814 1815      if (AST.getASTContext().getLangOpts().CPlusPlus)1816        NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)1817                       |  (1LL << CodeCompletionContext::CCC_UnionTag)1818                       |  (1LL << CodeCompletionContext::CCC_ClassOrStructTag);1819    }1820 1821    void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,1822                                    CodeCompletionResult *Results,1823                                    unsigned NumResults) override;1824 1825    void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,1826                                   OverloadCandidate *Candidates,1827                                   unsigned NumCandidates,1828                                   SourceLocation OpenParLoc,1829                                   bool Braced) override {1830      Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,1831                                     OpenParLoc, Braced);1832    }1833 1834    CodeCompletionAllocator &getAllocator() override {1835      return Next.getAllocator();1836    }1837 1838    CodeCompletionTUInfo &getCodeCompletionTUInfo() override {1839      return Next.getCodeCompletionTUInfo();1840    }1841  };1842 1843} // namespace1844 1845/// Helper function that computes which global names are hidden by the1846/// local code-completion results.1847static void CalculateHiddenNames(const CodeCompletionContext &Context,1848                                 CodeCompletionResult *Results,1849                                 unsigned NumResults,1850                                 ASTContext &Ctx,1851                          llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){1852  bool OnlyTagNames = false;1853  switch (Context.getKind()) {1854  case CodeCompletionContext::CCC_Recovery:1855  case CodeCompletionContext::CCC_TopLevel:1856  case CodeCompletionContext::CCC_ObjCInterface:1857  case CodeCompletionContext::CCC_ObjCImplementation:1858  case CodeCompletionContext::CCC_ObjCIvarList:1859  case CodeCompletionContext::CCC_ClassStructUnion:1860  case CodeCompletionContext::CCC_Statement:1861  case CodeCompletionContext::CCC_Expression:1862  case CodeCompletionContext::CCC_ObjCMessageReceiver:1863  case CodeCompletionContext::CCC_DotMemberAccess:1864  case CodeCompletionContext::CCC_ArrowMemberAccess:1865  case CodeCompletionContext::CCC_ObjCPropertyAccess:1866  case CodeCompletionContext::CCC_Namespace:1867  case CodeCompletionContext::CCC_Type:1868  case CodeCompletionContext::CCC_Symbol:1869  case CodeCompletionContext::CCC_SymbolOrNewName:1870  case CodeCompletionContext::CCC_ParenthesizedExpression:1871  case CodeCompletionContext::CCC_ObjCInterfaceName:1872  case CodeCompletionContext::CCC_TopLevelOrExpression:1873      break;1874 1875  case CodeCompletionContext::CCC_EnumTag:1876  case CodeCompletionContext::CCC_UnionTag:1877  case CodeCompletionContext::CCC_ClassOrStructTag:1878    OnlyTagNames = true;1879    break;1880 1881  case CodeCompletionContext::CCC_ObjCProtocolName:1882  case CodeCompletionContext::CCC_MacroName:1883  case CodeCompletionContext::CCC_MacroNameUse:1884  case CodeCompletionContext::CCC_PreprocessorExpression:1885  case CodeCompletionContext::CCC_PreprocessorDirective:1886  case CodeCompletionContext::CCC_NaturalLanguage:1887  case CodeCompletionContext::CCC_SelectorName:1888  case CodeCompletionContext::CCC_TypeQualifiers:1889  case CodeCompletionContext::CCC_Other:1890  case CodeCompletionContext::CCC_OtherWithMacros:1891  case CodeCompletionContext::CCC_ObjCInstanceMessage:1892  case CodeCompletionContext::CCC_ObjCClassMessage:1893  case CodeCompletionContext::CCC_ObjCCategoryName:1894  case CodeCompletionContext::CCC_IncludedFile:1895  case CodeCompletionContext::CCC_Attribute:1896  case CodeCompletionContext::CCC_NewName:1897  case CodeCompletionContext::CCC_ObjCClassForwardDecl:1898    // We're looking for nothing, or we're looking for names that cannot1899    // be hidden.1900    return;1901  }1902 1903  using Result = CodeCompletionResult;1904  for (unsigned I = 0; I != NumResults; ++I) {1905    if (Results[I].Kind != Result::RK_Declaration)1906      continue;1907 1908    unsigned IDNS1909      = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();1910 1911    bool Hiding = false;1912    if (OnlyTagNames)1913      Hiding = (IDNS & Decl::IDNS_Tag);1914    else {1915      unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |1916                             Decl::IDNS_Namespace | Decl::IDNS_Ordinary |1917                             Decl::IDNS_NonMemberOperator);1918      if (Ctx.getLangOpts().CPlusPlus)1919        HiddenIDNS |= Decl::IDNS_Tag;1920      Hiding = (IDNS & HiddenIDNS);1921    }1922 1923    if (!Hiding)1924      continue;1925 1926    DeclarationName Name = Results[I].Declaration->getDeclName();1927    if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())1928      HiddenNames.insert(Identifier->getName());1929    else1930      HiddenNames.insert(Name.getAsString());1931  }1932}1933 1934void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,1935                                            CodeCompletionContext Context,1936                                            CodeCompletionResult *Results,1937                                            unsigned NumResults) {1938  // Merge the results we were given with the results we cached.1939  bool AddedResult = false;1940  uint64_t InContexts =1941      Context.getKind() == CodeCompletionContext::CCC_Recovery1942        ? NormalContexts : (1LL << Context.getKind());1943  // Contains the set of names that are hidden by "local" completion results.1944  llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;1945  using Result = CodeCompletionResult;1946  SmallVector<Result, 8> AllResults;1947  for (ASTUnit::cached_completion_iterator1948            C = AST.cached_completion_begin(),1949         CEnd = AST.cached_completion_end();1950       C != CEnd; ++C) {1951    // If the context we are in matches any of the contexts we are1952    // interested in, we'll add this result.1953    if ((C->ShowInContexts & InContexts) == 0)1954      continue;1955 1956    // If we haven't added any results previously, do so now.1957    if (!AddedResult) {1958      CalculateHiddenNames(Context, Results, NumResults, S.Context,1959                           HiddenNames);1960      AllResults.insert(AllResults.end(), Results, Results + NumResults);1961      AddedResult = true;1962    }1963 1964    // Determine whether this global completion result is hidden by a local1965    // completion result. If so, skip it.1966    if (C->Kind != CXCursor_MacroDefinition &&1967        HiddenNames.count(C->Completion->getTypedText()))1968      continue;1969 1970    // Adjust priority based on similar type classes.1971    unsigned Priority = C->Priority;1972    CodeCompletionString *Completion = C->Completion;1973    if (!Context.getPreferredType().isNull()) {1974      if (C->Kind == CXCursor_MacroDefinition) {1975        Priority = getMacroUsagePriority(C->Completion->getTypedText(),1976                                         S.getLangOpts(),1977                               Context.getPreferredType()->isAnyPointerType());1978      } else if (C->Type) {1979        CanQualType Expected1980          = S.Context.getCanonicalType(1981                               Context.getPreferredType().getUnqualifiedType());1982        SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);1983        if (ExpectedSTC == C->TypeClass) {1984          // We know this type is similar; check for an exact match.1985          llvm::StringMap<unsigned> &CachedCompletionTypes1986            = AST.getCachedCompletionTypes();1987          llvm::StringMap<unsigned>::iterator Pos1988            = CachedCompletionTypes.find(QualType(Expected).getAsString());1989          if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)1990            Priority /= CCF_ExactTypeMatch;1991          else1992            Priority /= CCF_SimilarTypeMatch;1993        }1994      }1995    }1996 1997    // Adjust the completion string, if required.1998    if (C->Kind == CXCursor_MacroDefinition &&1999        Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {2000      // Create a new code-completion string that just contains the2001      // macro name, without its arguments.2002      CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),2003                                    CCP_CodePattern, C->Availability);2004      Builder.AddTypedTextChunk(C->Completion->getTypedText());2005      Priority = CCP_CodePattern;2006      Completion = Builder.TakeString();2007    }2008 2009    AllResults.push_back(Result(Completion, Priority, C->Kind,2010                                C->Availability));2011  }2012 2013  // If we did not add any cached completion results, just forward the2014  // results we were given to the next consumer.2015  if (!AddedResult) {2016    Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);2017    return;2018  }2019 2020  Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),2021                                  AllResults.size());2022}2023 2024void ASTUnit::CodeComplete(2025    StringRef File, unsigned Line, unsigned Column,2026    ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,2027    bool IncludeCodePatterns, bool IncludeBriefComments,2028    CodeCompleteConsumer &Consumer,2029    std::shared_ptr<PCHContainerOperations> PCHContainerOps,2030    llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diag, LangOptions &LangOpts,2031    llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr,2032    llvm::IntrusiveRefCntPtr<FileManager> FileMgr,2033    SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,2034    SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,2035    std::unique_ptr<SyntaxOnlyAction> Act) {2036  if (!Invocation)2037    return;2038 2039  SimpleTimer CompletionTimer(WantTiming);2040  CompletionTimer.setOutput("Code completion @ " + File + ":" +2041                            Twine(Line) + ":" + Twine(Column));2042 2043  auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);2044 2045  FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();2046  CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;2047  PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();2048 2049  CodeCompleteOpts.IncludeMacros = IncludeMacros &&2050                                   CachedCompletionResults.empty();2051  CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;2052  CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();2053  CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;2054  CodeCompleteOpts.LoadExternal = Consumer.loadExternal();2055  CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();2056 2057  assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);2058 2059  FrontendOpts.CodeCompletionAt.FileName = std::string(File);2060  FrontendOpts.CodeCompletionAt.Line = Line;2061  FrontendOpts.CodeCompletionAt.Column = Column;2062 2063  // Set the language options appropriately.2064  LangOpts = CCInvocation->getLangOpts();2065 2066  // Spell-checking and warnings are wasteful during code-completion.2067  LangOpts.SpellChecking = false;2068  CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;2069 2070  auto Clang = std::make_unique<CompilerInstance>(std::move(CCInvocation),2071                                                  PCHContainerOps);2072 2073  // Recover resources if we crash before exiting this method.2074  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>2075    CICleanup(Clang.get());2076 2077  auto &Inv = Clang->getInvocation();2078  OriginalSourceFile =2079      std::string(Clang->getFrontendOpts().Inputs[0].getFile());2080 2081  // Set up diagnostics, capturing any diagnostics produced.2082  Clang->setDiagnostics(Diag);2083  CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,2084                                    Clang->getDiagnostics(),2085                                    &StoredDiagnostics, nullptr);2086  ProcessWarningOptions(*Diag, Inv.getDiagnosticOpts(),2087                        FileMgr->getVirtualFileSystem());2088 2089  // Create the target instance.2090  if (!Clang->createTarget()) {2091    return;2092  }2093 2094  assert(Clang->getFrontendOpts().Inputs.size() == 1 &&2095         "Invocation must have exactly one source file!");2096  assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==2097             InputKind::Source &&2098         "FIXME: AST inputs not yet supported here!");2099  assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=2100             Language::LLVM_IR &&2101         "IR inputs not support here!");2102 2103  // Use the source and file managers that we were given.2104  Clang->setVirtualFileSystem(FileMgr->getVirtualFileSystemPtr());2105  Clang->setFileManager(FileMgr);2106  Clang->setSourceManager(SourceMgr);2107 2108  // Remap files.2109  PreprocessorOpts.clearRemappedFiles();2110  PreprocessorOpts.RetainRemappedFileBuffers = true;2111  for (const auto &RemappedFile : RemappedFiles) {2112    PreprocessorOpts.addRemappedFile(RemappedFile.first, RemappedFile.second);2113    OwnedBuffers.push_back(RemappedFile.second);2114  }2115 2116  // Use the code completion consumer we were given, but adding any cached2117  // code-completion results.2118  AugmentedCodeCompleteConsumer *AugmentedConsumer2119    = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);2120  Clang->setCodeCompletionConsumer(AugmentedConsumer);2121 2122  auto getUniqueID =2123      [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {2124    if (auto Status = FileMgr->getVirtualFileSystem().status(Filename))2125      return Status->getUniqueID();2126    return std::nullopt;2127  };2128 2129  auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {2130    if (LHS == RHS)2131      return true;2132    if (auto LHSID = getUniqueID(LHS))2133      if (auto RHSID = getUniqueID(RHS))2134        return *LHSID == *RHSID;2135    return false;2136  };2137 2138  // If we have a precompiled preamble, try to use it. We only allow2139  // the use of the precompiled preamble if we're if the completion2140  // point is within the main file, after the end of the precompiled2141  // preamble.2142  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;2143  if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {2144    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(2145        PCHContainerOps, Inv, FileMgr->getVirtualFileSystemPtr(), false,2146        Line - 1);2147  }2148 2149  // If the main file has been overridden due to the use of a preamble,2150  // make that override happen and introduce the preamble.2151  if (OverrideMainBuffer) {2152    assert(Preamble &&2153           "No preamble was built, but OverrideMainBuffer is not null");2154 2155    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =2156        FileMgr->getVirtualFileSystemPtr();2157    Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,2158                                  OverrideMainBuffer.get());2159    // FIXME: there is no way to update VFS if it was changed by2160    // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.2161    // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the2162    // PCH files are always readable.2163    OwnedBuffers.push_back(OverrideMainBuffer.release());2164  } else {2165    PreprocessorOpts.PrecompiledPreambleBytes.first = 0;2166    PreprocessorOpts.PrecompiledPreambleBytes.second = false;2167  }2168 2169  // Disable the preprocessing record if modules are not enabled.2170  if (!Clang->getLangOpts().Modules)2171    PreprocessorOpts.DetailedRecord = false;2172 2173  if (!Act)2174    Act.reset(new SyntaxOnlyAction);2175 2176  if (Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {2177    if (llvm::Error Err = Act->Execute()) {2178      consumeError(std::move(Err)); // FIXME this drops errors on the floor.2179    }2180    Act->EndSourceFile();2181  }2182}2183 2184bool ASTUnit::Save(StringRef File) {2185  if (HadModuleLoaderFatalFailure)2186    return true;2187 2188  // FIXME: Can we somehow regenerate the stat cache here, or do we need to2189  // unconditionally create a stat cache when we parse the file?2190 2191  if (llvm::Error Err = llvm::writeToOutput(2192          File, [this](llvm::raw_ostream &Out) {2193            return serialize(Out) ? llvm::make_error<llvm::StringError>(2194                                        "ASTUnit serialization failed",2195                                        llvm::inconvertibleErrorCode())2196                                  : llvm::Error::success();2197          })) {2198    consumeError(std::move(Err));2199    return true;2200  }2201  return false;2202}2203 2204static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,2205                          Sema &S, raw_ostream &OS) {2206  Writer.WriteAST(&S, std::string(), nullptr, "");2207 2208  // Write the generated bitstream to "Out".2209  if (!Buffer.empty())2210    OS.write(Buffer.data(), Buffer.size());2211 2212  return false;2213}2214 2215bool ASTUnit::serialize(raw_ostream &OS) {2216  if (WriterData)2217    return serializeUnit(WriterData->Writer, WriterData->Buffer, getSema(), OS);2218 2219  SmallString<128> Buffer;2220  llvm::BitstreamWriter Stream(Buffer);2221  IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();2222  ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});2223  return serializeUnit(Writer, Buffer, getSema(), OS);2224}2225 2226void ASTUnit::addFileLevelDecl(Decl *D) {2227  assert(D);2228 2229  // We only care about local declarations.2230  if (D->isFromASTFile())2231    return;2232 2233  SourceManager &SM = *SourceMgr;2234  SourceLocation Loc = D->getLocation();2235  if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))2236    return;2237 2238  // We only keep track of the file-level declarations of each file.2239  if (!D->getLexicalDeclContext()->isFileContext())2240    return;2241 2242  SourceLocation FileLoc = SM.getFileLoc(Loc);2243  assert(SM.isLocalSourceLocation(FileLoc));2244  auto [FID, Offset] = SM.getDecomposedLoc(FileLoc);2245  if (FID.isInvalid())2246    return;2247 2248  std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];2249  if (!Decls)2250    Decls = std::make_unique<LocDeclsTy>();2251 2252  std::pair<unsigned, Decl *> LocDecl(Offset, D);2253 2254  if (Decls->empty() || Decls->back().first <= Offset) {2255    Decls->push_back(LocDecl);2256    return;2257  }2258 2259  LocDeclsTy::iterator I =2260      llvm::upper_bound(*Decls, LocDecl, llvm::less_first());2261 2262  Decls->insert(I, LocDecl);2263}2264 2265void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,2266                                  SmallVectorImpl<Decl *> &Decls) {2267  if (File.isInvalid())2268    return;2269 2270  if (SourceMgr->isLoadedFileID(File)) {2271    assert(Ctx->getExternalSource() && "No external source!");2272    return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,2273                                                         Decls);2274  }2275 2276  FileDeclsTy::iterator I = FileDecls.find(File);2277  if (I == FileDecls.end())2278    return;2279 2280  LocDeclsTy &LocDecls = *I->second;2281  if (LocDecls.empty())2282    return;2283 2284  LocDeclsTy::iterator BeginIt =2285      llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {2286        return LD.first < Offset;2287      });2288  if (BeginIt != LocDecls.begin())2289    --BeginIt;2290 2291  // If we are pointing at a top-level decl inside an objc container, we need2292  // to backtrack until we find it otherwise we will fail to report that the2293  // region overlaps with an objc container.2294  while (BeginIt != LocDecls.begin() &&2295         BeginIt->second->isTopLevelDeclInObjCContainer())2296    --BeginIt;2297 2298  LocDeclsTy::iterator EndIt = llvm::upper_bound(2299      LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),2300      llvm::less_first());2301  if (EndIt != LocDecls.end())2302    ++EndIt;2303 2304  for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)2305    Decls.push_back(DIt->second);2306}2307 2308SourceLocation ASTUnit::getLocation(const FileEntry *File,2309                                    unsigned Line, unsigned Col) const {2310  const SourceManager &SM = getSourceManager();2311  SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);2312  return SM.getMacroArgExpandedLocation(Loc);2313}2314 2315SourceLocation ASTUnit::getLocation(const FileEntry *File,2316                                    unsigned Offset) const {2317  const SourceManager &SM = getSourceManager();2318  SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);2319  return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));2320}2321 2322/// If \arg Loc is a loaded location from the preamble, returns2323/// the corresponding local location of the main file, otherwise it returns2324/// \arg Loc.2325SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {2326  FileID PreambleID;2327  if (SourceMgr)2328    PreambleID = SourceMgr->getPreambleFileID();2329 2330  if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())2331    return Loc;2332 2333  unsigned Offs;2334  if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {2335    SourceLocation FileLoc2336        = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());2337    return FileLoc.getLocWithOffset(Offs);2338  }2339 2340  return Loc;2341}2342 2343/// If \arg Loc is a local location of the main file but inside the2344/// preamble chunk, returns the corresponding loaded location from the2345/// preamble, otherwise it returns \arg Loc.2346SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) const {2347  FileID PreambleID;2348  if (SourceMgr)2349    PreambleID = SourceMgr->getPreambleFileID();2350 2351  if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())2352    return Loc;2353 2354  unsigned Offs;2355  if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&2356      Offs < Preamble->getBounds().Size) {2357    SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);2358    return FileLoc.getLocWithOffset(Offs);2359  }2360 2361  return Loc;2362}2363 2364bool ASTUnit::isInPreambleFileID(SourceLocation Loc) const {2365  FileID FID;2366  if (SourceMgr)2367    FID = SourceMgr->getPreambleFileID();2368 2369  if (Loc.isInvalid() || FID.isInvalid())2370    return false;2371 2372  return SourceMgr->isInFileID(Loc, FID);2373}2374 2375bool ASTUnit::isInMainFileID(SourceLocation Loc) const {2376  FileID FID;2377  if (SourceMgr)2378    FID = SourceMgr->getMainFileID();2379 2380  if (Loc.isInvalid() || FID.isInvalid())2381    return false;2382 2383  return SourceMgr->isInFileID(Loc, FID);2384}2385 2386SourceLocation ASTUnit::getEndOfPreambleFileID() const {2387  FileID FID;2388  if (SourceMgr)2389    FID = SourceMgr->getPreambleFileID();2390 2391  if (FID.isInvalid())2392    return {};2393 2394  return SourceMgr->getLocForEndOfFile(FID);2395}2396 2397SourceLocation ASTUnit::getStartOfMainFileID() const {2398  FileID FID;2399  if (SourceMgr)2400    FID = SourceMgr->getMainFileID();2401 2402  if (FID.isInvalid())2403    return {};2404 2405  return SourceMgr->getLocForStartOfFile(FID);2406}2407 2408llvm::iterator_range<PreprocessingRecord::iterator>2409ASTUnit::getLocalPreprocessingEntities() const {2410  if (isMainFileAST()) {2411    serialization::ModuleFile &2412      Mod = Reader->getModuleManager().getPrimaryModule();2413    return Reader->getModulePreprocessedEntities(Mod);2414  }2415 2416  if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())2417    return llvm::make_range(PPRec->local_begin(), PPRec->local_end());2418 2419  return llvm::make_range(PreprocessingRecord::iterator(),2420                          PreprocessingRecord::iterator());2421}2422 2423bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {2424  if (isMainFileAST()) {2425    serialization::ModuleFile &2426      Mod = Reader->getModuleManager().getPrimaryModule();2427    for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {2428      if (!Fn(context, D))2429        return false;2430    }2431 2432    return true;2433  }2434 2435  for (ASTUnit::top_level_iterator TL = top_level_begin(),2436                                TLEnd = top_level_end();2437         TL != TLEnd; ++TL) {2438    if (!Fn(context, *TL))2439      return false;2440  }2441 2442  return true;2443}2444 2445OptionalFileEntryRef ASTUnit::getPCHFile() {2446  if (!Reader)2447    return std::nullopt;2448 2449  serialization::ModuleFile *Mod = nullptr;2450  Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {2451    switch (M.Kind) {2452    case serialization::MK_ImplicitModule:2453    case serialization::MK_ExplicitModule:2454    case serialization::MK_PrebuiltModule:2455      return true; // skip dependencies.2456    case serialization::MK_PCH:2457      Mod = &M;2458      return true; // found it.2459    case serialization::MK_Preamble:2460      return false; // look in dependencies.2461    case serialization::MK_MainFile:2462      return false; // look in dependencies.2463    }2464 2465    return true;2466  });2467  if (Mod)2468    return Mod->File;2469 2470  return std::nullopt;2471}2472 2473bool ASTUnit::isModuleFile() const {2474  return isMainFileAST() && getLangOpts().isCompilingModule();2475}2476 2477InputKind ASTUnit::getInputKind() const {2478  auto &LangOpts = getLangOpts();2479 2480  Language Lang;2481  if (LangOpts.OpenCL)2482    Lang = Language::OpenCL;2483  else if (LangOpts.CUDA)2484    Lang = Language::CUDA;2485  else if (LangOpts.CPlusPlus)2486    Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;2487  else2488    Lang = LangOpts.ObjC ? Language::ObjC : Language::C;2489 2490  InputKind::Format Fmt = InputKind::Source;2491  if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)2492    Fmt = InputKind::ModuleMap;2493 2494  // We don't know if input was preprocessed. Assume not.2495  bool PP = false;2496 2497  return InputKind(Lang, Fmt, PP);2498}2499 2500#ifndef NDEBUG2501ASTUnit::ConcurrencyState::ConcurrencyState() {2502  Mutex = new std::recursive_mutex;2503}2504 2505ASTUnit::ConcurrencyState::~ConcurrencyState() {2506  delete static_cast<std::recursive_mutex *>(Mutex);2507}2508 2509void ASTUnit::ConcurrencyState::start() {2510  bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();2511  assert(acquired && "Concurrent access to ASTUnit!");2512}2513 2514void ASTUnit::ConcurrencyState::finish() {2515  static_cast<std::recursive_mutex *>(Mutex)->unlock();2516}2517 2518#else // NDEBUG2519 2520ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }2521ASTUnit::ConcurrencyState::~ConcurrencyState() {}2522void ASTUnit::ConcurrencyState::start() {}2523void ASTUnit::ConcurrencyState::finish() {}2524 2525#endif // NDEBUG2526