xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Frontend/ASTUnit.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===- ASTUnit.cpp - ASTUnit utility --------------------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // ASTUnit Implementation.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "clang/Frontend/ASTUnit.h"
147330f729Sjoerg #include "clang/AST/ASTConsumer.h"
157330f729Sjoerg #include "clang/AST/ASTContext.h"
167330f729Sjoerg #include "clang/AST/CommentCommandTraits.h"
177330f729Sjoerg #include "clang/AST/Decl.h"
187330f729Sjoerg #include "clang/AST/DeclBase.h"
197330f729Sjoerg #include "clang/AST/DeclCXX.h"
207330f729Sjoerg #include "clang/AST/DeclGroup.h"
217330f729Sjoerg #include "clang/AST/DeclObjC.h"
227330f729Sjoerg #include "clang/AST/DeclTemplate.h"
237330f729Sjoerg #include "clang/AST/DeclarationName.h"
247330f729Sjoerg #include "clang/AST/ExternalASTSource.h"
257330f729Sjoerg #include "clang/AST/PrettyPrinter.h"
267330f729Sjoerg #include "clang/AST/Type.h"
277330f729Sjoerg #include "clang/AST/TypeOrdering.h"
287330f729Sjoerg #include "clang/Basic/Diagnostic.h"
297330f729Sjoerg #include "clang/Basic/FileManager.h"
307330f729Sjoerg #include "clang/Basic/IdentifierTable.h"
317330f729Sjoerg #include "clang/Basic/LLVM.h"
327330f729Sjoerg #include "clang/Basic/LangOptions.h"
337330f729Sjoerg #include "clang/Basic/LangStandard.h"
347330f729Sjoerg #include "clang/Basic/Module.h"
357330f729Sjoerg #include "clang/Basic/SourceLocation.h"
367330f729Sjoerg #include "clang/Basic/SourceManager.h"
377330f729Sjoerg #include "clang/Basic/TargetInfo.h"
387330f729Sjoerg #include "clang/Basic/TargetOptions.h"
397330f729Sjoerg #include "clang/Frontend/CompilerInstance.h"
407330f729Sjoerg #include "clang/Frontend/CompilerInvocation.h"
417330f729Sjoerg #include "clang/Frontend/FrontendAction.h"
427330f729Sjoerg #include "clang/Frontend/FrontendActions.h"
437330f729Sjoerg #include "clang/Frontend/FrontendDiagnostic.h"
447330f729Sjoerg #include "clang/Frontend/FrontendOptions.h"
457330f729Sjoerg #include "clang/Frontend/MultiplexConsumer.h"
467330f729Sjoerg #include "clang/Frontend/PrecompiledPreamble.h"
477330f729Sjoerg #include "clang/Frontend/Utils.h"
487330f729Sjoerg #include "clang/Lex/HeaderSearch.h"
497330f729Sjoerg #include "clang/Lex/HeaderSearchOptions.h"
507330f729Sjoerg #include "clang/Lex/Lexer.h"
517330f729Sjoerg #include "clang/Lex/PPCallbacks.h"
527330f729Sjoerg #include "clang/Lex/PreprocessingRecord.h"
537330f729Sjoerg #include "clang/Lex/Preprocessor.h"
547330f729Sjoerg #include "clang/Lex/PreprocessorOptions.h"
557330f729Sjoerg #include "clang/Lex/Token.h"
567330f729Sjoerg #include "clang/Sema/CodeCompleteConsumer.h"
577330f729Sjoerg #include "clang/Sema/CodeCompleteOptions.h"
587330f729Sjoerg #include "clang/Sema/Sema.h"
597330f729Sjoerg #include "clang/Serialization/ASTBitCodes.h"
607330f729Sjoerg #include "clang/Serialization/ASTReader.h"
617330f729Sjoerg #include "clang/Serialization/ASTWriter.h"
627330f729Sjoerg #include "clang/Serialization/ContinuousRangeMap.h"
637330f729Sjoerg #include "clang/Serialization/InMemoryModuleCache.h"
64*e038c9c4Sjoerg #include "clang/Serialization/ModuleFile.h"
657330f729Sjoerg #include "clang/Serialization/PCHContainerOperations.h"
667330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
677330f729Sjoerg #include "llvm/ADT/DenseMap.h"
687330f729Sjoerg #include "llvm/ADT/IntrusiveRefCntPtr.h"
697330f729Sjoerg #include "llvm/ADT/None.h"
707330f729Sjoerg #include "llvm/ADT/Optional.h"
717330f729Sjoerg #include "llvm/ADT/STLExtras.h"
72*e038c9c4Sjoerg #include "llvm/ADT/ScopeExit.h"
737330f729Sjoerg #include "llvm/ADT/SmallString.h"
747330f729Sjoerg #include "llvm/ADT/SmallVector.h"
757330f729Sjoerg #include "llvm/ADT/StringMap.h"
767330f729Sjoerg #include "llvm/ADT/StringRef.h"
777330f729Sjoerg #include "llvm/ADT/StringSet.h"
787330f729Sjoerg #include "llvm/ADT/Twine.h"
797330f729Sjoerg #include "llvm/ADT/iterator_range.h"
807330f729Sjoerg #include "llvm/Bitstream/BitstreamWriter.h"
817330f729Sjoerg #include "llvm/Support/Allocator.h"
827330f729Sjoerg #include "llvm/Support/Casting.h"
837330f729Sjoerg #include "llvm/Support/CrashRecoveryContext.h"
847330f729Sjoerg #include "llvm/Support/DJB.h"
857330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
867330f729Sjoerg #include "llvm/Support/ErrorOr.h"
877330f729Sjoerg #include "llvm/Support/FileSystem.h"
887330f729Sjoerg #include "llvm/Support/FileUtilities.h"
897330f729Sjoerg #include "llvm/Support/MemoryBuffer.h"
907330f729Sjoerg #include "llvm/Support/Timer.h"
917330f729Sjoerg #include "llvm/Support/VirtualFileSystem.h"
927330f729Sjoerg #include "llvm/Support/raw_ostream.h"
937330f729Sjoerg #include <algorithm>
947330f729Sjoerg #include <atomic>
957330f729Sjoerg #include <cassert>
967330f729Sjoerg #include <cstdint>
977330f729Sjoerg #include <cstdio>
987330f729Sjoerg #include <cstdlib>
997330f729Sjoerg #include <memory>
1007330f729Sjoerg #include <mutex>
1017330f729Sjoerg #include <string>
1027330f729Sjoerg #include <tuple>
1037330f729Sjoerg #include <utility>
1047330f729Sjoerg #include <vector>
1057330f729Sjoerg 
1067330f729Sjoerg using namespace clang;
1077330f729Sjoerg 
1087330f729Sjoerg using llvm::TimeRecord;
1097330f729Sjoerg 
1107330f729Sjoerg namespace {
1117330f729Sjoerg 
1127330f729Sjoerg   class SimpleTimer {
1137330f729Sjoerg     bool WantTiming;
1147330f729Sjoerg     TimeRecord Start;
1157330f729Sjoerg     std::string Output;
1167330f729Sjoerg 
1177330f729Sjoerg   public:
SimpleTimer(bool WantTiming)1187330f729Sjoerg     explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {
1197330f729Sjoerg       if (WantTiming)
1207330f729Sjoerg         Start = TimeRecord::getCurrentTime();
1217330f729Sjoerg     }
1227330f729Sjoerg 
~SimpleTimer()1237330f729Sjoerg     ~SimpleTimer() {
1247330f729Sjoerg       if (WantTiming) {
1257330f729Sjoerg         TimeRecord Elapsed = TimeRecord::getCurrentTime();
1267330f729Sjoerg         Elapsed -= Start;
1277330f729Sjoerg         llvm::errs() << Output << ':';
1287330f729Sjoerg         Elapsed.print(Elapsed, llvm::errs());
1297330f729Sjoerg         llvm::errs() << '\n';
1307330f729Sjoerg       }
1317330f729Sjoerg     }
1327330f729Sjoerg 
setOutput(const Twine & Output)1337330f729Sjoerg     void setOutput(const Twine &Output) {
1347330f729Sjoerg       if (WantTiming)
1357330f729Sjoerg         this->Output = Output.str();
1367330f729Sjoerg     }
1377330f729Sjoerg   };
1387330f729Sjoerg 
1397330f729Sjoerg } // namespace
1407330f729Sjoerg 
1417330f729Sjoerg template <class T>
valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val)1427330f729Sjoerg static std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
1437330f729Sjoerg   if (!Val)
1447330f729Sjoerg     return nullptr;
1457330f729Sjoerg   return std::move(*Val);
1467330f729Sjoerg }
1477330f729Sjoerg 
1487330f729Sjoerg template <class T>
moveOnNoError(llvm::ErrorOr<T> Val,T & Output)1497330f729Sjoerg static bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
1507330f729Sjoerg   if (!Val)
1517330f729Sjoerg     return false;
1527330f729Sjoerg   Output = std::move(*Val);
1537330f729Sjoerg   return true;
1547330f729Sjoerg }
1557330f729Sjoerg 
1567330f729Sjoerg /// Get a source buffer for \p MainFilePath, handling all file-to-file
1577330f729Sjoerg /// and file-to-buffer remappings inside \p Invocation.
1587330f729Sjoerg static std::unique_ptr<llvm::MemoryBuffer>
getBufferForFileHandlingRemapping(const CompilerInvocation & Invocation,llvm::vfs::FileSystem * VFS,StringRef FilePath,bool isVolatile)1597330f729Sjoerg getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
1607330f729Sjoerg                                   llvm::vfs::FileSystem *VFS,
1617330f729Sjoerg                                   StringRef FilePath, bool isVolatile) {
1627330f729Sjoerg   const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
1637330f729Sjoerg 
1647330f729Sjoerg   // Try to determine if the main file has been remapped, either from the
1657330f729Sjoerg   // command line (to another file) or directly through the compiler
1667330f729Sjoerg   // invocation (to a memory buffer).
1677330f729Sjoerg   llvm::MemoryBuffer *Buffer = nullptr;
1687330f729Sjoerg   std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
1697330f729Sjoerg   auto FileStatus = VFS->status(FilePath);
1707330f729Sjoerg   if (FileStatus) {
1717330f729Sjoerg     llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();
1727330f729Sjoerg 
1737330f729Sjoerg     // Check whether there is a file-file remapping of the main file
1747330f729Sjoerg     for (const auto &RF : PreprocessorOpts.RemappedFiles) {
1757330f729Sjoerg       std::string MPath(RF.first);
1767330f729Sjoerg       auto MPathStatus = VFS->status(MPath);
1777330f729Sjoerg       if (MPathStatus) {
1787330f729Sjoerg         llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
1797330f729Sjoerg         if (MainFileID == MID) {
1807330f729Sjoerg           // We found a remapping. Try to load the resulting, remapped source.
1817330f729Sjoerg           BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second, -1, true, isVolatile));
1827330f729Sjoerg           if (!BufferOwner)
1837330f729Sjoerg             return nullptr;
1847330f729Sjoerg         }
1857330f729Sjoerg       }
1867330f729Sjoerg     }
1877330f729Sjoerg 
1887330f729Sjoerg     // Check whether there is a file-buffer remapping. It supercedes the
1897330f729Sjoerg     // file-file remapping.
1907330f729Sjoerg     for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
1917330f729Sjoerg       std::string MPath(RB.first);
1927330f729Sjoerg       auto MPathStatus = VFS->status(MPath);
1937330f729Sjoerg       if (MPathStatus) {
1947330f729Sjoerg         llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
1957330f729Sjoerg         if (MainFileID == MID) {
1967330f729Sjoerg           // We found a remapping.
1977330f729Sjoerg           BufferOwner.reset();
1987330f729Sjoerg           Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
1997330f729Sjoerg         }
2007330f729Sjoerg       }
2017330f729Sjoerg     }
2027330f729Sjoerg   }
2037330f729Sjoerg 
2047330f729Sjoerg   // If the main source file was not remapped, load it now.
2057330f729Sjoerg   if (!Buffer && !BufferOwner) {
2067330f729Sjoerg     BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));
2077330f729Sjoerg     if (!BufferOwner)
2087330f729Sjoerg       return nullptr;
2097330f729Sjoerg   }
2107330f729Sjoerg 
2117330f729Sjoerg   if (BufferOwner)
2127330f729Sjoerg     return BufferOwner;
2137330f729Sjoerg   if (!Buffer)
2147330f729Sjoerg     return nullptr;
2157330f729Sjoerg   return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
2167330f729Sjoerg }
2177330f729Sjoerg 
2187330f729Sjoerg struct ASTUnit::ASTWriterData {
2197330f729Sjoerg   SmallString<128> Buffer;
2207330f729Sjoerg   llvm::BitstreamWriter Stream;
2217330f729Sjoerg   ASTWriter Writer;
2227330f729Sjoerg 
ASTWriterDataASTUnit::ASTWriterData2237330f729Sjoerg   ASTWriterData(InMemoryModuleCache &ModuleCache)
2247330f729Sjoerg       : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
2257330f729Sjoerg };
2267330f729Sjoerg 
clearFileLevelDecls()2277330f729Sjoerg void ASTUnit::clearFileLevelDecls() {
228*e038c9c4Sjoerg   FileDecls.clear();
2297330f729Sjoerg }
2307330f729Sjoerg 
2317330f729Sjoerg /// After failing to build a precompiled preamble (due to
2327330f729Sjoerg /// errors in the source that occurs in the preamble), the number of
2337330f729Sjoerg /// reparses during which we'll skip even trying to precompile the
2347330f729Sjoerg /// preamble.
2357330f729Sjoerg const unsigned DefaultPreambleRebuildInterval = 5;
2367330f729Sjoerg 
2377330f729Sjoerg /// Tracks the number of ASTUnit objects that are currently active.
2387330f729Sjoerg ///
2397330f729Sjoerg /// Used for debugging purposes only.
2407330f729Sjoerg static std::atomic<unsigned> ActiveASTUnitObjects;
2417330f729Sjoerg 
ASTUnit(bool _MainFileIsAST)2427330f729Sjoerg ASTUnit::ASTUnit(bool _MainFileIsAST)
2437330f729Sjoerg     : MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),
2447330f729Sjoerg       ShouldCacheCodeCompletionResults(false),
2457330f729Sjoerg       IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
2467330f729Sjoerg       UnsafeToFree(false) {
2477330f729Sjoerg   if (getenv("LIBCLANG_OBJTRACKING"))
2487330f729Sjoerg     fprintf(stderr, "+++ %u translation units\n", ++ActiveASTUnitObjects);
2497330f729Sjoerg }
2507330f729Sjoerg 
~ASTUnit()2517330f729Sjoerg ASTUnit::~ASTUnit() {
2527330f729Sjoerg   // If we loaded from an AST file, balance out the BeginSourceFile call.
2537330f729Sjoerg   if (MainFileIsAST && getDiagnostics().getClient()) {
2547330f729Sjoerg     getDiagnostics().getClient()->EndSourceFile();
2557330f729Sjoerg   }
2567330f729Sjoerg 
2577330f729Sjoerg   clearFileLevelDecls();
2587330f729Sjoerg 
2597330f729Sjoerg   // Free the buffers associated with remapped files. We are required to
2607330f729Sjoerg   // perform this operation here because we explicitly request that the
2617330f729Sjoerg   // compiler instance *not* free these buffers for each invocation of the
2627330f729Sjoerg   // parser.
2637330f729Sjoerg   if (Invocation && OwnsRemappedFileBuffers) {
2647330f729Sjoerg     PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
2657330f729Sjoerg     for (const auto &RB : PPOpts.RemappedFileBuffers)
2667330f729Sjoerg       delete RB.second;
2677330f729Sjoerg   }
2687330f729Sjoerg 
2697330f729Sjoerg   ClearCachedCompletionResults();
2707330f729Sjoerg 
2717330f729Sjoerg   if (getenv("LIBCLANG_OBJTRACKING"))
2727330f729Sjoerg     fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects);
2737330f729Sjoerg }
2747330f729Sjoerg 
setPreprocessor(std::shared_ptr<Preprocessor> PP)2757330f729Sjoerg void ASTUnit::setPreprocessor(std::shared_ptr<Preprocessor> PP) {
2767330f729Sjoerg   this->PP = std::move(PP);
2777330f729Sjoerg }
2787330f729Sjoerg 
enableSourceFileDiagnostics()2797330f729Sjoerg void ASTUnit::enableSourceFileDiagnostics() {
2807330f729Sjoerg   assert(getDiagnostics().getClient() && Ctx &&
2817330f729Sjoerg       "Bad context for source file");
2827330f729Sjoerg   getDiagnostics().getClient()->BeginSourceFile(Ctx->getLangOpts(), PP.get());
2837330f729Sjoerg }
2847330f729Sjoerg 
2857330f729Sjoerg /// Determine the set of code-completion contexts in which this
2867330f729Sjoerg /// declaration should be shown.
getDeclShowContexts(const NamedDecl * ND,const LangOptions & LangOpts,bool & IsNestedNameSpecifier)2877330f729Sjoerg static uint64_t getDeclShowContexts(const NamedDecl *ND,
2887330f729Sjoerg                                     const LangOptions &LangOpts,
2897330f729Sjoerg                                     bool &IsNestedNameSpecifier) {
2907330f729Sjoerg   IsNestedNameSpecifier = false;
2917330f729Sjoerg 
2927330f729Sjoerg   if (isa<UsingShadowDecl>(ND))
2937330f729Sjoerg     ND = ND->getUnderlyingDecl();
2947330f729Sjoerg   if (!ND)
2957330f729Sjoerg     return 0;
2967330f729Sjoerg 
2977330f729Sjoerg   uint64_t Contexts = 0;
2987330f729Sjoerg   if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||
2997330f729Sjoerg       isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) ||
3007330f729Sjoerg       isa<TypeAliasTemplateDecl>(ND)) {
3017330f729Sjoerg     // Types can appear in these contexts.
3027330f729Sjoerg     if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
3037330f729Sjoerg       Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
3047330f729Sjoerg                |  (1LL << CodeCompletionContext::CCC_ObjCIvarList)
3057330f729Sjoerg                |  (1LL << CodeCompletionContext::CCC_ClassStructUnion)
3067330f729Sjoerg                |  (1LL << CodeCompletionContext::CCC_Statement)
3077330f729Sjoerg                |  (1LL << CodeCompletionContext::CCC_Type)
3087330f729Sjoerg                |  (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
3097330f729Sjoerg 
3107330f729Sjoerg     // In C++, types can appear in expressions contexts (for functional casts).
3117330f729Sjoerg     if (LangOpts.CPlusPlus)
3127330f729Sjoerg       Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
3137330f729Sjoerg 
3147330f729Sjoerg     // In Objective-C, message sends can send interfaces. In Objective-C++,
3157330f729Sjoerg     // all types are available due to functional casts.
3167330f729Sjoerg     if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
3177330f729Sjoerg       Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
3187330f729Sjoerg 
3197330f729Sjoerg     // In Objective-C, you can only be a subclass of another Objective-C class
3207330f729Sjoerg     if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
3217330f729Sjoerg       // Objective-C interfaces can be used in a class property expression.
3227330f729Sjoerg       if (ID->getDefinition())
3237330f729Sjoerg         Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
3247330f729Sjoerg       Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
3257330f729Sjoerg     }
3267330f729Sjoerg 
3277330f729Sjoerg     // Deal with tag names.
3287330f729Sjoerg     if (isa<EnumDecl>(ND)) {
3297330f729Sjoerg       Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);
3307330f729Sjoerg 
3317330f729Sjoerg       // Part of the nested-name-specifier in C++0x.
3327330f729Sjoerg       if (LangOpts.CPlusPlus11)
3337330f729Sjoerg         IsNestedNameSpecifier = true;
3347330f729Sjoerg     } else if (const auto *Record = dyn_cast<RecordDecl>(ND)) {
3357330f729Sjoerg       if (Record->isUnion())
3367330f729Sjoerg         Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);
3377330f729Sjoerg       else
3387330f729Sjoerg         Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
3397330f729Sjoerg 
3407330f729Sjoerg       if (LangOpts.CPlusPlus)
3417330f729Sjoerg         IsNestedNameSpecifier = true;
3427330f729Sjoerg     } else if (isa<ClassTemplateDecl>(ND))
3437330f729Sjoerg       IsNestedNameSpecifier = true;
3447330f729Sjoerg   } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
3457330f729Sjoerg     // Values can appear in these contexts.
3467330f729Sjoerg     Contexts = (1LL << CodeCompletionContext::CCC_Statement)
3477330f729Sjoerg              | (1LL << CodeCompletionContext::CCC_Expression)
3487330f729Sjoerg              | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
3497330f729Sjoerg              | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
3507330f729Sjoerg   } else if (isa<ObjCProtocolDecl>(ND)) {
3517330f729Sjoerg     Contexts = (1LL << CodeCompletionContext::CCC_ObjCProtocolName);
3527330f729Sjoerg   } else if (isa<ObjCCategoryDecl>(ND)) {
3537330f729Sjoerg     Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName);
3547330f729Sjoerg   } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
3557330f729Sjoerg     Contexts = (1LL << CodeCompletionContext::CCC_Namespace);
3567330f729Sjoerg 
3577330f729Sjoerg     // Part of the nested-name-specifier.
3587330f729Sjoerg     IsNestedNameSpecifier = true;
3597330f729Sjoerg   }
3607330f729Sjoerg 
3617330f729Sjoerg   return Contexts;
3627330f729Sjoerg }
3637330f729Sjoerg 
CacheCodeCompletionResults()3647330f729Sjoerg void ASTUnit::CacheCodeCompletionResults() {
3657330f729Sjoerg   if (!TheSema)
3667330f729Sjoerg     return;
3677330f729Sjoerg 
3687330f729Sjoerg   SimpleTimer Timer(WantTiming);
3697330f729Sjoerg   Timer.setOutput("Cache global code completions for " + getMainFileName());
3707330f729Sjoerg 
3717330f729Sjoerg   // Clear out the previous results.
3727330f729Sjoerg   ClearCachedCompletionResults();
3737330f729Sjoerg 
3747330f729Sjoerg   // Gather the set of global code completions.
3757330f729Sjoerg   using Result = CodeCompletionResult;
3767330f729Sjoerg   SmallVector<Result, 8> Results;
3777330f729Sjoerg   CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
3787330f729Sjoerg   CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
3797330f729Sjoerg   TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
3807330f729Sjoerg                                        CCTUInfo, Results);
3817330f729Sjoerg 
3827330f729Sjoerg   // Translate global code completions into cached completions.
3837330f729Sjoerg   llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
3847330f729Sjoerg   CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel);
3857330f729Sjoerg 
3867330f729Sjoerg   for (auto &R : Results) {
3877330f729Sjoerg     switch (R.Kind) {
3887330f729Sjoerg     case Result::RK_Declaration: {
3897330f729Sjoerg       bool IsNestedNameSpecifier = false;
3907330f729Sjoerg       CachedCodeCompletionResult CachedResult;
3917330f729Sjoerg       CachedResult.Completion = R.CreateCodeCompletionString(
3927330f729Sjoerg           *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
3937330f729Sjoerg           IncludeBriefCommentsInCodeCompletion);
3947330f729Sjoerg       CachedResult.ShowInContexts = getDeclShowContexts(
3957330f729Sjoerg           R.Declaration, Ctx->getLangOpts(), IsNestedNameSpecifier);
3967330f729Sjoerg       CachedResult.Priority = R.Priority;
3977330f729Sjoerg       CachedResult.Kind = R.CursorKind;
3987330f729Sjoerg       CachedResult.Availability = R.Availability;
3997330f729Sjoerg 
4007330f729Sjoerg       // Keep track of the type of this completion in an ASTContext-agnostic
4017330f729Sjoerg       // way.
4027330f729Sjoerg       QualType UsageType = getDeclUsageType(*Ctx, R.Declaration);
4037330f729Sjoerg       if (UsageType.isNull()) {
4047330f729Sjoerg         CachedResult.TypeClass = STC_Void;
4057330f729Sjoerg         CachedResult.Type = 0;
4067330f729Sjoerg       } else {
4077330f729Sjoerg         CanQualType CanUsageType
4087330f729Sjoerg           = Ctx->getCanonicalType(UsageType.getUnqualifiedType());
4097330f729Sjoerg         CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);
4107330f729Sjoerg 
4117330f729Sjoerg         // Determine whether we have already seen this type. If so, we save
4127330f729Sjoerg         // ourselves the work of formatting the type string by using the
4137330f729Sjoerg         // temporary, CanQualType-based hash table to find the associated value.
4147330f729Sjoerg         unsigned &TypeValue = CompletionTypes[CanUsageType];
4157330f729Sjoerg         if (TypeValue == 0) {
4167330f729Sjoerg           TypeValue = CompletionTypes.size();
4177330f729Sjoerg           CachedCompletionTypes[QualType(CanUsageType).getAsString()]
4187330f729Sjoerg             = TypeValue;
4197330f729Sjoerg         }
4207330f729Sjoerg 
4217330f729Sjoerg         CachedResult.Type = TypeValue;
4227330f729Sjoerg       }
4237330f729Sjoerg 
4247330f729Sjoerg       CachedCompletionResults.push_back(CachedResult);
4257330f729Sjoerg 
4267330f729Sjoerg       /// Handle nested-name-specifiers in C++.
4277330f729Sjoerg       if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&
4287330f729Sjoerg           !R.StartsNestedNameSpecifier) {
4297330f729Sjoerg         // The contexts in which a nested-name-specifier can appear in C++.
4307330f729Sjoerg         uint64_t NNSContexts
4317330f729Sjoerg           = (1LL << CodeCompletionContext::CCC_TopLevel)
4327330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
4337330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
4347330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_Statement)
4357330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_Expression)
4367330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
4377330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_EnumTag)
4387330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_UnionTag)
4397330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_ClassOrStructTag)
4407330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_Type)
4417330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_SymbolOrNewName)
4427330f729Sjoerg           | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
4437330f729Sjoerg 
4447330f729Sjoerg         if (isa<NamespaceDecl>(R.Declaration) ||
4457330f729Sjoerg             isa<NamespaceAliasDecl>(R.Declaration))
4467330f729Sjoerg           NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);
4477330f729Sjoerg 
4487330f729Sjoerg         if (uint64_t RemainingContexts
4497330f729Sjoerg                                 = NNSContexts & ~CachedResult.ShowInContexts) {
4507330f729Sjoerg           // If there any contexts where this completion can be a
4517330f729Sjoerg           // nested-name-specifier but isn't already an option, create a
4527330f729Sjoerg           // nested-name-specifier completion.
4537330f729Sjoerg           R.StartsNestedNameSpecifier = true;
4547330f729Sjoerg           CachedResult.Completion = R.CreateCodeCompletionString(
4557330f729Sjoerg               *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
4567330f729Sjoerg               IncludeBriefCommentsInCodeCompletion);
4577330f729Sjoerg           CachedResult.ShowInContexts = RemainingContexts;
4587330f729Sjoerg           CachedResult.Priority = CCP_NestedNameSpecifier;
4597330f729Sjoerg           CachedResult.TypeClass = STC_Void;
4607330f729Sjoerg           CachedResult.Type = 0;
4617330f729Sjoerg           CachedCompletionResults.push_back(CachedResult);
4627330f729Sjoerg         }
4637330f729Sjoerg       }
4647330f729Sjoerg       break;
4657330f729Sjoerg     }
4667330f729Sjoerg 
4677330f729Sjoerg     case Result::RK_Keyword:
4687330f729Sjoerg     case Result::RK_Pattern:
4697330f729Sjoerg       // Ignore keywords and patterns; we don't care, since they are so
4707330f729Sjoerg       // easily regenerated.
4717330f729Sjoerg       break;
4727330f729Sjoerg 
4737330f729Sjoerg     case Result::RK_Macro: {
4747330f729Sjoerg       CachedCodeCompletionResult CachedResult;
4757330f729Sjoerg       CachedResult.Completion = R.CreateCodeCompletionString(
4767330f729Sjoerg           *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
4777330f729Sjoerg           IncludeBriefCommentsInCodeCompletion);
4787330f729Sjoerg       CachedResult.ShowInContexts
4797330f729Sjoerg         = (1LL << CodeCompletionContext::CCC_TopLevel)
4807330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCInterface)
4817330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
4827330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
4837330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
4847330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_Statement)
4857330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_Expression)
4867330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
4877330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_MacroNameUse)
4887330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_PreprocessorExpression)
4897330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
4907330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_OtherWithMacros);
4917330f729Sjoerg 
4927330f729Sjoerg       CachedResult.Priority = R.Priority;
4937330f729Sjoerg       CachedResult.Kind = R.CursorKind;
4947330f729Sjoerg       CachedResult.Availability = R.Availability;
4957330f729Sjoerg       CachedResult.TypeClass = STC_Void;
4967330f729Sjoerg       CachedResult.Type = 0;
4977330f729Sjoerg       CachedCompletionResults.push_back(CachedResult);
4987330f729Sjoerg       break;
4997330f729Sjoerg     }
5007330f729Sjoerg     }
5017330f729Sjoerg   }
5027330f729Sjoerg 
5037330f729Sjoerg   // Save the current top-level hash value.
5047330f729Sjoerg   CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
5057330f729Sjoerg }
5067330f729Sjoerg 
ClearCachedCompletionResults()5077330f729Sjoerg void ASTUnit::ClearCachedCompletionResults() {
5087330f729Sjoerg   CachedCompletionResults.clear();
5097330f729Sjoerg   CachedCompletionTypes.clear();
5107330f729Sjoerg   CachedCompletionAllocator = nullptr;
5117330f729Sjoerg }
5127330f729Sjoerg 
5137330f729Sjoerg namespace {
5147330f729Sjoerg 
5157330f729Sjoerg /// Gathers information from ASTReader that will be used to initialize
5167330f729Sjoerg /// a Preprocessor.
5177330f729Sjoerg class ASTInfoCollector : public ASTReaderListener {
5187330f729Sjoerg   Preprocessor &PP;
5197330f729Sjoerg   ASTContext *Context;
5207330f729Sjoerg   HeaderSearchOptions &HSOpts;
5217330f729Sjoerg   PreprocessorOptions &PPOpts;
5227330f729Sjoerg   LangOptions &LangOpt;
5237330f729Sjoerg   std::shared_ptr<TargetOptions> &TargetOpts;
5247330f729Sjoerg   IntrusiveRefCntPtr<TargetInfo> &Target;
5257330f729Sjoerg   unsigned &Counter;
5267330f729Sjoerg   bool InitializedLanguage = false;
5277330f729Sjoerg 
5287330f729Sjoerg public:
ASTInfoCollector(Preprocessor & PP,ASTContext * Context,HeaderSearchOptions & HSOpts,PreprocessorOptions & PPOpts,LangOptions & LangOpt,std::shared_ptr<TargetOptions> & TargetOpts,IntrusiveRefCntPtr<TargetInfo> & Target,unsigned & Counter)5297330f729Sjoerg   ASTInfoCollector(Preprocessor &PP, ASTContext *Context,
5307330f729Sjoerg                    HeaderSearchOptions &HSOpts, PreprocessorOptions &PPOpts,
5317330f729Sjoerg                    LangOptions &LangOpt,
5327330f729Sjoerg                    std::shared_ptr<TargetOptions> &TargetOpts,
5337330f729Sjoerg                    IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter)
5347330f729Sjoerg       : PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),
5357330f729Sjoerg         LangOpt(LangOpt), TargetOpts(TargetOpts), Target(Target),
5367330f729Sjoerg         Counter(Counter) {}
5377330f729Sjoerg 
ReadLanguageOptions(const LangOptions & LangOpts,bool Complain,bool AllowCompatibleDifferences)5387330f729Sjoerg   bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
5397330f729Sjoerg                            bool AllowCompatibleDifferences) override {
5407330f729Sjoerg     if (InitializedLanguage)
5417330f729Sjoerg       return false;
5427330f729Sjoerg 
5437330f729Sjoerg     LangOpt = LangOpts;
5447330f729Sjoerg     InitializedLanguage = true;
5457330f729Sjoerg 
5467330f729Sjoerg     updated();
5477330f729Sjoerg     return false;
5487330f729Sjoerg   }
5497330f729Sjoerg 
ReadHeaderSearchOptions(const HeaderSearchOptions & HSOpts,StringRef SpecificModuleCachePath,bool Complain)5507330f729Sjoerg   bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
5517330f729Sjoerg                                StringRef SpecificModuleCachePath,
5527330f729Sjoerg                                bool Complain) override {
5537330f729Sjoerg     this->HSOpts = HSOpts;
5547330f729Sjoerg     return false;
5557330f729Sjoerg   }
5567330f729Sjoerg 
ReadPreprocessorOptions(const PreprocessorOptions & PPOpts,bool Complain,std::string & SuggestedPredefines)5577330f729Sjoerg   bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
5587330f729Sjoerg                                std::string &SuggestedPredefines) override {
5597330f729Sjoerg     this->PPOpts = PPOpts;
5607330f729Sjoerg     return false;
5617330f729Sjoerg   }
5627330f729Sjoerg 
ReadTargetOptions(const TargetOptions & TargetOpts,bool Complain,bool AllowCompatibleDifferences)5637330f729Sjoerg   bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
5647330f729Sjoerg                          bool AllowCompatibleDifferences) override {
5657330f729Sjoerg     // If we've already initialized the target, don't do it again.
5667330f729Sjoerg     if (Target)
5677330f729Sjoerg       return false;
5687330f729Sjoerg 
5697330f729Sjoerg     this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
5707330f729Sjoerg     Target =
5717330f729Sjoerg         TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
5727330f729Sjoerg 
5737330f729Sjoerg     updated();
5747330f729Sjoerg     return false;
5757330f729Sjoerg   }
5767330f729Sjoerg 
ReadCounter(const serialization::ModuleFile & M,unsigned Value)5777330f729Sjoerg   void ReadCounter(const serialization::ModuleFile &M,
5787330f729Sjoerg                    unsigned Value) override {
5797330f729Sjoerg     Counter = Value;
5807330f729Sjoerg   }
5817330f729Sjoerg 
5827330f729Sjoerg private:
updated()5837330f729Sjoerg   void updated() {
5847330f729Sjoerg     if (!Target || !InitializedLanguage)
5857330f729Sjoerg       return;
5867330f729Sjoerg 
5877330f729Sjoerg     // Inform the target of the language options.
5887330f729Sjoerg     //
5897330f729Sjoerg     // FIXME: We shouldn't need to do this, the target should be immutable once
5907330f729Sjoerg     // created. This complexity should be lifted elsewhere.
5917330f729Sjoerg     Target->adjust(LangOpt);
5927330f729Sjoerg 
5937330f729Sjoerg     // Initialize the preprocessor.
5947330f729Sjoerg     PP.Initialize(*Target);
5957330f729Sjoerg 
5967330f729Sjoerg     if (!Context)
5977330f729Sjoerg       return;
5987330f729Sjoerg 
5997330f729Sjoerg     // Initialize the ASTContext
6007330f729Sjoerg     Context->InitBuiltinTypes(*Target);
6017330f729Sjoerg 
6027330f729Sjoerg     // Adjust printing policy based on language options.
6037330f729Sjoerg     Context->setPrintingPolicy(PrintingPolicy(LangOpt));
6047330f729Sjoerg 
6057330f729Sjoerg     // We didn't have access to the comment options when the ASTContext was
6067330f729Sjoerg     // constructed, so register them now.
6077330f729Sjoerg     Context->getCommentCommandTraits().registerCommentOptions(
6087330f729Sjoerg         LangOpt.CommentOpts);
6097330f729Sjoerg   }
6107330f729Sjoerg };
6117330f729Sjoerg 
6127330f729Sjoerg /// Diagnostic consumer that saves each diagnostic it is given.
6137330f729Sjoerg class FilterAndStoreDiagnosticConsumer : public DiagnosticConsumer {
6147330f729Sjoerg   SmallVectorImpl<StoredDiagnostic> *StoredDiags;
6157330f729Sjoerg   SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags;
6167330f729Sjoerg   bool CaptureNonErrorsFromIncludes = true;
6177330f729Sjoerg   const LangOptions *LangOpts = nullptr;
6187330f729Sjoerg   SourceManager *SourceMgr = nullptr;
6197330f729Sjoerg 
6207330f729Sjoerg public:
FilterAndStoreDiagnosticConsumer(SmallVectorImpl<StoredDiagnostic> * StoredDiags,SmallVectorImpl<ASTUnit::StandaloneDiagnostic> * StandaloneDiags,bool CaptureNonErrorsFromIncludes)6217330f729Sjoerg   FilterAndStoreDiagnosticConsumer(
6227330f729Sjoerg       SmallVectorImpl<StoredDiagnostic> *StoredDiags,
6237330f729Sjoerg       SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags,
6247330f729Sjoerg       bool CaptureNonErrorsFromIncludes)
6257330f729Sjoerg       : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
6267330f729Sjoerg         CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
6277330f729Sjoerg     assert((StoredDiags || StandaloneDiags) &&
6287330f729Sjoerg            "No output collections were passed to StoredDiagnosticConsumer.");
6297330f729Sjoerg   }
6307330f729Sjoerg 
BeginSourceFile(const LangOptions & LangOpts,const Preprocessor * PP=nullptr)6317330f729Sjoerg   void BeginSourceFile(const LangOptions &LangOpts,
6327330f729Sjoerg                        const Preprocessor *PP = nullptr) override {
6337330f729Sjoerg     this->LangOpts = &LangOpts;
6347330f729Sjoerg     if (PP)
6357330f729Sjoerg       SourceMgr = &PP->getSourceManager();
6367330f729Sjoerg   }
6377330f729Sjoerg 
6387330f729Sjoerg   void HandleDiagnostic(DiagnosticsEngine::Level Level,
6397330f729Sjoerg                         const Diagnostic &Info) override;
6407330f729Sjoerg };
6417330f729Sjoerg 
6427330f729Sjoerg /// RAII object that optionally captures and filters diagnostics, if
6437330f729Sjoerg /// there is no diagnostic client to capture them already.
6447330f729Sjoerg class CaptureDroppedDiagnostics {
6457330f729Sjoerg   DiagnosticsEngine &Diags;
6467330f729Sjoerg   FilterAndStoreDiagnosticConsumer Client;
6477330f729Sjoerg   DiagnosticConsumer *PreviousClient = nullptr;
6487330f729Sjoerg   std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
6497330f729Sjoerg 
6507330f729Sjoerg public:
CaptureDroppedDiagnostics(CaptureDiagsKind CaptureDiagnostics,DiagnosticsEngine & Diags,SmallVectorImpl<StoredDiagnostic> * StoredDiags,SmallVectorImpl<ASTUnit::StandaloneDiagnostic> * StandaloneDiags)6517330f729Sjoerg   CaptureDroppedDiagnostics(
6527330f729Sjoerg       CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
6537330f729Sjoerg       SmallVectorImpl<StoredDiagnostic> *StoredDiags,
6547330f729Sjoerg       SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
6557330f729Sjoerg       : Diags(Diags),
6567330f729Sjoerg         Client(StoredDiags, StandaloneDiags,
6577330f729Sjoerg                CaptureDiagnostics !=
6587330f729Sjoerg                    CaptureDiagsKind::AllWithoutNonErrorsFromIncludes) {
6597330f729Sjoerg     if (CaptureDiagnostics != CaptureDiagsKind::None ||
6607330f729Sjoerg         Diags.getClient() == nullptr) {
6617330f729Sjoerg       OwningPreviousClient = Diags.takeClient();
6627330f729Sjoerg       PreviousClient = Diags.getClient();
6637330f729Sjoerg       Diags.setClient(&Client, false);
6647330f729Sjoerg     }
6657330f729Sjoerg   }
6667330f729Sjoerg 
~CaptureDroppedDiagnostics()6677330f729Sjoerg   ~CaptureDroppedDiagnostics() {
6687330f729Sjoerg     if (Diags.getClient() == &Client)
6697330f729Sjoerg       Diags.setClient(PreviousClient, !!OwningPreviousClient.release());
6707330f729Sjoerg   }
6717330f729Sjoerg };
6727330f729Sjoerg 
6737330f729Sjoerg } // namespace
6747330f729Sjoerg 
6757330f729Sjoerg static ASTUnit::StandaloneDiagnostic
6767330f729Sjoerg makeStandaloneDiagnostic(const LangOptions &LangOpts,
6777330f729Sjoerg                          const StoredDiagnostic &InDiag);
6787330f729Sjoerg 
isInMainFile(const clang::Diagnostic & D)6797330f729Sjoerg static bool isInMainFile(const clang::Diagnostic &D) {
6807330f729Sjoerg   if (!D.hasSourceManager() || !D.getLocation().isValid())
6817330f729Sjoerg     return false;
6827330f729Sjoerg 
6837330f729Sjoerg   auto &M = D.getSourceManager();
6847330f729Sjoerg   return M.isWrittenInMainFile(M.getExpansionLoc(D.getLocation()));
6857330f729Sjoerg }
6867330f729Sjoerg 
HandleDiagnostic(DiagnosticsEngine::Level Level,const Diagnostic & Info)6877330f729Sjoerg void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
6887330f729Sjoerg     DiagnosticsEngine::Level Level, const Diagnostic &Info) {
6897330f729Sjoerg   // Default implementation (Warnings/errors count).
6907330f729Sjoerg   DiagnosticConsumer::HandleDiagnostic(Level, Info);
6917330f729Sjoerg 
6927330f729Sjoerg   // Only record the diagnostic if it's part of the source manager we know
6937330f729Sjoerg   // about. This effectively drops diagnostics from modules we're building.
6947330f729Sjoerg   // FIXME: In the long run, ee don't want to drop source managers from modules.
6957330f729Sjoerg   if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) {
6967330f729Sjoerg     if (!CaptureNonErrorsFromIncludes && Level <= DiagnosticsEngine::Warning &&
6977330f729Sjoerg         !isInMainFile(Info)) {
6987330f729Sjoerg       return;
6997330f729Sjoerg     }
7007330f729Sjoerg 
7017330f729Sjoerg     StoredDiagnostic *ResultDiag = nullptr;
7027330f729Sjoerg     if (StoredDiags) {
7037330f729Sjoerg       StoredDiags->emplace_back(Level, Info);
7047330f729Sjoerg       ResultDiag = &StoredDiags->back();
7057330f729Sjoerg     }
7067330f729Sjoerg 
7077330f729Sjoerg     if (StandaloneDiags) {
7087330f729Sjoerg       llvm::Optional<StoredDiagnostic> StoredDiag = None;
7097330f729Sjoerg       if (!ResultDiag) {
7107330f729Sjoerg         StoredDiag.emplace(Level, Info);
7117330f729Sjoerg         ResultDiag = StoredDiag.getPointer();
7127330f729Sjoerg       }
7137330f729Sjoerg       StandaloneDiags->push_back(
7147330f729Sjoerg           makeStandaloneDiagnostic(*LangOpts, *ResultDiag));
7157330f729Sjoerg     }
7167330f729Sjoerg   }
7177330f729Sjoerg }
7187330f729Sjoerg 
getASTReader() const7197330f729Sjoerg IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
7207330f729Sjoerg   return Reader;
7217330f729Sjoerg }
7227330f729Sjoerg 
getASTMutationListener()7237330f729Sjoerg ASTMutationListener *ASTUnit::getASTMutationListener() {
7247330f729Sjoerg   if (WriterData)
7257330f729Sjoerg     return &WriterData->Writer;
7267330f729Sjoerg   return nullptr;
7277330f729Sjoerg }
7287330f729Sjoerg 
getDeserializationListener()7297330f729Sjoerg ASTDeserializationListener *ASTUnit::getDeserializationListener() {
7307330f729Sjoerg   if (WriterData)
7317330f729Sjoerg     return &WriterData->Writer;
7327330f729Sjoerg   return nullptr;
7337330f729Sjoerg }
7347330f729Sjoerg 
7357330f729Sjoerg std::unique_ptr<llvm::MemoryBuffer>
getBufferForFile(StringRef Filename,std::string * ErrorStr)7367330f729Sjoerg ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
7377330f729Sjoerg   assert(FileMgr);
7387330f729Sjoerg   auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
7397330f729Sjoerg   if (Buffer)
7407330f729Sjoerg     return std::move(*Buffer);
7417330f729Sjoerg   if (ErrorStr)
7427330f729Sjoerg     *ErrorStr = Buffer.getError().message();
7437330f729Sjoerg   return nullptr;
7447330f729Sjoerg }
7457330f729Sjoerg 
7467330f729Sjoerg /// Configure the diagnostics object for use with ASTUnit.
ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,ASTUnit & AST,CaptureDiagsKind CaptureDiagnostics)7477330f729Sjoerg void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
7487330f729Sjoerg                              ASTUnit &AST,
7497330f729Sjoerg                              CaptureDiagsKind CaptureDiagnostics) {
7507330f729Sjoerg   assert(Diags.get() && "no DiagnosticsEngine was provided");
7517330f729Sjoerg   if (CaptureDiagnostics != CaptureDiagsKind::None)
7527330f729Sjoerg     Diags->setClient(new FilterAndStoreDiagnosticConsumer(
7537330f729Sjoerg         &AST.StoredDiagnostics, nullptr,
7547330f729Sjoerg         CaptureDiagnostics != CaptureDiagsKind::AllWithoutNonErrorsFromIncludes));
7557330f729Sjoerg }
7567330f729Sjoerg 
LoadFromASTFile(const std::string & Filename,const PCHContainerReader & PCHContainerRdr,WhatToLoad ToLoad,IntrusiveRefCntPtr<DiagnosticsEngine> Diags,const FileSystemOptions & FileSystemOpts,bool UseDebugInfo,bool OnlyLocalDecls,CaptureDiagsKind CaptureDiagnostics,bool AllowASTWithCompilerErrors,bool UserFilesAreVolatile)7577330f729Sjoerg std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
7587330f729Sjoerg     const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
7597330f729Sjoerg     WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
7607330f729Sjoerg     const FileSystemOptions &FileSystemOpts, bool UseDebugInfo,
761*e038c9c4Sjoerg     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
762*e038c9c4Sjoerg     bool AllowASTWithCompilerErrors, bool UserFilesAreVolatile) {
7637330f729Sjoerg   std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
7647330f729Sjoerg 
7657330f729Sjoerg   // Recover resources if we crash before exiting this method.
7667330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
7677330f729Sjoerg     ASTUnitCleanup(AST.get());
7687330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
7697330f729Sjoerg     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
7707330f729Sjoerg     DiagCleanup(Diags.get());
7717330f729Sjoerg 
7727330f729Sjoerg   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
7737330f729Sjoerg 
7747330f729Sjoerg   AST->LangOpts = std::make_shared<LangOptions>();
7757330f729Sjoerg   AST->OnlyLocalDecls = OnlyLocalDecls;
7767330f729Sjoerg   AST->CaptureDiagnostics = CaptureDiagnostics;
7777330f729Sjoerg   AST->Diagnostics = Diags;
7787330f729Sjoerg   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
7797330f729Sjoerg       llvm::vfs::getRealFileSystem();
7807330f729Sjoerg   AST->FileMgr = new FileManager(FileSystemOpts, VFS);
7817330f729Sjoerg   AST->UserFilesAreVolatile = UserFilesAreVolatile;
7827330f729Sjoerg   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
7837330f729Sjoerg                                      AST->getFileManager(),
7847330f729Sjoerg                                      UserFilesAreVolatile);
7857330f729Sjoerg   AST->ModuleCache = new InMemoryModuleCache;
7867330f729Sjoerg   AST->HSOpts = std::make_shared<HeaderSearchOptions>();
787*e038c9c4Sjoerg   AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormat());
7887330f729Sjoerg   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
7897330f729Sjoerg                                          AST->getSourceManager(),
7907330f729Sjoerg                                          AST->getDiagnostics(),
7917330f729Sjoerg                                          AST->getLangOpts(),
7927330f729Sjoerg                                          /*Target=*/nullptr));
7937330f729Sjoerg   AST->PPOpts = std::make_shared<PreprocessorOptions>();
7947330f729Sjoerg 
7957330f729Sjoerg   // Gather Info for preprocessor construction later on.
7967330f729Sjoerg 
7977330f729Sjoerg   HeaderSearch &HeaderInfo = *AST->HeaderInfo;
7987330f729Sjoerg   unsigned Counter;
7997330f729Sjoerg 
8007330f729Sjoerg   AST->PP = std::make_shared<Preprocessor>(
8017330f729Sjoerg       AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
8027330f729Sjoerg       AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,
8037330f729Sjoerg       /*IILookup=*/nullptr,
8047330f729Sjoerg       /*OwnsHeaderSearch=*/false);
8057330f729Sjoerg   Preprocessor &PP = *AST->PP;
8067330f729Sjoerg 
8077330f729Sjoerg   if (ToLoad >= LoadASTOnly)
8087330f729Sjoerg     AST->Ctx = new ASTContext(*AST->LangOpts, AST->getSourceManager(),
8097330f729Sjoerg                               PP.getIdentifierTable(), PP.getSelectorTable(),
8107330f729Sjoerg                               PP.getBuiltinInfo());
8117330f729Sjoerg 
812*e038c9c4Sjoerg   DisableValidationForModuleKind disableValid =
813*e038c9c4Sjoerg       DisableValidationForModuleKind::None;
8147330f729Sjoerg   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
815*e038c9c4Sjoerg     disableValid = DisableValidationForModuleKind::All;
8167330f729Sjoerg   AST->Reader = new ASTReader(
8177330f729Sjoerg       PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
8187330f729Sjoerg       /*isysroot=*/"",
819*e038c9c4Sjoerg       /*DisableValidation=*/disableValid, AllowASTWithCompilerErrors);
8207330f729Sjoerg 
8217330f729Sjoerg   AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
8227330f729Sjoerg       *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
8237330f729Sjoerg       AST->TargetOpts, AST->Target, Counter));
8247330f729Sjoerg 
8257330f729Sjoerg   // Attach the AST reader to the AST context as an external AST
8267330f729Sjoerg   // source, so that declarations will be deserialized from the
8277330f729Sjoerg   // AST file as needed.
8287330f729Sjoerg   // We need the external source to be set up before we read the AST, because
8297330f729Sjoerg   // eagerly-deserialized declarations may use it.
8307330f729Sjoerg   if (AST->Ctx)
8317330f729Sjoerg     AST->Ctx->setExternalSource(AST->Reader);
8327330f729Sjoerg 
8337330f729Sjoerg   switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,
8347330f729Sjoerg                           SourceLocation(), ASTReader::ARR_None)) {
8357330f729Sjoerg   case ASTReader::Success:
8367330f729Sjoerg     break;
8377330f729Sjoerg 
8387330f729Sjoerg   case ASTReader::Failure:
8397330f729Sjoerg   case ASTReader::Missing:
8407330f729Sjoerg   case ASTReader::OutOfDate:
8417330f729Sjoerg   case ASTReader::VersionMismatch:
8427330f729Sjoerg   case ASTReader::ConfigurationMismatch:
8437330f729Sjoerg   case ASTReader::HadErrors:
8447330f729Sjoerg     AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
8457330f729Sjoerg     return nullptr;
8467330f729Sjoerg   }
8477330f729Sjoerg 
848*e038c9c4Sjoerg   AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());
8497330f729Sjoerg 
8507330f729Sjoerg   PP.setCounterValue(Counter);
8517330f729Sjoerg 
8527330f729Sjoerg   // Create an AST consumer, even though it isn't used.
8537330f729Sjoerg   if (ToLoad >= LoadASTOnly)
8547330f729Sjoerg     AST->Consumer.reset(new ASTConsumer);
8557330f729Sjoerg 
8567330f729Sjoerg   // Create a semantic analysis object and tell the AST reader about it.
8577330f729Sjoerg   if (ToLoad >= LoadEverything) {
8587330f729Sjoerg     AST->TheSema.reset(new Sema(PP, *AST->Ctx, *AST->Consumer));
8597330f729Sjoerg     AST->TheSema->Initialize();
8607330f729Sjoerg     AST->Reader->InitializeSema(*AST->TheSema);
8617330f729Sjoerg   }
8627330f729Sjoerg 
8637330f729Sjoerg   // Tell the diagnostic client that we have started a source file.
8647330f729Sjoerg   AST->getDiagnostics().getClient()->BeginSourceFile(PP.getLangOpts(), &PP);
8657330f729Sjoerg 
8667330f729Sjoerg   return AST;
8677330f729Sjoerg }
8687330f729Sjoerg 
8697330f729Sjoerg /// Add the given macro to the hash of all top-level entities.
AddDefinedMacroToHash(const Token & MacroNameTok,unsigned & Hash)8707330f729Sjoerg static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
8717330f729Sjoerg   Hash = llvm::djbHash(MacroNameTok.getIdentifierInfo()->getName(), Hash);
8727330f729Sjoerg }
8737330f729Sjoerg 
8747330f729Sjoerg namespace {
8757330f729Sjoerg 
8767330f729Sjoerg /// Preprocessor callback class that updates a hash value with the names
8777330f729Sjoerg /// of all macros that have been defined by the translation unit.
8787330f729Sjoerg class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {
8797330f729Sjoerg   unsigned &Hash;
8807330f729Sjoerg 
8817330f729Sjoerg public:
MacroDefinitionTrackerPPCallbacks(unsigned & Hash)8827330f729Sjoerg   explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}
8837330f729Sjoerg 
MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)8847330f729Sjoerg   void MacroDefined(const Token &MacroNameTok,
8857330f729Sjoerg                     const MacroDirective *MD) override {
8867330f729Sjoerg     AddDefinedMacroToHash(MacroNameTok, Hash);
8877330f729Sjoerg   }
8887330f729Sjoerg };
8897330f729Sjoerg 
8907330f729Sjoerg } // namespace
8917330f729Sjoerg 
8927330f729Sjoerg /// Add the given declaration to the hash of all top-level entities.
AddTopLevelDeclarationToHash(Decl * D,unsigned & Hash)8937330f729Sjoerg static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
8947330f729Sjoerg   if (!D)
8957330f729Sjoerg     return;
8967330f729Sjoerg 
8977330f729Sjoerg   DeclContext *DC = D->getDeclContext();
8987330f729Sjoerg   if (!DC)
8997330f729Sjoerg     return;
9007330f729Sjoerg 
9017330f729Sjoerg   if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))
9027330f729Sjoerg     return;
9037330f729Sjoerg 
9047330f729Sjoerg   if (const auto *ND = dyn_cast<NamedDecl>(D)) {
9057330f729Sjoerg     if (const auto *EnumD = dyn_cast<EnumDecl>(D)) {
9067330f729Sjoerg       // For an unscoped enum include the enumerators in the hash since they
9077330f729Sjoerg       // enter the top-level namespace.
9087330f729Sjoerg       if (!EnumD->isScoped()) {
9097330f729Sjoerg         for (const auto *EI : EnumD->enumerators()) {
9107330f729Sjoerg           if (EI->getIdentifier())
9117330f729Sjoerg             Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
9127330f729Sjoerg         }
9137330f729Sjoerg       }
9147330f729Sjoerg     }
9157330f729Sjoerg 
9167330f729Sjoerg     if (ND->getIdentifier())
9177330f729Sjoerg       Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
9187330f729Sjoerg     else if (DeclarationName Name = ND->getDeclName()) {
9197330f729Sjoerg       std::string NameStr = Name.getAsString();
9207330f729Sjoerg       Hash = llvm::djbHash(NameStr, Hash);
9217330f729Sjoerg     }
9227330f729Sjoerg     return;
9237330f729Sjoerg   }
9247330f729Sjoerg 
9257330f729Sjoerg   if (const auto *ImportD = dyn_cast<ImportDecl>(D)) {
9267330f729Sjoerg     if (const Module *Mod = ImportD->getImportedModule()) {
9277330f729Sjoerg       std::string ModName = Mod->getFullModuleName();
9287330f729Sjoerg       Hash = llvm::djbHash(ModName, Hash);
9297330f729Sjoerg     }
9307330f729Sjoerg     return;
9317330f729Sjoerg   }
9327330f729Sjoerg }
9337330f729Sjoerg 
9347330f729Sjoerg namespace {
9357330f729Sjoerg 
9367330f729Sjoerg class TopLevelDeclTrackerConsumer : public ASTConsumer {
9377330f729Sjoerg   ASTUnit &Unit;
9387330f729Sjoerg   unsigned &Hash;
9397330f729Sjoerg 
9407330f729Sjoerg public:
TopLevelDeclTrackerConsumer(ASTUnit & _Unit,unsigned & Hash)9417330f729Sjoerg   TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)
9427330f729Sjoerg       : Unit(_Unit), Hash(Hash) {
9437330f729Sjoerg     Hash = 0;
9447330f729Sjoerg   }
9457330f729Sjoerg 
handleTopLevelDecl(Decl * D)9467330f729Sjoerg   void handleTopLevelDecl(Decl *D) {
9477330f729Sjoerg     if (!D)
9487330f729Sjoerg       return;
9497330f729Sjoerg 
9507330f729Sjoerg     // FIXME: Currently ObjC method declarations are incorrectly being
9517330f729Sjoerg     // reported as top-level declarations, even though their DeclContext
9527330f729Sjoerg     // is the containing ObjC @interface/@implementation.  This is a
9537330f729Sjoerg     // fundamental problem in the parser right now.
9547330f729Sjoerg     if (isa<ObjCMethodDecl>(D))
9557330f729Sjoerg       return;
9567330f729Sjoerg 
9577330f729Sjoerg     AddTopLevelDeclarationToHash(D, Hash);
9587330f729Sjoerg     Unit.addTopLevelDecl(D);
9597330f729Sjoerg 
9607330f729Sjoerg     handleFileLevelDecl(D);
9617330f729Sjoerg   }
9627330f729Sjoerg 
handleFileLevelDecl(Decl * D)9637330f729Sjoerg   void handleFileLevelDecl(Decl *D) {
9647330f729Sjoerg     Unit.addFileLevelDecl(D);
9657330f729Sjoerg     if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {
9667330f729Sjoerg       for (auto *I : NSD->decls())
9677330f729Sjoerg         handleFileLevelDecl(I);
9687330f729Sjoerg     }
9697330f729Sjoerg   }
9707330f729Sjoerg 
HandleTopLevelDecl(DeclGroupRef D)9717330f729Sjoerg   bool HandleTopLevelDecl(DeclGroupRef D) override {
9727330f729Sjoerg     for (auto *TopLevelDecl : D)
9737330f729Sjoerg       handleTopLevelDecl(TopLevelDecl);
9747330f729Sjoerg     return true;
9757330f729Sjoerg   }
9767330f729Sjoerg 
9777330f729Sjoerg   // We're not interested in "interesting" decls.
HandleInterestingDecl(DeclGroupRef)9787330f729Sjoerg   void HandleInterestingDecl(DeclGroupRef) override {}
9797330f729Sjoerg 
HandleTopLevelDeclInObjCContainer(DeclGroupRef D)9807330f729Sjoerg   void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
9817330f729Sjoerg     for (auto *TopLevelDecl : D)
9827330f729Sjoerg       handleTopLevelDecl(TopLevelDecl);
9837330f729Sjoerg   }
9847330f729Sjoerg 
GetASTMutationListener()9857330f729Sjoerg   ASTMutationListener *GetASTMutationListener() override {
9867330f729Sjoerg     return Unit.getASTMutationListener();
9877330f729Sjoerg   }
9887330f729Sjoerg 
GetASTDeserializationListener()9897330f729Sjoerg   ASTDeserializationListener *GetASTDeserializationListener() override {
9907330f729Sjoerg     return Unit.getDeserializationListener();
9917330f729Sjoerg   }
9927330f729Sjoerg };
9937330f729Sjoerg 
9947330f729Sjoerg class TopLevelDeclTrackerAction : public ASTFrontendAction {
9957330f729Sjoerg public:
9967330f729Sjoerg   ASTUnit &Unit;
9977330f729Sjoerg 
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)9987330f729Sjoerg   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
9997330f729Sjoerg                                                  StringRef InFile) override {
10007330f729Sjoerg     CI.getPreprocessor().addPPCallbacks(
10017330f729Sjoerg         std::make_unique<MacroDefinitionTrackerPPCallbacks>(
10027330f729Sjoerg                                            Unit.getCurrentTopLevelHashValue()));
10037330f729Sjoerg     return std::make_unique<TopLevelDeclTrackerConsumer>(
10047330f729Sjoerg         Unit, Unit.getCurrentTopLevelHashValue());
10057330f729Sjoerg   }
10067330f729Sjoerg 
10077330f729Sjoerg public:
TopLevelDeclTrackerAction(ASTUnit & _Unit)10087330f729Sjoerg   TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
10097330f729Sjoerg 
hasCodeCompletionSupport() const10107330f729Sjoerg   bool hasCodeCompletionSupport() const override { return false; }
10117330f729Sjoerg 
getTranslationUnitKind()10127330f729Sjoerg   TranslationUnitKind getTranslationUnitKind() override {
10137330f729Sjoerg     return Unit.getTranslationUnitKind();
10147330f729Sjoerg   }
10157330f729Sjoerg };
10167330f729Sjoerg 
10177330f729Sjoerg class ASTUnitPreambleCallbacks : public PreambleCallbacks {
10187330f729Sjoerg public:
getHash() const10197330f729Sjoerg   unsigned getHash() const { return Hash; }
10207330f729Sjoerg 
takeTopLevelDecls()10217330f729Sjoerg   std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
10227330f729Sjoerg 
takeTopLevelDeclIDs()10237330f729Sjoerg   std::vector<serialization::DeclID> takeTopLevelDeclIDs() {
10247330f729Sjoerg     return std::move(TopLevelDeclIDs);
10257330f729Sjoerg   }
10267330f729Sjoerg 
AfterPCHEmitted(ASTWriter & Writer)10277330f729Sjoerg   void AfterPCHEmitted(ASTWriter &Writer) override {
10287330f729Sjoerg     TopLevelDeclIDs.reserve(TopLevelDecls.size());
10297330f729Sjoerg     for (const auto *D : TopLevelDecls) {
10307330f729Sjoerg       // Invalid top-level decls may not have been serialized.
10317330f729Sjoerg       if (D->isInvalidDecl())
10327330f729Sjoerg         continue;
10337330f729Sjoerg       TopLevelDeclIDs.push_back(Writer.getDeclID(D));
10347330f729Sjoerg     }
10357330f729Sjoerg   }
10367330f729Sjoerg 
HandleTopLevelDecl(DeclGroupRef DG)10377330f729Sjoerg   void HandleTopLevelDecl(DeclGroupRef DG) override {
10387330f729Sjoerg     for (auto *D : DG) {
10397330f729Sjoerg       // FIXME: Currently ObjC method declarations are incorrectly being
10407330f729Sjoerg       // reported as top-level declarations, even though their DeclContext
10417330f729Sjoerg       // is the containing ObjC @interface/@implementation.  This is a
10427330f729Sjoerg       // fundamental problem in the parser right now.
10437330f729Sjoerg       if (isa<ObjCMethodDecl>(D))
10447330f729Sjoerg         continue;
10457330f729Sjoerg       AddTopLevelDeclarationToHash(D, Hash);
10467330f729Sjoerg       TopLevelDecls.push_back(D);
10477330f729Sjoerg     }
10487330f729Sjoerg   }
10497330f729Sjoerg 
createPPCallbacks()10507330f729Sjoerg   std::unique_ptr<PPCallbacks> createPPCallbacks() override {
10517330f729Sjoerg     return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);
10527330f729Sjoerg   }
10537330f729Sjoerg 
10547330f729Sjoerg private:
10557330f729Sjoerg   unsigned Hash = 0;
10567330f729Sjoerg   std::vector<Decl *> TopLevelDecls;
10577330f729Sjoerg   std::vector<serialization::DeclID> TopLevelDeclIDs;
10587330f729Sjoerg   llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
10597330f729Sjoerg };
10607330f729Sjoerg 
10617330f729Sjoerg } // namespace
10627330f729Sjoerg 
isNonDriverDiag(const StoredDiagnostic & StoredDiag)10637330f729Sjoerg static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
10647330f729Sjoerg   return StoredDiag.getLocation().isValid();
10657330f729Sjoerg }
10667330f729Sjoerg 
10677330f729Sjoerg static void
checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> & StoredDiags)10687330f729Sjoerg checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &StoredDiags) {
10697330f729Sjoerg   // Get rid of stored diagnostics except the ones from the driver which do not
10707330f729Sjoerg   // have a source location.
10717330f729Sjoerg   StoredDiags.erase(
10727330f729Sjoerg       std::remove_if(StoredDiags.begin(), StoredDiags.end(), isNonDriverDiag),
10737330f729Sjoerg       StoredDiags.end());
10747330f729Sjoerg }
10757330f729Sjoerg 
checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & StoredDiagnostics,SourceManager & SM)10767330f729Sjoerg static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
10777330f729Sjoerg                                                               StoredDiagnostics,
10787330f729Sjoerg                                   SourceManager &SM) {
10797330f729Sjoerg   // The stored diagnostic has the old source manager in it; update
10807330f729Sjoerg   // the locations to refer into the new source manager. Since we've
10817330f729Sjoerg   // been careful to make sure that the source manager's state
10827330f729Sjoerg   // before and after are identical, so that we can reuse the source
10837330f729Sjoerg   // location itself.
10847330f729Sjoerg   for (auto &SD : StoredDiagnostics) {
10857330f729Sjoerg     if (SD.getLocation().isValid()) {
10867330f729Sjoerg       FullSourceLoc Loc(SD.getLocation(), SM);
10877330f729Sjoerg       SD.setLocation(Loc);
10887330f729Sjoerg     }
10897330f729Sjoerg   }
10907330f729Sjoerg }
10917330f729Sjoerg 
10927330f729Sjoerg /// Parse the source file into a translation unit using the given compiler
10937330f729Sjoerg /// invocation, replacing the current translation unit.
10947330f729Sjoerg ///
10957330f729Sjoerg /// \returns True if a failure occurred that causes the ASTUnit not to
10967330f729Sjoerg /// contain any translation-unit information, false otherwise.
Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)10977330f729Sjoerg bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
10987330f729Sjoerg                     std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
10997330f729Sjoerg                     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
11007330f729Sjoerg   if (!Invocation)
11017330f729Sjoerg     return true;
11027330f729Sjoerg 
11037330f729Sjoerg   if (VFS && FileMgr)
11047330f729Sjoerg     assert(VFS == &FileMgr->getVirtualFileSystem() &&
11057330f729Sjoerg            "VFS passed to Parse and VFS in FileMgr are different");
11067330f729Sjoerg 
11077330f729Sjoerg   auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
11087330f729Sjoerg   if (OverrideMainBuffer) {
11097330f729Sjoerg     assert(Preamble &&
11107330f729Sjoerg            "No preamble was built, but OverrideMainBuffer is not null");
11117330f729Sjoerg     Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
11127330f729Sjoerg     // VFS may have changed...
11137330f729Sjoerg   }
11147330f729Sjoerg 
11157330f729Sjoerg   // Create the compiler instance to use for building the AST.
11167330f729Sjoerg   std::unique_ptr<CompilerInstance> Clang(
11177330f729Sjoerg       new CompilerInstance(std::move(PCHContainerOps)));
11187330f729Sjoerg 
1119*e038c9c4Sjoerg   // Clean up on error, disengage it if the function returns successfully.
1120*e038c9c4Sjoerg   auto CleanOnError = llvm::make_scope_exit([&]() {
1121*e038c9c4Sjoerg     // Remove the overridden buffer we used for the preamble.
1122*e038c9c4Sjoerg     SavedMainFileBuffer = nullptr;
1123*e038c9c4Sjoerg 
1124*e038c9c4Sjoerg     // Keep the ownership of the data in the ASTUnit because the client may
1125*e038c9c4Sjoerg     // want to see the diagnostics.
1126*e038c9c4Sjoerg     transferASTDataFromCompilerInstance(*Clang);
1127*e038c9c4Sjoerg     FailedParseDiagnostics.swap(StoredDiagnostics);
1128*e038c9c4Sjoerg     StoredDiagnostics.clear();
1129*e038c9c4Sjoerg     NumStoredDiagnosticsFromDriver = 0;
1130*e038c9c4Sjoerg   });
1131*e038c9c4Sjoerg 
11327330f729Sjoerg   // Ensure that Clang has a FileManager with the right VFS, which may have
11337330f729Sjoerg   // changed above in AddImplicitPreamble.  If VFS is nullptr, rely on
11347330f729Sjoerg   // createFileManager to create one.
11357330f729Sjoerg   if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS)
11367330f729Sjoerg     Clang->setFileManager(&*FileMgr);
11377330f729Sjoerg   else
11387330f729Sjoerg     FileMgr = Clang->createFileManager(std::move(VFS));
11397330f729Sjoerg 
11407330f729Sjoerg   // Recover resources if we crash before exiting this method.
11417330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
11427330f729Sjoerg     CICleanup(Clang.get());
11437330f729Sjoerg 
11447330f729Sjoerg   Clang->setInvocation(CCInvocation);
1145*e038c9c4Sjoerg   OriginalSourceFile =
1146*e038c9c4Sjoerg       std::string(Clang->getFrontendOpts().Inputs[0].getFile());
11477330f729Sjoerg 
11487330f729Sjoerg   // Set up diagnostics, capturing any diagnostics that would
11497330f729Sjoerg   // otherwise be dropped.
11507330f729Sjoerg   Clang->setDiagnostics(&getDiagnostics());
11517330f729Sjoerg 
11527330f729Sjoerg   // Create the target instance.
1153*e038c9c4Sjoerg   if (!Clang->createTarget())
11547330f729Sjoerg     return true;
11557330f729Sjoerg 
11567330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
11577330f729Sjoerg          "Invocation must have exactly one source file!");
11587330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
11597330f729Sjoerg              InputKind::Source &&
11607330f729Sjoerg          "FIXME: AST inputs not yet supported here!");
11617330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
11627330f729Sjoerg              Language::LLVM_IR &&
11637330f729Sjoerg          "IR inputs not support here!");
11647330f729Sjoerg 
11657330f729Sjoerg   // Configure the various subsystems.
11667330f729Sjoerg   LangOpts = Clang->getInvocation().LangOpts;
11677330f729Sjoerg   FileSystemOpts = Clang->getFileSystemOpts();
11687330f729Sjoerg 
11697330f729Sjoerg   ResetForParse();
11707330f729Sjoerg 
11717330f729Sjoerg   SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
11727330f729Sjoerg                                 UserFilesAreVolatile);
11737330f729Sjoerg   if (!OverrideMainBuffer) {
11747330f729Sjoerg     checkAndRemoveNonDriverDiags(StoredDiagnostics);
11757330f729Sjoerg     TopLevelDeclsInPreamble.clear();
11767330f729Sjoerg   }
11777330f729Sjoerg 
11787330f729Sjoerg   // Create the source manager.
11797330f729Sjoerg   Clang->setSourceManager(&getSourceManager());
11807330f729Sjoerg 
11817330f729Sjoerg   // If the main file has been overridden due to the use of a preamble,
11827330f729Sjoerg   // make that override happen and introduce the preamble.
11837330f729Sjoerg   if (OverrideMainBuffer) {
11847330f729Sjoerg     // The stored diagnostic has the old source manager in it; update
11857330f729Sjoerg     // the locations to refer into the new source manager. Since we've
11867330f729Sjoerg     // been careful to make sure that the source manager's state
11877330f729Sjoerg     // before and after are identical, so that we can reuse the source
11887330f729Sjoerg     // location itself.
11897330f729Sjoerg     checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
11907330f729Sjoerg 
11917330f729Sjoerg     // Keep track of the override buffer;
11927330f729Sjoerg     SavedMainFileBuffer = std::move(OverrideMainBuffer);
11937330f729Sjoerg   }
11947330f729Sjoerg 
11957330f729Sjoerg   std::unique_ptr<TopLevelDeclTrackerAction> Act(
11967330f729Sjoerg       new TopLevelDeclTrackerAction(*this));
11977330f729Sjoerg 
11987330f729Sjoerg   // Recover resources if we crash before exiting this method.
11997330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
12007330f729Sjoerg     ActCleanup(Act.get());
12017330f729Sjoerg 
12027330f729Sjoerg   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
1203*e038c9c4Sjoerg     return true;
12047330f729Sjoerg 
12057330f729Sjoerg   if (SavedMainFileBuffer)
12067330f729Sjoerg     TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
12077330f729Sjoerg                                PreambleDiagnostics, StoredDiagnostics);
12087330f729Sjoerg   else
12097330f729Sjoerg     PreambleSrcLocCache.clear();
12107330f729Sjoerg 
12117330f729Sjoerg   if (llvm::Error Err = Act->Execute()) {
12127330f729Sjoerg     consumeError(std::move(Err)); // FIXME this drops errors on the floor.
1213*e038c9c4Sjoerg     return true;
12147330f729Sjoerg   }
12157330f729Sjoerg 
12167330f729Sjoerg   transferASTDataFromCompilerInstance(*Clang);
12177330f729Sjoerg 
12187330f729Sjoerg   Act->EndSourceFile();
12197330f729Sjoerg 
12207330f729Sjoerg   FailedParseDiagnostics.clear();
12217330f729Sjoerg 
1222*e038c9c4Sjoerg   CleanOnError.release();
1223*e038c9c4Sjoerg 
12247330f729Sjoerg   return false;
12257330f729Sjoerg }
12267330f729Sjoerg 
12277330f729Sjoerg static std::pair<unsigned, unsigned>
makeStandaloneRange(CharSourceRange Range,const SourceManager & SM,const LangOptions & LangOpts)12287330f729Sjoerg makeStandaloneRange(CharSourceRange Range, const SourceManager &SM,
12297330f729Sjoerg                     const LangOptions &LangOpts) {
12307330f729Sjoerg   CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts);
12317330f729Sjoerg   unsigned Offset = SM.getFileOffset(FileRange.getBegin());
12327330f729Sjoerg   unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());
12337330f729Sjoerg   return std::make_pair(Offset, EndOffset);
12347330f729Sjoerg }
12357330f729Sjoerg 
makeStandaloneFixIt(const SourceManager & SM,const LangOptions & LangOpts,const FixItHint & InFix)12367330f729Sjoerg static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM,
12377330f729Sjoerg                                                     const LangOptions &LangOpts,
12387330f729Sjoerg                                                     const FixItHint &InFix) {
12397330f729Sjoerg   ASTUnit::StandaloneFixIt OutFix;
12407330f729Sjoerg   OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);
12417330f729Sjoerg   OutFix.InsertFromRange = makeStandaloneRange(InFix.InsertFromRange, SM,
12427330f729Sjoerg                                                LangOpts);
12437330f729Sjoerg   OutFix.CodeToInsert = InFix.CodeToInsert;
12447330f729Sjoerg   OutFix.BeforePreviousInsertions = InFix.BeforePreviousInsertions;
12457330f729Sjoerg   return OutFix;
12467330f729Sjoerg }
12477330f729Sjoerg 
12487330f729Sjoerg static ASTUnit::StandaloneDiagnostic
makeStandaloneDiagnostic(const LangOptions & LangOpts,const StoredDiagnostic & InDiag)12497330f729Sjoerg makeStandaloneDiagnostic(const LangOptions &LangOpts,
12507330f729Sjoerg                          const StoredDiagnostic &InDiag) {
12517330f729Sjoerg   ASTUnit::StandaloneDiagnostic OutDiag;
12527330f729Sjoerg   OutDiag.ID = InDiag.getID();
12537330f729Sjoerg   OutDiag.Level = InDiag.getLevel();
1254*e038c9c4Sjoerg   OutDiag.Message = std::string(InDiag.getMessage());
12557330f729Sjoerg   OutDiag.LocOffset = 0;
12567330f729Sjoerg   if (InDiag.getLocation().isInvalid())
12577330f729Sjoerg     return OutDiag;
12587330f729Sjoerg   const SourceManager &SM = InDiag.getLocation().getManager();
12597330f729Sjoerg   SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());
1260*e038c9c4Sjoerg   OutDiag.Filename = std::string(SM.getFilename(FileLoc));
12617330f729Sjoerg   if (OutDiag.Filename.empty())
12627330f729Sjoerg     return OutDiag;
12637330f729Sjoerg   OutDiag.LocOffset = SM.getFileOffset(FileLoc);
12647330f729Sjoerg   for (const auto &Range : InDiag.getRanges())
12657330f729Sjoerg     OutDiag.Ranges.push_back(makeStandaloneRange(Range, SM, LangOpts));
12667330f729Sjoerg   for (const auto &FixIt : InDiag.getFixIts())
12677330f729Sjoerg     OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, FixIt));
12687330f729Sjoerg 
12697330f729Sjoerg   return OutDiag;
12707330f729Sjoerg }
12717330f729Sjoerg 
12727330f729Sjoerg /// Attempt to build or re-use a precompiled preamble when (re-)parsing
12737330f729Sjoerg /// the source file.
12747330f729Sjoerg ///
12757330f729Sjoerg /// This routine will compute the preamble of the main source file. If a
12767330f729Sjoerg /// non-trivial preamble is found, it will precompile that preamble into a
12777330f729Sjoerg /// precompiled header so that the precompiled preamble can be used to reduce
12787330f729Sjoerg /// reparsing time. If a precompiled preamble has already been constructed,
12797330f729Sjoerg /// this routine will determine if it is still valid and, if so, avoid
12807330f729Sjoerg /// rebuilding the precompiled preamble.
12817330f729Sjoerg ///
12827330f729Sjoerg /// \param AllowRebuild When true (the default), this routine is
12837330f729Sjoerg /// allowed to rebuild the precompiled preamble if it is found to be
12847330f729Sjoerg /// out-of-date.
12857330f729Sjoerg ///
12867330f729Sjoerg /// \param MaxLines When non-zero, the maximum number of lines that
12877330f729Sjoerg /// can occur within the preamble.
12887330f729Sjoerg ///
12897330f729Sjoerg /// \returns If the precompiled preamble can be used, returns a newly-allocated
12907330f729Sjoerg /// buffer that should be used in place of the main file when doing so.
12917330f729Sjoerg /// Otherwise, returns a NULL pointer.
12927330f729Sjoerg std::unique_ptr<llvm::MemoryBuffer>
getMainBufferWithPrecompiledPreamble(std::shared_ptr<PCHContainerOperations> PCHContainerOps,CompilerInvocation & PreambleInvocationIn,IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,bool AllowRebuild,unsigned MaxLines)12937330f729Sjoerg ASTUnit::getMainBufferWithPrecompiledPreamble(
12947330f729Sjoerg     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
12957330f729Sjoerg     CompilerInvocation &PreambleInvocationIn,
12967330f729Sjoerg     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild,
12977330f729Sjoerg     unsigned MaxLines) {
12987330f729Sjoerg   auto MainFilePath =
12997330f729Sjoerg       PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
13007330f729Sjoerg   std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
13017330f729Sjoerg       getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
13027330f729Sjoerg                                         MainFilePath, UserFilesAreVolatile);
13037330f729Sjoerg   if (!MainFileBuffer)
13047330f729Sjoerg     return nullptr;
13057330f729Sjoerg 
1306*e038c9c4Sjoerg   PreambleBounds Bounds = ComputePreambleBounds(
1307*e038c9c4Sjoerg       *PreambleInvocationIn.getLangOpts(), *MainFileBuffer, MaxLines);
13087330f729Sjoerg   if (!Bounds.Size)
13097330f729Sjoerg     return nullptr;
13107330f729Sjoerg 
13117330f729Sjoerg   if (Preamble) {
1312*e038c9c4Sjoerg     if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
1313*e038c9c4Sjoerg                            *VFS)) {
13147330f729Sjoerg       // Okay! We can re-use the precompiled preamble.
13157330f729Sjoerg 
13167330f729Sjoerg       // Set the state of the diagnostic object to mimic its state
13177330f729Sjoerg       // after parsing the preamble.
13187330f729Sjoerg       getDiagnostics().Reset();
13197330f729Sjoerg       ProcessWarningOptions(getDiagnostics(),
13207330f729Sjoerg                             PreambleInvocationIn.getDiagnosticOpts());
13217330f729Sjoerg       getDiagnostics().setNumWarnings(NumWarningsInPreamble);
13227330f729Sjoerg 
13237330f729Sjoerg       PreambleRebuildCountdown = 1;
13247330f729Sjoerg       return MainFileBuffer;
13257330f729Sjoerg     } else {
13267330f729Sjoerg       Preamble.reset();
13277330f729Sjoerg       PreambleDiagnostics.clear();
13287330f729Sjoerg       TopLevelDeclsInPreamble.clear();
13297330f729Sjoerg       PreambleSrcLocCache.clear();
13307330f729Sjoerg       PreambleRebuildCountdown = 1;
13317330f729Sjoerg     }
13327330f729Sjoerg   }
13337330f729Sjoerg 
13347330f729Sjoerg   // If the preamble rebuild counter > 1, it's because we previously
13357330f729Sjoerg   // failed to build a preamble and we're not yet ready to try
13367330f729Sjoerg   // again. Decrement the counter and return a failure.
13377330f729Sjoerg   if (PreambleRebuildCountdown > 1) {
13387330f729Sjoerg     --PreambleRebuildCountdown;
13397330f729Sjoerg     return nullptr;
13407330f729Sjoerg   }
13417330f729Sjoerg 
13427330f729Sjoerg   assert(!Preamble && "No Preamble should be stored at that point");
13437330f729Sjoerg   // If we aren't allowed to rebuild the precompiled preamble, just
13447330f729Sjoerg   // return now.
13457330f729Sjoerg   if (!AllowRebuild)
13467330f729Sjoerg     return nullptr;
13477330f729Sjoerg 
13487330f729Sjoerg   ++PreambleCounter;
13497330f729Sjoerg 
13507330f729Sjoerg   SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;
13517330f729Sjoerg   SmallVector<StoredDiagnostic, 4> NewPreambleDiags;
13527330f729Sjoerg   ASTUnitPreambleCallbacks Callbacks;
13537330f729Sjoerg   {
13547330f729Sjoerg     llvm::Optional<CaptureDroppedDiagnostics> Capture;
13557330f729Sjoerg     if (CaptureDiagnostics != CaptureDiagsKind::None)
13567330f729Sjoerg       Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,
13577330f729Sjoerg                       &NewPreambleDiagsStandalone);
13587330f729Sjoerg 
13597330f729Sjoerg     // We did not previously compute a preamble, or it can't be reused anyway.
13607330f729Sjoerg     SimpleTimer PreambleTimer(WantTiming);
13617330f729Sjoerg     PreambleTimer.setOutput("Precompiling preamble");
13627330f729Sjoerg 
13637330f729Sjoerg     const bool PreviousSkipFunctionBodies =
13647330f729Sjoerg         PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;
13657330f729Sjoerg     if (SkipFunctionBodies == SkipFunctionBodiesScope::Preamble)
13667330f729Sjoerg       PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true;
13677330f729Sjoerg 
13687330f729Sjoerg     llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(
13697330f729Sjoerg         PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,
13707330f729Sjoerg         PCHContainerOps, /*StoreInMemory=*/false, Callbacks);
13717330f729Sjoerg 
13727330f729Sjoerg     PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
13737330f729Sjoerg         PreviousSkipFunctionBodies;
13747330f729Sjoerg 
13757330f729Sjoerg     if (NewPreamble) {
13767330f729Sjoerg       Preamble = std::move(*NewPreamble);
13777330f729Sjoerg       PreambleRebuildCountdown = 1;
13787330f729Sjoerg     } else {
13797330f729Sjoerg       switch (static_cast<BuildPreambleError>(NewPreamble.getError().value())) {
13807330f729Sjoerg       case BuildPreambleError::CouldntCreateTempFile:
13817330f729Sjoerg         // Try again next time.
13827330f729Sjoerg         PreambleRebuildCountdown = 1;
13837330f729Sjoerg         return nullptr;
13847330f729Sjoerg       case BuildPreambleError::CouldntCreateTargetInfo:
13857330f729Sjoerg       case BuildPreambleError::BeginSourceFileFailed:
13867330f729Sjoerg       case BuildPreambleError::CouldntEmitPCH:
13877330f729Sjoerg       case BuildPreambleError::BadInputs:
13887330f729Sjoerg         // These erros are more likely to repeat, retry after some period.
13897330f729Sjoerg         PreambleRebuildCountdown = DefaultPreambleRebuildInterval;
13907330f729Sjoerg         return nullptr;
13917330f729Sjoerg       }
13927330f729Sjoerg       llvm_unreachable("unexpected BuildPreambleError");
13937330f729Sjoerg     }
13947330f729Sjoerg   }
13957330f729Sjoerg 
13967330f729Sjoerg   assert(Preamble && "Preamble wasn't built");
13977330f729Sjoerg 
13987330f729Sjoerg   TopLevelDecls.clear();
13997330f729Sjoerg   TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
14007330f729Sjoerg   PreambleTopLevelHashValue = Callbacks.getHash();
14017330f729Sjoerg 
14027330f729Sjoerg   NumWarningsInPreamble = getDiagnostics().getNumWarnings();
14037330f729Sjoerg 
14047330f729Sjoerg   checkAndRemoveNonDriverDiags(NewPreambleDiags);
14057330f729Sjoerg   StoredDiagnostics = std::move(NewPreambleDiags);
14067330f729Sjoerg   PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
14077330f729Sjoerg 
14087330f729Sjoerg   // If the hash of top-level entities differs from the hash of the top-level
14097330f729Sjoerg   // entities the last time we rebuilt the preamble, clear out the completion
14107330f729Sjoerg   // cache.
14117330f729Sjoerg   if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
14127330f729Sjoerg     CompletionCacheTopLevelHashValue = 0;
14137330f729Sjoerg     PreambleTopLevelHashValue = CurrentTopLevelHashValue;
14147330f729Sjoerg   }
14157330f729Sjoerg 
14167330f729Sjoerg   return MainFileBuffer;
14177330f729Sjoerg }
14187330f729Sjoerg 
RealizeTopLevelDeclsFromPreamble()14197330f729Sjoerg void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
14207330f729Sjoerg   assert(Preamble && "Should only be called when preamble was built");
14217330f729Sjoerg 
14227330f729Sjoerg   std::vector<Decl *> Resolved;
14237330f729Sjoerg   Resolved.reserve(TopLevelDeclsInPreamble.size());
14247330f729Sjoerg   ExternalASTSource &Source = *getASTContext().getExternalSource();
14257330f729Sjoerg   for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
14267330f729Sjoerg     // Resolve the declaration ID to an actual declaration, possibly
14277330f729Sjoerg     // deserializing the declaration in the process.
14287330f729Sjoerg     if (Decl *D = Source.GetExternalDecl(TopLevelDecl))
14297330f729Sjoerg       Resolved.push_back(D);
14307330f729Sjoerg   }
14317330f729Sjoerg   TopLevelDeclsInPreamble.clear();
14327330f729Sjoerg   TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
14337330f729Sjoerg }
14347330f729Sjoerg 
transferASTDataFromCompilerInstance(CompilerInstance & CI)14357330f729Sjoerg void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
14367330f729Sjoerg   // Steal the created target, context, and preprocessor if they have been
14377330f729Sjoerg   // created.
14387330f729Sjoerg   assert(CI.hasInvocation() && "missing invocation");
14397330f729Sjoerg   LangOpts = CI.getInvocation().LangOpts;
14407330f729Sjoerg   TheSema = CI.takeSema();
14417330f729Sjoerg   Consumer = CI.takeASTConsumer();
14427330f729Sjoerg   if (CI.hasASTContext())
14437330f729Sjoerg     Ctx = &CI.getASTContext();
14447330f729Sjoerg   if (CI.hasPreprocessor())
14457330f729Sjoerg     PP = CI.getPreprocessorPtr();
14467330f729Sjoerg   CI.setSourceManager(nullptr);
14477330f729Sjoerg   CI.setFileManager(nullptr);
14487330f729Sjoerg   if (CI.hasTarget())
14497330f729Sjoerg     Target = &CI.getTarget();
1450*e038c9c4Sjoerg   Reader = CI.getASTReader();
14517330f729Sjoerg   HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
14527330f729Sjoerg }
14537330f729Sjoerg 
getMainFileName() const14547330f729Sjoerg StringRef ASTUnit::getMainFileName() const {
14557330f729Sjoerg   if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
14567330f729Sjoerg     const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];
14577330f729Sjoerg     if (Input.isFile())
14587330f729Sjoerg       return Input.getFile();
14597330f729Sjoerg     else
1460*e038c9c4Sjoerg       return Input.getBuffer().getBufferIdentifier();
14617330f729Sjoerg   }
14627330f729Sjoerg 
14637330f729Sjoerg   if (SourceMgr) {
14647330f729Sjoerg     if (const FileEntry *
14657330f729Sjoerg           FE = SourceMgr->getFileEntryForID(SourceMgr->getMainFileID()))
14667330f729Sjoerg       return FE->getName();
14677330f729Sjoerg   }
14687330f729Sjoerg 
14697330f729Sjoerg   return {};
14707330f729Sjoerg }
14717330f729Sjoerg 
getASTFileName() const14727330f729Sjoerg StringRef ASTUnit::getASTFileName() const {
14737330f729Sjoerg   if (!isMainFileAST())
14747330f729Sjoerg     return {};
14757330f729Sjoerg 
14767330f729Sjoerg   serialization::ModuleFile &
14777330f729Sjoerg     Mod = Reader->getModuleManager().getPrimaryModule();
14787330f729Sjoerg   return Mod.FileName;
14797330f729Sjoerg }
14807330f729Sjoerg 
14817330f729Sjoerg std::unique_ptr<ASTUnit>
create(std::shared_ptr<CompilerInvocation> CI,IntrusiveRefCntPtr<DiagnosticsEngine> Diags,CaptureDiagsKind CaptureDiagnostics,bool UserFilesAreVolatile)14827330f729Sjoerg ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
14837330f729Sjoerg                 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
14847330f729Sjoerg                 CaptureDiagsKind CaptureDiagnostics,
14857330f729Sjoerg                 bool UserFilesAreVolatile) {
14867330f729Sjoerg   std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
14877330f729Sjoerg   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
14887330f729Sjoerg   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
14897330f729Sjoerg       createVFSFromCompilerInvocation(*CI, *Diags);
14907330f729Sjoerg   AST->Diagnostics = Diags;
14917330f729Sjoerg   AST->FileSystemOpts = CI->getFileSystemOpts();
14927330f729Sjoerg   AST->Invocation = std::move(CI);
14937330f729Sjoerg   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
14947330f729Sjoerg   AST->UserFilesAreVolatile = UserFilesAreVolatile;
14957330f729Sjoerg   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
14967330f729Sjoerg                                      UserFilesAreVolatile);
14977330f729Sjoerg   AST->ModuleCache = new InMemoryModuleCache;
14987330f729Sjoerg 
14997330f729Sjoerg   return AST;
15007330f729Sjoerg }
15017330f729Sjoerg 
LoadFromCompilerInvocationAction(std::shared_ptr<CompilerInvocation> CI,std::shared_ptr<PCHContainerOperations> PCHContainerOps,IntrusiveRefCntPtr<DiagnosticsEngine> Diags,FrontendAction * Action,ASTUnit * Unit,bool Persistent,StringRef ResourceFilesPath,bool OnlyLocalDecls,CaptureDiagsKind CaptureDiagnostics,unsigned PrecompilePreambleAfterNParses,bool CacheCodeCompletionResults,bool UserFilesAreVolatile,std::unique_ptr<ASTUnit> * ErrAST)15027330f729Sjoerg ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
15037330f729Sjoerg     std::shared_ptr<CompilerInvocation> CI,
15047330f729Sjoerg     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
15057330f729Sjoerg     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action,
15067330f729Sjoerg     ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
15077330f729Sjoerg     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
15087330f729Sjoerg     unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
1509*e038c9c4Sjoerg     bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
15107330f729Sjoerg   assert(CI && "A CompilerInvocation is required");
15117330f729Sjoerg 
15127330f729Sjoerg   std::unique_ptr<ASTUnit> OwnAST;
15137330f729Sjoerg   ASTUnit *AST = Unit;
15147330f729Sjoerg   if (!AST) {
15157330f729Sjoerg     // Create the AST unit.
15167330f729Sjoerg     OwnAST = create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile);
15177330f729Sjoerg     AST = OwnAST.get();
15187330f729Sjoerg     if (!AST)
15197330f729Sjoerg       return nullptr;
15207330f729Sjoerg   }
15217330f729Sjoerg 
15227330f729Sjoerg   if (!ResourceFilesPath.empty()) {
15237330f729Sjoerg     // Override the resources path.
1524*e038c9c4Sjoerg     CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
15257330f729Sjoerg   }
15267330f729Sjoerg   AST->OnlyLocalDecls = OnlyLocalDecls;
15277330f729Sjoerg   AST->CaptureDiagnostics = CaptureDiagnostics;
15287330f729Sjoerg   if (PrecompilePreambleAfterNParses > 0)
15297330f729Sjoerg     AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
15307330f729Sjoerg   AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
15317330f729Sjoerg   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1532*e038c9c4Sjoerg   AST->IncludeBriefCommentsInCodeCompletion = false;
15337330f729Sjoerg 
15347330f729Sjoerg   // Recover resources if we crash before exiting this method.
15357330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
15367330f729Sjoerg     ASTUnitCleanup(OwnAST.get());
15377330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
15387330f729Sjoerg     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
15397330f729Sjoerg     DiagCleanup(Diags.get());
15407330f729Sjoerg 
15417330f729Sjoerg   // We'll manage file buffers ourselves.
15427330f729Sjoerg   CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
15437330f729Sjoerg   CI->getFrontendOpts().DisableFree = false;
15447330f729Sjoerg   ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
15457330f729Sjoerg 
15467330f729Sjoerg   // Create the compiler instance to use for building the AST.
15477330f729Sjoerg   std::unique_ptr<CompilerInstance> Clang(
15487330f729Sjoerg       new CompilerInstance(std::move(PCHContainerOps)));
15497330f729Sjoerg 
15507330f729Sjoerg   // Recover resources if we crash before exiting this method.
15517330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
15527330f729Sjoerg     CICleanup(Clang.get());
15537330f729Sjoerg 
15547330f729Sjoerg   Clang->setInvocation(std::move(CI));
1555*e038c9c4Sjoerg   AST->OriginalSourceFile =
1556*e038c9c4Sjoerg       std::string(Clang->getFrontendOpts().Inputs[0].getFile());
15577330f729Sjoerg 
15587330f729Sjoerg   // Set up diagnostics, capturing any diagnostics that would
15597330f729Sjoerg   // otherwise be dropped.
15607330f729Sjoerg   Clang->setDiagnostics(&AST->getDiagnostics());
15617330f729Sjoerg 
15627330f729Sjoerg   // Create the target instance.
1563*e038c9c4Sjoerg   if (!Clang->createTarget())
15647330f729Sjoerg     return nullptr;
15657330f729Sjoerg 
15667330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
15677330f729Sjoerg          "Invocation must have exactly one source file!");
15687330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
15697330f729Sjoerg              InputKind::Source &&
15707330f729Sjoerg          "FIXME: AST inputs not yet supported here!");
15717330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
15727330f729Sjoerg              Language::LLVM_IR &&
15737330f729Sjoerg          "IR inputs not support here!");
15747330f729Sjoerg 
15757330f729Sjoerg   // Configure the various subsystems.
15767330f729Sjoerg   AST->TheSema.reset();
15777330f729Sjoerg   AST->Ctx = nullptr;
15787330f729Sjoerg   AST->PP = nullptr;
15797330f729Sjoerg   AST->Reader = nullptr;
15807330f729Sjoerg 
15817330f729Sjoerg   // Create a file manager object to provide access to and cache the filesystem.
15827330f729Sjoerg   Clang->setFileManager(&AST->getFileManager());
15837330f729Sjoerg 
15847330f729Sjoerg   // Create the source manager.
15857330f729Sjoerg   Clang->setSourceManager(&AST->getSourceManager());
15867330f729Sjoerg 
15877330f729Sjoerg   FrontendAction *Act = Action;
15887330f729Sjoerg 
15897330f729Sjoerg   std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
15907330f729Sjoerg   if (!Act) {
15917330f729Sjoerg     TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
15927330f729Sjoerg     Act = TrackerAct.get();
15937330f729Sjoerg   }
15947330f729Sjoerg 
15957330f729Sjoerg   // Recover resources if we crash before exiting this method.
15967330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
15977330f729Sjoerg     ActCleanup(TrackerAct.get());
15987330f729Sjoerg 
15997330f729Sjoerg   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
16007330f729Sjoerg     AST->transferASTDataFromCompilerInstance(*Clang);
16017330f729Sjoerg     if (OwnAST && ErrAST)
16027330f729Sjoerg       ErrAST->swap(OwnAST);
16037330f729Sjoerg 
16047330f729Sjoerg     return nullptr;
16057330f729Sjoerg   }
16067330f729Sjoerg 
16077330f729Sjoerg   if (Persistent && !TrackerAct) {
16087330f729Sjoerg     Clang->getPreprocessor().addPPCallbacks(
16097330f729Sjoerg         std::make_unique<MacroDefinitionTrackerPPCallbacks>(
16107330f729Sjoerg                                            AST->getCurrentTopLevelHashValue()));
16117330f729Sjoerg     std::vector<std::unique_ptr<ASTConsumer>> Consumers;
16127330f729Sjoerg     if (Clang->hasASTConsumer())
16137330f729Sjoerg       Consumers.push_back(Clang->takeASTConsumer());
16147330f729Sjoerg     Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
16157330f729Sjoerg         *AST, AST->getCurrentTopLevelHashValue()));
16167330f729Sjoerg     Clang->setASTConsumer(
16177330f729Sjoerg         std::make_unique<MultiplexConsumer>(std::move(Consumers)));
16187330f729Sjoerg   }
16197330f729Sjoerg   if (llvm::Error Err = Act->Execute()) {
16207330f729Sjoerg     consumeError(std::move(Err)); // FIXME this drops errors on the floor.
16217330f729Sjoerg     AST->transferASTDataFromCompilerInstance(*Clang);
16227330f729Sjoerg     if (OwnAST && ErrAST)
16237330f729Sjoerg       ErrAST->swap(OwnAST);
16247330f729Sjoerg 
16257330f729Sjoerg     return nullptr;
16267330f729Sjoerg   }
16277330f729Sjoerg 
16287330f729Sjoerg   // Steal the created target, context, and preprocessor.
16297330f729Sjoerg   AST->transferASTDataFromCompilerInstance(*Clang);
16307330f729Sjoerg 
16317330f729Sjoerg   Act->EndSourceFile();
16327330f729Sjoerg 
16337330f729Sjoerg   if (OwnAST)
16347330f729Sjoerg     return OwnAST.release();
16357330f729Sjoerg   else
16367330f729Sjoerg     return AST;
16377330f729Sjoerg }
16387330f729Sjoerg 
LoadFromCompilerInvocation(std::shared_ptr<PCHContainerOperations> PCHContainerOps,unsigned PrecompilePreambleAfterNParses,IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)16397330f729Sjoerg bool ASTUnit::LoadFromCompilerInvocation(
16407330f729Sjoerg     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
16417330f729Sjoerg     unsigned PrecompilePreambleAfterNParses,
16427330f729Sjoerg     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
16437330f729Sjoerg   if (!Invocation)
16447330f729Sjoerg     return true;
16457330f729Sjoerg 
16467330f729Sjoerg   assert(VFS && "VFS is null");
16477330f729Sjoerg 
16487330f729Sjoerg   // We'll manage file buffers ourselves.
16497330f729Sjoerg   Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
16507330f729Sjoerg   Invocation->getFrontendOpts().DisableFree = false;
16517330f729Sjoerg   getDiagnostics().Reset();
16527330f729Sjoerg   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
16537330f729Sjoerg 
16547330f729Sjoerg   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
16557330f729Sjoerg   if (PrecompilePreambleAfterNParses > 0) {
16567330f729Sjoerg     PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
16577330f729Sjoerg     OverrideMainBuffer =
16587330f729Sjoerg         getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
16597330f729Sjoerg     getDiagnostics().Reset();
16607330f729Sjoerg     ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
16617330f729Sjoerg   }
16627330f729Sjoerg 
16637330f729Sjoerg   SimpleTimer ParsingTimer(WantTiming);
16647330f729Sjoerg   ParsingTimer.setOutput("Parsing " + getMainFileName());
16657330f729Sjoerg 
16667330f729Sjoerg   // Recover resources if we crash before exiting this method.
16677330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
16687330f729Sjoerg     MemBufferCleanup(OverrideMainBuffer.get());
16697330f729Sjoerg 
16707330f729Sjoerg   return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
16717330f729Sjoerg }
16727330f729Sjoerg 
LoadFromCompilerInvocation(std::shared_ptr<CompilerInvocation> CI,std::shared_ptr<PCHContainerOperations> PCHContainerOps,IntrusiveRefCntPtr<DiagnosticsEngine> Diags,FileManager * FileMgr,bool OnlyLocalDecls,CaptureDiagsKind CaptureDiagnostics,unsigned PrecompilePreambleAfterNParses,TranslationUnitKind TUKind,bool CacheCodeCompletionResults,bool IncludeBriefCommentsInCodeCompletion,bool UserFilesAreVolatile)16737330f729Sjoerg std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
16747330f729Sjoerg     std::shared_ptr<CompilerInvocation> CI,
16757330f729Sjoerg     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
16767330f729Sjoerg     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
16777330f729Sjoerg     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
16787330f729Sjoerg     unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
16797330f729Sjoerg     bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
16807330f729Sjoerg     bool UserFilesAreVolatile) {
16817330f729Sjoerg   // Create the AST unit.
16827330f729Sjoerg   std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
16837330f729Sjoerg   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
16847330f729Sjoerg   AST->Diagnostics = Diags;
16857330f729Sjoerg   AST->OnlyLocalDecls = OnlyLocalDecls;
16867330f729Sjoerg   AST->CaptureDiagnostics = CaptureDiagnostics;
16877330f729Sjoerg   AST->TUKind = TUKind;
16887330f729Sjoerg   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
16897330f729Sjoerg   AST->IncludeBriefCommentsInCodeCompletion
16907330f729Sjoerg     = IncludeBriefCommentsInCodeCompletion;
16917330f729Sjoerg   AST->Invocation = std::move(CI);
16927330f729Sjoerg   AST->FileSystemOpts = FileMgr->getFileSystemOpts();
16937330f729Sjoerg   AST->FileMgr = FileMgr;
16947330f729Sjoerg   AST->UserFilesAreVolatile = UserFilesAreVolatile;
16957330f729Sjoerg 
16967330f729Sjoerg   // Recover resources if we crash before exiting this method.
16977330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
16987330f729Sjoerg     ASTUnitCleanup(AST.get());
16997330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
17007330f729Sjoerg     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
17017330f729Sjoerg     DiagCleanup(Diags.get());
17027330f729Sjoerg 
17037330f729Sjoerg   if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
17047330f729Sjoerg                                       PrecompilePreambleAfterNParses,
17057330f729Sjoerg                                       &AST->FileMgr->getVirtualFileSystem()))
17067330f729Sjoerg     return nullptr;
17077330f729Sjoerg   return AST;
17087330f729Sjoerg }
17097330f729Sjoerg 
LoadFromCommandLine(const char ** ArgBegin,const char ** ArgEnd,std::shared_ptr<PCHContainerOperations> PCHContainerOps,IntrusiveRefCntPtr<DiagnosticsEngine> Diags,StringRef ResourceFilesPath,bool OnlyLocalDecls,CaptureDiagsKind CaptureDiagnostics,ArrayRef<RemappedFile> RemappedFiles,bool RemappedFilesKeepOriginalName,unsigned PrecompilePreambleAfterNParses,TranslationUnitKind TUKind,bool CacheCodeCompletionResults,bool IncludeBriefCommentsInCodeCompletion,bool AllowPCHWithCompilerErrors,SkipFunctionBodiesScope SkipFunctionBodies,bool SingleFileParse,bool UserFilesAreVolatile,bool ForSerialization,bool RetainExcludedConditionalBlocks,llvm::Optional<StringRef> ModuleFormat,std::unique_ptr<ASTUnit> * ErrAST,IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)17107330f729Sjoerg ASTUnit *ASTUnit::LoadFromCommandLine(
17117330f729Sjoerg     const char **ArgBegin, const char **ArgEnd,
17127330f729Sjoerg     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
17137330f729Sjoerg     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
17147330f729Sjoerg     bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
17157330f729Sjoerg     ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
17167330f729Sjoerg     unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
17177330f729Sjoerg     bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
17187330f729Sjoerg     bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
17197330f729Sjoerg     bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
17207330f729Sjoerg     bool RetainExcludedConditionalBlocks,
17217330f729Sjoerg     llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST,
17227330f729Sjoerg     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
17237330f729Sjoerg   assert(Diags.get() && "no DiagnosticsEngine was provided");
17247330f729Sjoerg 
17257330f729Sjoerg   SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
17267330f729Sjoerg 
17277330f729Sjoerg   std::shared_ptr<CompilerInvocation> CI;
17287330f729Sjoerg 
17297330f729Sjoerg   {
17307330f729Sjoerg     CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
17317330f729Sjoerg                                       &StoredDiagnostics, nullptr);
17327330f729Sjoerg 
17337330f729Sjoerg     CI = createInvocationFromCommandLine(
17347330f729Sjoerg         llvm::makeArrayRef(ArgBegin, ArgEnd), Diags, VFS);
17357330f729Sjoerg     if (!CI)
17367330f729Sjoerg       return nullptr;
17377330f729Sjoerg   }
17387330f729Sjoerg 
17397330f729Sjoerg   // Override any files that need remapping
17407330f729Sjoerg   for (const auto &RemappedFile : RemappedFiles) {
17417330f729Sjoerg     CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
17427330f729Sjoerg                                               RemappedFile.second);
17437330f729Sjoerg   }
17447330f729Sjoerg   PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
17457330f729Sjoerg   PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
17467330f729Sjoerg   PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
17477330f729Sjoerg   PPOpts.SingleFileParseMode = SingleFileParse;
17487330f729Sjoerg   PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
17497330f729Sjoerg 
17507330f729Sjoerg   // Override the resources path.
1751*e038c9c4Sjoerg   CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
17527330f729Sjoerg 
17537330f729Sjoerg   CI->getFrontendOpts().SkipFunctionBodies =
17547330f729Sjoerg       SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile;
17557330f729Sjoerg 
17567330f729Sjoerg   if (ModuleFormat)
1757*e038c9c4Sjoerg     CI->getHeaderSearchOpts().ModuleFormat =
1758*e038c9c4Sjoerg         std::string(ModuleFormat.getValue());
17597330f729Sjoerg 
17607330f729Sjoerg   // Create the AST unit.
17617330f729Sjoerg   std::unique_ptr<ASTUnit> AST;
17627330f729Sjoerg   AST.reset(new ASTUnit(false));
17637330f729Sjoerg   AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
17647330f729Sjoerg   AST->StoredDiagnostics.swap(StoredDiagnostics);
17657330f729Sjoerg   ConfigureDiags(Diags, *AST, CaptureDiagnostics);
17667330f729Sjoerg   AST->Diagnostics = Diags;
17677330f729Sjoerg   AST->FileSystemOpts = CI->getFileSystemOpts();
17687330f729Sjoerg   if (!VFS)
17697330f729Sjoerg     VFS = llvm::vfs::getRealFileSystem();
17707330f729Sjoerg   VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
17717330f729Sjoerg   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
17727330f729Sjoerg   AST->ModuleCache = new InMemoryModuleCache;
17737330f729Sjoerg   AST->OnlyLocalDecls = OnlyLocalDecls;
17747330f729Sjoerg   AST->CaptureDiagnostics = CaptureDiagnostics;
17757330f729Sjoerg   AST->TUKind = TUKind;
17767330f729Sjoerg   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
17777330f729Sjoerg   AST->IncludeBriefCommentsInCodeCompletion
17787330f729Sjoerg     = IncludeBriefCommentsInCodeCompletion;
17797330f729Sjoerg   AST->UserFilesAreVolatile = UserFilesAreVolatile;
17807330f729Sjoerg   AST->Invocation = CI;
17817330f729Sjoerg   AST->SkipFunctionBodies = SkipFunctionBodies;
17827330f729Sjoerg   if (ForSerialization)
17837330f729Sjoerg     AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));
17847330f729Sjoerg   // Zero out now to ease cleanup during crash recovery.
17857330f729Sjoerg   CI = nullptr;
17867330f729Sjoerg   Diags = nullptr;
17877330f729Sjoerg 
17887330f729Sjoerg   // Recover resources if we crash before exiting this method.
17897330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
17907330f729Sjoerg     ASTUnitCleanup(AST.get());
17917330f729Sjoerg 
17927330f729Sjoerg   if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
17937330f729Sjoerg                                       PrecompilePreambleAfterNParses,
17947330f729Sjoerg                                       VFS)) {
17957330f729Sjoerg     // Some error occurred, if caller wants to examine diagnostics, pass it the
17967330f729Sjoerg     // ASTUnit.
17977330f729Sjoerg     if (ErrAST) {
17987330f729Sjoerg       AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
17997330f729Sjoerg       ErrAST->swap(AST);
18007330f729Sjoerg     }
18017330f729Sjoerg     return nullptr;
18027330f729Sjoerg   }
18037330f729Sjoerg 
18047330f729Sjoerg   return AST.release();
18057330f729Sjoerg }
18067330f729Sjoerg 
Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,ArrayRef<RemappedFile> RemappedFiles,IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)18077330f729Sjoerg bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
18087330f729Sjoerg                       ArrayRef<RemappedFile> RemappedFiles,
18097330f729Sjoerg                       IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
18107330f729Sjoerg   if (!Invocation)
18117330f729Sjoerg     return true;
18127330f729Sjoerg 
18137330f729Sjoerg   if (!VFS) {
18147330f729Sjoerg     assert(FileMgr && "FileMgr is null on Reparse call");
18157330f729Sjoerg     VFS = &FileMgr->getVirtualFileSystem();
18167330f729Sjoerg   }
18177330f729Sjoerg 
18187330f729Sjoerg   clearFileLevelDecls();
18197330f729Sjoerg 
18207330f729Sjoerg   SimpleTimer ParsingTimer(WantTiming);
18217330f729Sjoerg   ParsingTimer.setOutput("Reparsing " + getMainFileName());
18227330f729Sjoerg 
18237330f729Sjoerg   // Remap files.
18247330f729Sjoerg   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
18257330f729Sjoerg   for (const auto &RB : PPOpts.RemappedFileBuffers)
18267330f729Sjoerg     delete RB.second;
18277330f729Sjoerg 
18287330f729Sjoerg   Invocation->getPreprocessorOpts().clearRemappedFiles();
18297330f729Sjoerg   for (const auto &RemappedFile : RemappedFiles) {
18307330f729Sjoerg     Invocation->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
18317330f729Sjoerg                                                       RemappedFile.second);
18327330f729Sjoerg   }
18337330f729Sjoerg 
18347330f729Sjoerg   // If we have a preamble file lying around, or if we might try to
18357330f729Sjoerg   // build a precompiled preamble, do so now.
18367330f729Sjoerg   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
18377330f729Sjoerg   if (Preamble || PreambleRebuildCountdown > 0)
18387330f729Sjoerg     OverrideMainBuffer =
18397330f729Sjoerg         getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
18407330f729Sjoerg 
18417330f729Sjoerg   // Clear out the diagnostics state.
18427330f729Sjoerg   FileMgr.reset();
18437330f729Sjoerg   getDiagnostics().Reset();
18447330f729Sjoerg   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
18457330f729Sjoerg   if (OverrideMainBuffer)
18467330f729Sjoerg     getDiagnostics().setNumWarnings(NumWarningsInPreamble);
18477330f729Sjoerg 
18487330f729Sjoerg   // Parse the sources
18497330f729Sjoerg   bool Result =
18507330f729Sjoerg       Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
18517330f729Sjoerg 
18527330f729Sjoerg   // If we're caching global code-completion results, and the top-level
18537330f729Sjoerg   // declarations have changed, clear out the code-completion cache.
18547330f729Sjoerg   if (!Result && ShouldCacheCodeCompletionResults &&
18557330f729Sjoerg       CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
18567330f729Sjoerg     CacheCodeCompletionResults();
18577330f729Sjoerg 
18587330f729Sjoerg   // We now need to clear out the completion info related to this translation
18597330f729Sjoerg   // unit; it'll be recreated if necessary.
18607330f729Sjoerg   CCTUInfo.reset();
18617330f729Sjoerg 
18627330f729Sjoerg   return Result;
18637330f729Sjoerg }
18647330f729Sjoerg 
ResetForParse()18657330f729Sjoerg void ASTUnit::ResetForParse() {
18667330f729Sjoerg   SavedMainFileBuffer.reset();
18677330f729Sjoerg 
18687330f729Sjoerg   SourceMgr.reset();
18697330f729Sjoerg   TheSema.reset();
18707330f729Sjoerg   Ctx.reset();
18717330f729Sjoerg   PP.reset();
18727330f729Sjoerg   Reader.reset();
18737330f729Sjoerg 
18747330f729Sjoerg   TopLevelDecls.clear();
18757330f729Sjoerg   clearFileLevelDecls();
18767330f729Sjoerg }
18777330f729Sjoerg 
18787330f729Sjoerg //----------------------------------------------------------------------------//
18797330f729Sjoerg // Code completion
18807330f729Sjoerg //----------------------------------------------------------------------------//
18817330f729Sjoerg 
18827330f729Sjoerg namespace {
18837330f729Sjoerg 
18847330f729Sjoerg   /// Code completion consumer that combines the cached code-completion
18857330f729Sjoerg   /// results from an ASTUnit with the code-completion results provided to it,
18867330f729Sjoerg   /// then passes the result on to
18877330f729Sjoerg   class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
18887330f729Sjoerg     uint64_t NormalContexts;
18897330f729Sjoerg     ASTUnit &AST;
18907330f729Sjoerg     CodeCompleteConsumer &Next;
18917330f729Sjoerg 
18927330f729Sjoerg   public:
AugmentedCodeCompleteConsumer(ASTUnit & AST,CodeCompleteConsumer & Next,const CodeCompleteOptions & CodeCompleteOpts)18937330f729Sjoerg     AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
18947330f729Sjoerg                                   const CodeCompleteOptions &CodeCompleteOpts)
18957330f729Sjoerg         : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
18967330f729Sjoerg       // Compute the set of contexts in which we will look when we don't have
18977330f729Sjoerg       // any information about the specific context.
18987330f729Sjoerg       NormalContexts
18997330f729Sjoerg         = (1LL << CodeCompletionContext::CCC_TopLevel)
19007330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCInterface)
19017330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
19027330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
19037330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_Statement)
19047330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_Expression)
19057330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
19067330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_DotMemberAccess)
19077330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess)
19087330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess)
19097330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ObjCProtocolName)
19107330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
19117330f729Sjoerg         | (1LL << CodeCompletionContext::CCC_Recovery);
19127330f729Sjoerg 
19137330f729Sjoerg       if (AST.getASTContext().getLangOpts().CPlusPlus)
19147330f729Sjoerg         NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
19157330f729Sjoerg                        |  (1LL << CodeCompletionContext::CCC_UnionTag)
19167330f729Sjoerg                        |  (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
19177330f729Sjoerg     }
19187330f729Sjoerg 
19197330f729Sjoerg     void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
19207330f729Sjoerg                                     CodeCompletionResult *Results,
19217330f729Sjoerg                                     unsigned NumResults) override;
19227330f729Sjoerg 
ProcessOverloadCandidates(Sema & S,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates,SourceLocation OpenParLoc)19237330f729Sjoerg     void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
19247330f729Sjoerg                                    OverloadCandidate *Candidates,
19257330f729Sjoerg                                    unsigned NumCandidates,
19267330f729Sjoerg                                    SourceLocation OpenParLoc) override {
19277330f729Sjoerg       Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
19287330f729Sjoerg                                      OpenParLoc);
19297330f729Sjoerg     }
19307330f729Sjoerg 
getAllocator()19317330f729Sjoerg     CodeCompletionAllocator &getAllocator() override {
19327330f729Sjoerg       return Next.getAllocator();
19337330f729Sjoerg     }
19347330f729Sjoerg 
getCodeCompletionTUInfo()19357330f729Sjoerg     CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
19367330f729Sjoerg       return Next.getCodeCompletionTUInfo();
19377330f729Sjoerg     }
19387330f729Sjoerg   };
19397330f729Sjoerg 
19407330f729Sjoerg } // namespace
19417330f729Sjoerg 
19427330f729Sjoerg /// Helper function that computes which global names are hidden by the
19437330f729Sjoerg /// local code-completion results.
CalculateHiddenNames(const CodeCompletionContext & Context,CodeCompletionResult * Results,unsigned NumResults,ASTContext & Ctx,llvm::StringSet<llvm::BumpPtrAllocator> & HiddenNames)19447330f729Sjoerg static void CalculateHiddenNames(const CodeCompletionContext &Context,
19457330f729Sjoerg                                  CodeCompletionResult *Results,
19467330f729Sjoerg                                  unsigned NumResults,
19477330f729Sjoerg                                  ASTContext &Ctx,
19487330f729Sjoerg                           llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
19497330f729Sjoerg   bool OnlyTagNames = false;
19507330f729Sjoerg   switch (Context.getKind()) {
19517330f729Sjoerg   case CodeCompletionContext::CCC_Recovery:
19527330f729Sjoerg   case CodeCompletionContext::CCC_TopLevel:
19537330f729Sjoerg   case CodeCompletionContext::CCC_ObjCInterface:
19547330f729Sjoerg   case CodeCompletionContext::CCC_ObjCImplementation:
19557330f729Sjoerg   case CodeCompletionContext::CCC_ObjCIvarList:
19567330f729Sjoerg   case CodeCompletionContext::CCC_ClassStructUnion:
19577330f729Sjoerg   case CodeCompletionContext::CCC_Statement:
19587330f729Sjoerg   case CodeCompletionContext::CCC_Expression:
19597330f729Sjoerg   case CodeCompletionContext::CCC_ObjCMessageReceiver:
19607330f729Sjoerg   case CodeCompletionContext::CCC_DotMemberAccess:
19617330f729Sjoerg   case CodeCompletionContext::CCC_ArrowMemberAccess:
19627330f729Sjoerg   case CodeCompletionContext::CCC_ObjCPropertyAccess:
19637330f729Sjoerg   case CodeCompletionContext::CCC_Namespace:
19647330f729Sjoerg   case CodeCompletionContext::CCC_Type:
19657330f729Sjoerg   case CodeCompletionContext::CCC_Symbol:
19667330f729Sjoerg   case CodeCompletionContext::CCC_SymbolOrNewName:
19677330f729Sjoerg   case CodeCompletionContext::CCC_ParenthesizedExpression:
19687330f729Sjoerg   case CodeCompletionContext::CCC_ObjCInterfaceName:
19697330f729Sjoerg     break;
19707330f729Sjoerg 
19717330f729Sjoerg   case CodeCompletionContext::CCC_EnumTag:
19727330f729Sjoerg   case CodeCompletionContext::CCC_UnionTag:
19737330f729Sjoerg   case CodeCompletionContext::CCC_ClassOrStructTag:
19747330f729Sjoerg     OnlyTagNames = true;
19757330f729Sjoerg     break;
19767330f729Sjoerg 
19777330f729Sjoerg   case CodeCompletionContext::CCC_ObjCProtocolName:
19787330f729Sjoerg   case CodeCompletionContext::CCC_MacroName:
19797330f729Sjoerg   case CodeCompletionContext::CCC_MacroNameUse:
19807330f729Sjoerg   case CodeCompletionContext::CCC_PreprocessorExpression:
19817330f729Sjoerg   case CodeCompletionContext::CCC_PreprocessorDirective:
19827330f729Sjoerg   case CodeCompletionContext::CCC_NaturalLanguage:
19837330f729Sjoerg   case CodeCompletionContext::CCC_SelectorName:
19847330f729Sjoerg   case CodeCompletionContext::CCC_TypeQualifiers:
19857330f729Sjoerg   case CodeCompletionContext::CCC_Other:
19867330f729Sjoerg   case CodeCompletionContext::CCC_OtherWithMacros:
19877330f729Sjoerg   case CodeCompletionContext::CCC_ObjCInstanceMessage:
19887330f729Sjoerg   case CodeCompletionContext::CCC_ObjCClassMessage:
19897330f729Sjoerg   case CodeCompletionContext::CCC_ObjCCategoryName:
19907330f729Sjoerg   case CodeCompletionContext::CCC_IncludedFile:
19917330f729Sjoerg   case CodeCompletionContext::CCC_NewName:
19927330f729Sjoerg     // We're looking for nothing, or we're looking for names that cannot
19937330f729Sjoerg     // be hidden.
19947330f729Sjoerg     return;
19957330f729Sjoerg   }
19967330f729Sjoerg 
19977330f729Sjoerg   using Result = CodeCompletionResult;
19987330f729Sjoerg   for (unsigned I = 0; I != NumResults; ++I) {
19997330f729Sjoerg     if (Results[I].Kind != Result::RK_Declaration)
20007330f729Sjoerg       continue;
20017330f729Sjoerg 
20027330f729Sjoerg     unsigned IDNS
20037330f729Sjoerg       = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
20047330f729Sjoerg 
20057330f729Sjoerg     bool Hiding = false;
20067330f729Sjoerg     if (OnlyTagNames)
20077330f729Sjoerg       Hiding = (IDNS & Decl::IDNS_Tag);
20087330f729Sjoerg     else {
20097330f729Sjoerg       unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
20107330f729Sjoerg                              Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
20117330f729Sjoerg                              Decl::IDNS_NonMemberOperator);
20127330f729Sjoerg       if (Ctx.getLangOpts().CPlusPlus)
20137330f729Sjoerg         HiddenIDNS |= Decl::IDNS_Tag;
20147330f729Sjoerg       Hiding = (IDNS & HiddenIDNS);
20157330f729Sjoerg     }
20167330f729Sjoerg 
20177330f729Sjoerg     if (!Hiding)
20187330f729Sjoerg       continue;
20197330f729Sjoerg 
20207330f729Sjoerg     DeclarationName Name = Results[I].Declaration->getDeclName();
20217330f729Sjoerg     if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
20227330f729Sjoerg       HiddenNames.insert(Identifier->getName());
20237330f729Sjoerg     else
20247330f729Sjoerg       HiddenNames.insert(Name.getAsString());
20257330f729Sjoerg   }
20267330f729Sjoerg }
20277330f729Sjoerg 
ProcessCodeCompleteResults(Sema & S,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)20287330f729Sjoerg void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
20297330f729Sjoerg                                             CodeCompletionContext Context,
20307330f729Sjoerg                                             CodeCompletionResult *Results,
20317330f729Sjoerg                                             unsigned NumResults) {
20327330f729Sjoerg   // Merge the results we were given with the results we cached.
20337330f729Sjoerg   bool AddedResult = false;
20347330f729Sjoerg   uint64_t InContexts =
20357330f729Sjoerg       Context.getKind() == CodeCompletionContext::CCC_Recovery
20367330f729Sjoerg         ? NormalContexts : (1LL << Context.getKind());
20377330f729Sjoerg   // Contains the set of names that are hidden by "local" completion results.
20387330f729Sjoerg   llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
20397330f729Sjoerg   using Result = CodeCompletionResult;
20407330f729Sjoerg   SmallVector<Result, 8> AllResults;
20417330f729Sjoerg   for (ASTUnit::cached_completion_iterator
20427330f729Sjoerg             C = AST.cached_completion_begin(),
20437330f729Sjoerg          CEnd = AST.cached_completion_end();
20447330f729Sjoerg        C != CEnd; ++C) {
20457330f729Sjoerg     // If the context we are in matches any of the contexts we are
20467330f729Sjoerg     // interested in, we'll add this result.
20477330f729Sjoerg     if ((C->ShowInContexts & InContexts) == 0)
20487330f729Sjoerg       continue;
20497330f729Sjoerg 
20507330f729Sjoerg     // If we haven't added any results previously, do so now.
20517330f729Sjoerg     if (!AddedResult) {
20527330f729Sjoerg       CalculateHiddenNames(Context, Results, NumResults, S.Context,
20537330f729Sjoerg                            HiddenNames);
20547330f729Sjoerg       AllResults.insert(AllResults.end(), Results, Results + NumResults);
20557330f729Sjoerg       AddedResult = true;
20567330f729Sjoerg     }
20577330f729Sjoerg 
20587330f729Sjoerg     // Determine whether this global completion result is hidden by a local
20597330f729Sjoerg     // completion result. If so, skip it.
20607330f729Sjoerg     if (C->Kind != CXCursor_MacroDefinition &&
20617330f729Sjoerg         HiddenNames.count(C->Completion->getTypedText()))
20627330f729Sjoerg       continue;
20637330f729Sjoerg 
20647330f729Sjoerg     // Adjust priority based on similar type classes.
20657330f729Sjoerg     unsigned Priority = C->Priority;
20667330f729Sjoerg     CodeCompletionString *Completion = C->Completion;
20677330f729Sjoerg     if (!Context.getPreferredType().isNull()) {
20687330f729Sjoerg       if (C->Kind == CXCursor_MacroDefinition) {
20697330f729Sjoerg         Priority = getMacroUsagePriority(C->Completion->getTypedText(),
20707330f729Sjoerg                                          S.getLangOpts(),
20717330f729Sjoerg                                Context.getPreferredType()->isAnyPointerType());
20727330f729Sjoerg       } else if (C->Type) {
20737330f729Sjoerg         CanQualType Expected
20747330f729Sjoerg           = S.Context.getCanonicalType(
20757330f729Sjoerg                                Context.getPreferredType().getUnqualifiedType());
20767330f729Sjoerg         SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected);
20777330f729Sjoerg         if (ExpectedSTC == C->TypeClass) {
20787330f729Sjoerg           // We know this type is similar; check for an exact match.
20797330f729Sjoerg           llvm::StringMap<unsigned> &CachedCompletionTypes
20807330f729Sjoerg             = AST.getCachedCompletionTypes();
20817330f729Sjoerg           llvm::StringMap<unsigned>::iterator Pos
20827330f729Sjoerg             = CachedCompletionTypes.find(QualType(Expected).getAsString());
20837330f729Sjoerg           if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
20847330f729Sjoerg             Priority /= CCF_ExactTypeMatch;
20857330f729Sjoerg           else
20867330f729Sjoerg             Priority /= CCF_SimilarTypeMatch;
20877330f729Sjoerg         }
20887330f729Sjoerg       }
20897330f729Sjoerg     }
20907330f729Sjoerg 
20917330f729Sjoerg     // Adjust the completion string, if required.
20927330f729Sjoerg     if (C->Kind == CXCursor_MacroDefinition &&
20937330f729Sjoerg         Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
20947330f729Sjoerg       // Create a new code-completion string that just contains the
20957330f729Sjoerg       // macro name, without its arguments.
20967330f729Sjoerg       CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
20977330f729Sjoerg                                     CCP_CodePattern, C->Availability);
20987330f729Sjoerg       Builder.AddTypedTextChunk(C->Completion->getTypedText());
20997330f729Sjoerg       Priority = CCP_CodePattern;
21007330f729Sjoerg       Completion = Builder.TakeString();
21017330f729Sjoerg     }
21027330f729Sjoerg 
21037330f729Sjoerg     AllResults.push_back(Result(Completion, Priority, C->Kind,
21047330f729Sjoerg                                 C->Availability));
21057330f729Sjoerg   }
21067330f729Sjoerg 
21077330f729Sjoerg   // If we did not add any cached completion results, just forward the
21087330f729Sjoerg   // results we were given to the next consumer.
21097330f729Sjoerg   if (!AddedResult) {
21107330f729Sjoerg     Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
21117330f729Sjoerg     return;
21127330f729Sjoerg   }
21137330f729Sjoerg 
21147330f729Sjoerg   Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
21157330f729Sjoerg                                   AllResults.size());
21167330f729Sjoerg }
21177330f729Sjoerg 
CodeComplete(StringRef File,unsigned Line,unsigned Column,ArrayRef<RemappedFile> RemappedFiles,bool IncludeMacros,bool IncludeCodePatterns,bool IncludeBriefComments,CodeCompleteConsumer & Consumer,std::shared_ptr<PCHContainerOperations> PCHContainerOps,DiagnosticsEngine & Diag,LangOptions & LangOpts,SourceManager & SourceMgr,FileManager & FileMgr,SmallVectorImpl<StoredDiagnostic> & StoredDiagnostics,SmallVectorImpl<const llvm::MemoryBuffer * > & OwnedBuffers)21187330f729Sjoerg void ASTUnit::CodeComplete(
21197330f729Sjoerg     StringRef File, unsigned Line, unsigned Column,
21207330f729Sjoerg     ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
21217330f729Sjoerg     bool IncludeCodePatterns, bool IncludeBriefComments,
21227330f729Sjoerg     CodeCompleteConsumer &Consumer,
21237330f729Sjoerg     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
21247330f729Sjoerg     DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr,
21257330f729Sjoerg     FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
21267330f729Sjoerg     SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
21277330f729Sjoerg   if (!Invocation)
21287330f729Sjoerg     return;
21297330f729Sjoerg 
21307330f729Sjoerg   SimpleTimer CompletionTimer(WantTiming);
21317330f729Sjoerg   CompletionTimer.setOutput("Code completion @ " + File + ":" +
21327330f729Sjoerg                             Twine(Line) + ":" + Twine(Column));
21337330f729Sjoerg 
21347330f729Sjoerg   auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
21357330f729Sjoerg 
21367330f729Sjoerg   FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
21377330f729Sjoerg   CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
21387330f729Sjoerg   PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
21397330f729Sjoerg 
21407330f729Sjoerg   CodeCompleteOpts.IncludeMacros = IncludeMacros &&
21417330f729Sjoerg                                    CachedCompletionResults.empty();
21427330f729Sjoerg   CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
21437330f729Sjoerg   CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
21447330f729Sjoerg   CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
21457330f729Sjoerg   CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
21467330f729Sjoerg   CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
21477330f729Sjoerg 
21487330f729Sjoerg   assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
21497330f729Sjoerg 
2150*e038c9c4Sjoerg   FrontendOpts.CodeCompletionAt.FileName = std::string(File);
21517330f729Sjoerg   FrontendOpts.CodeCompletionAt.Line = Line;
21527330f729Sjoerg   FrontendOpts.CodeCompletionAt.Column = Column;
21537330f729Sjoerg 
21547330f729Sjoerg   // Set the language options appropriately.
21557330f729Sjoerg   LangOpts = *CCInvocation->getLangOpts();
21567330f729Sjoerg 
21577330f729Sjoerg   // Spell-checking and warnings are wasteful during code-completion.
21587330f729Sjoerg   LangOpts.SpellChecking = false;
21597330f729Sjoerg   CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
21607330f729Sjoerg 
21617330f729Sjoerg   std::unique_ptr<CompilerInstance> Clang(
21627330f729Sjoerg       new CompilerInstance(PCHContainerOps));
21637330f729Sjoerg 
21647330f729Sjoerg   // Recover resources if we crash before exiting this method.
21657330f729Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
21667330f729Sjoerg     CICleanup(Clang.get());
21677330f729Sjoerg 
21687330f729Sjoerg   auto &Inv = *CCInvocation;
21697330f729Sjoerg   Clang->setInvocation(std::move(CCInvocation));
2170*e038c9c4Sjoerg   OriginalSourceFile =
2171*e038c9c4Sjoerg       std::string(Clang->getFrontendOpts().Inputs[0].getFile());
21727330f729Sjoerg 
21737330f729Sjoerg   // Set up diagnostics, capturing any diagnostics produced.
21747330f729Sjoerg   Clang->setDiagnostics(&Diag);
21757330f729Sjoerg   CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
21767330f729Sjoerg                                     Clang->getDiagnostics(),
21777330f729Sjoerg                                     &StoredDiagnostics, nullptr);
21787330f729Sjoerg   ProcessWarningOptions(Diag, Inv.getDiagnosticOpts());
21797330f729Sjoerg 
21807330f729Sjoerg   // Create the target instance.
2181*e038c9c4Sjoerg   if (!Clang->createTarget()) {
21827330f729Sjoerg     Clang->setInvocation(nullptr);
21837330f729Sjoerg     return;
21847330f729Sjoerg   }
21857330f729Sjoerg 
21867330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
21877330f729Sjoerg          "Invocation must have exactly one source file!");
21887330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
21897330f729Sjoerg              InputKind::Source &&
21907330f729Sjoerg          "FIXME: AST inputs not yet supported here!");
21917330f729Sjoerg   assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
21927330f729Sjoerg              Language::LLVM_IR &&
21937330f729Sjoerg          "IR inputs not support here!");
21947330f729Sjoerg 
21957330f729Sjoerg   // Use the source and file managers that we were given.
21967330f729Sjoerg   Clang->setFileManager(&FileMgr);
21977330f729Sjoerg   Clang->setSourceManager(&SourceMgr);
21987330f729Sjoerg 
21997330f729Sjoerg   // Remap files.
22007330f729Sjoerg   PreprocessorOpts.clearRemappedFiles();
22017330f729Sjoerg   PreprocessorOpts.RetainRemappedFileBuffers = true;
22027330f729Sjoerg   for (const auto &RemappedFile : RemappedFiles) {
22037330f729Sjoerg     PreprocessorOpts.addRemappedFile(RemappedFile.first, RemappedFile.second);
22047330f729Sjoerg     OwnedBuffers.push_back(RemappedFile.second);
22057330f729Sjoerg   }
22067330f729Sjoerg 
22077330f729Sjoerg   // Use the code completion consumer we were given, but adding any cached
22087330f729Sjoerg   // code-completion results.
22097330f729Sjoerg   AugmentedCodeCompleteConsumer *AugmentedConsumer
22107330f729Sjoerg     = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
22117330f729Sjoerg   Clang->setCodeCompletionConsumer(AugmentedConsumer);
22127330f729Sjoerg 
2213*e038c9c4Sjoerg   auto getUniqueID =
2214*e038c9c4Sjoerg       [&FileMgr](StringRef Filename) -> Optional<llvm::sys::fs::UniqueID> {
2215*e038c9c4Sjoerg     if (auto Status = FileMgr.getVirtualFileSystem().status(Filename))
2216*e038c9c4Sjoerg       return Status->getUniqueID();
2217*e038c9c4Sjoerg     return None;
2218*e038c9c4Sjoerg   };
2219*e038c9c4Sjoerg 
2220*e038c9c4Sjoerg   auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2221*e038c9c4Sjoerg     if (LHS == RHS)
2222*e038c9c4Sjoerg       return true;
2223*e038c9c4Sjoerg     if (auto LHSID = getUniqueID(LHS))
2224*e038c9c4Sjoerg       if (auto RHSID = getUniqueID(RHS))
2225*e038c9c4Sjoerg         return *LHSID == *RHSID;
2226*e038c9c4Sjoerg     return false;
2227*e038c9c4Sjoerg   };
2228*e038c9c4Sjoerg 
22297330f729Sjoerg   // If we have a precompiled preamble, try to use it. We only allow
22307330f729Sjoerg   // the use of the precompiled preamble if we're if the completion
22317330f729Sjoerg   // point is within the main file, after the end of the precompiled
22327330f729Sjoerg   // preamble.
22337330f729Sjoerg   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2234*e038c9c4Sjoerg   if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
22357330f729Sjoerg     OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2236*e038c9c4Sjoerg         PCHContainerOps, Inv, &FileMgr.getVirtualFileSystem(), false, Line - 1);
22377330f729Sjoerg   }
22387330f729Sjoerg 
22397330f729Sjoerg   // If the main file has been overridden due to the use of a preamble,
22407330f729Sjoerg   // make that override happen and introduce the preamble.
22417330f729Sjoerg   if (OverrideMainBuffer) {
22427330f729Sjoerg     assert(Preamble &&
22437330f729Sjoerg            "No preamble was built, but OverrideMainBuffer is not null");
22447330f729Sjoerg 
22457330f729Sjoerg     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
22467330f729Sjoerg         &FileMgr.getVirtualFileSystem();
22477330f729Sjoerg     Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
22487330f729Sjoerg                                   OverrideMainBuffer.get());
22497330f729Sjoerg     // FIXME: there is no way to update VFS if it was changed by
22507330f729Sjoerg     // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
22517330f729Sjoerg     // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
22527330f729Sjoerg     // PCH files are always readable.
22537330f729Sjoerg     OwnedBuffers.push_back(OverrideMainBuffer.release());
22547330f729Sjoerg   } else {
22557330f729Sjoerg     PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
22567330f729Sjoerg     PreprocessorOpts.PrecompiledPreambleBytes.second = false;
22577330f729Sjoerg   }
22587330f729Sjoerg 
22597330f729Sjoerg   // Disable the preprocessing record if modules are not enabled.
22607330f729Sjoerg   if (!Clang->getLangOpts().Modules)
22617330f729Sjoerg     PreprocessorOpts.DetailedRecord = false;
22627330f729Sjoerg 
22637330f729Sjoerg   std::unique_ptr<SyntaxOnlyAction> Act;
22647330f729Sjoerg   Act.reset(new SyntaxOnlyAction);
22657330f729Sjoerg   if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
22667330f729Sjoerg     if (llvm::Error Err = Act->Execute()) {
22677330f729Sjoerg       consumeError(std::move(Err)); // FIXME this drops errors on the floor.
22687330f729Sjoerg     }
22697330f729Sjoerg     Act->EndSourceFile();
22707330f729Sjoerg   }
22717330f729Sjoerg }
22727330f729Sjoerg 
Save(StringRef File)22737330f729Sjoerg bool ASTUnit::Save(StringRef File) {
22747330f729Sjoerg   if (HadModuleLoaderFatalFailure)
22757330f729Sjoerg     return true;
22767330f729Sjoerg 
22777330f729Sjoerg   // Write to a temporary file and later rename it to the actual file, to avoid
22787330f729Sjoerg   // possible race conditions.
22797330f729Sjoerg   SmallString<128> TempPath;
22807330f729Sjoerg   TempPath = File;
22817330f729Sjoerg   TempPath += "-%%%%%%%%";
22827330f729Sjoerg   // FIXME: Can we somehow regenerate the stat cache here, or do we need to
22837330f729Sjoerg   // unconditionally create a stat cache when we parse the file?
22847330f729Sjoerg 
22857330f729Sjoerg   if (llvm::Error Err = llvm::writeFileAtomically(
22867330f729Sjoerg           TempPath, File, [this](llvm::raw_ostream &Out) {
22877330f729Sjoerg             return serialize(Out) ? llvm::make_error<llvm::StringError>(
22887330f729Sjoerg                                         "ASTUnit serialization failed",
22897330f729Sjoerg                                         llvm::inconvertibleErrorCode())
22907330f729Sjoerg                                   : llvm::Error::success();
22917330f729Sjoerg           })) {
22927330f729Sjoerg     consumeError(std::move(Err));
22937330f729Sjoerg     return true;
22947330f729Sjoerg   }
22957330f729Sjoerg   return false;
22967330f729Sjoerg }
22977330f729Sjoerg 
serializeUnit(ASTWriter & Writer,SmallVectorImpl<char> & Buffer,Sema & S,bool hasErrors,raw_ostream & OS)22987330f729Sjoerg static bool serializeUnit(ASTWriter &Writer,
22997330f729Sjoerg                           SmallVectorImpl<char> &Buffer,
23007330f729Sjoerg                           Sema &S,
23017330f729Sjoerg                           bool hasErrors,
23027330f729Sjoerg                           raw_ostream &OS) {
23037330f729Sjoerg   Writer.WriteAST(S, std::string(), nullptr, "", hasErrors);
23047330f729Sjoerg 
23057330f729Sjoerg   // Write the generated bitstream to "Out".
23067330f729Sjoerg   if (!Buffer.empty())
23077330f729Sjoerg     OS.write(Buffer.data(), Buffer.size());
23087330f729Sjoerg 
23097330f729Sjoerg   return false;
23107330f729Sjoerg }
23117330f729Sjoerg 
serialize(raw_ostream & OS)23127330f729Sjoerg bool ASTUnit::serialize(raw_ostream &OS) {
23137330f729Sjoerg   // For serialization we are lenient if the errors were only warn-as-error kind.
23147330f729Sjoerg   bool hasErrors = getDiagnostics().hasUncompilableErrorOccurred();
23157330f729Sjoerg 
23167330f729Sjoerg   if (WriterData)
23177330f729Sjoerg     return serializeUnit(WriterData->Writer, WriterData->Buffer,
23187330f729Sjoerg                          getSema(), hasErrors, OS);
23197330f729Sjoerg 
23207330f729Sjoerg   SmallString<128> Buffer;
23217330f729Sjoerg   llvm::BitstreamWriter Stream(Buffer);
23227330f729Sjoerg   InMemoryModuleCache ModuleCache;
23237330f729Sjoerg   ASTWriter Writer(Stream, Buffer, ModuleCache, {});
23247330f729Sjoerg   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
23257330f729Sjoerg }
23267330f729Sjoerg 
23277330f729Sjoerg using SLocRemap = ContinuousRangeMap<unsigned, int, 2>;
23287330f729Sjoerg 
TranslateStoredDiagnostics(FileManager & FileMgr,SourceManager & SrcMgr,const SmallVectorImpl<StandaloneDiagnostic> & Diags,SmallVectorImpl<StoredDiagnostic> & Out)23297330f729Sjoerg void ASTUnit::TranslateStoredDiagnostics(
23307330f729Sjoerg                           FileManager &FileMgr,
23317330f729Sjoerg                           SourceManager &SrcMgr,
23327330f729Sjoerg                           const SmallVectorImpl<StandaloneDiagnostic> &Diags,
23337330f729Sjoerg                           SmallVectorImpl<StoredDiagnostic> &Out) {
23347330f729Sjoerg   // Map the standalone diagnostic into the new source manager. We also need to
23357330f729Sjoerg   // remap all the locations to the new view. This includes the diag location,
23367330f729Sjoerg   // any associated source ranges, and the source ranges of associated fix-its.
23377330f729Sjoerg   // FIXME: There should be a cleaner way to do this.
23387330f729Sjoerg   SmallVector<StoredDiagnostic, 4> Result;
23397330f729Sjoerg   Result.reserve(Diags.size());
23407330f729Sjoerg 
23417330f729Sjoerg   for (const auto &SD : Diags) {
23427330f729Sjoerg     // Rebuild the StoredDiagnostic.
23437330f729Sjoerg     if (SD.Filename.empty())
23447330f729Sjoerg       continue;
23457330f729Sjoerg     auto FE = FileMgr.getFile(SD.Filename);
23467330f729Sjoerg     if (!FE)
23477330f729Sjoerg       continue;
23487330f729Sjoerg     SourceLocation FileLoc;
23497330f729Sjoerg     auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
23507330f729Sjoerg     if (ItFileID == PreambleSrcLocCache.end()) {
23517330f729Sjoerg       FileID FID = SrcMgr.translateFile(*FE);
23527330f729Sjoerg       FileLoc = SrcMgr.getLocForStartOfFile(FID);
23537330f729Sjoerg       PreambleSrcLocCache[SD.Filename] = FileLoc;
23547330f729Sjoerg     } else {
23557330f729Sjoerg       FileLoc = ItFileID->getValue();
23567330f729Sjoerg     }
23577330f729Sjoerg 
23587330f729Sjoerg     if (FileLoc.isInvalid())
23597330f729Sjoerg       continue;
23607330f729Sjoerg     SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
23617330f729Sjoerg     FullSourceLoc Loc(L, SrcMgr);
23627330f729Sjoerg 
23637330f729Sjoerg     SmallVector<CharSourceRange, 4> Ranges;
23647330f729Sjoerg     Ranges.reserve(SD.Ranges.size());
23657330f729Sjoerg     for (const auto &Range : SD.Ranges) {
23667330f729Sjoerg       SourceLocation BL = FileLoc.getLocWithOffset(Range.first);
23677330f729Sjoerg       SourceLocation EL = FileLoc.getLocWithOffset(Range.second);
23687330f729Sjoerg       Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
23697330f729Sjoerg     }
23707330f729Sjoerg 
23717330f729Sjoerg     SmallVector<FixItHint, 2> FixIts;
23727330f729Sjoerg     FixIts.reserve(SD.FixIts.size());
23737330f729Sjoerg     for (const auto &FixIt : SD.FixIts) {
23747330f729Sjoerg       FixIts.push_back(FixItHint());
23757330f729Sjoerg       FixItHint &FH = FixIts.back();
23767330f729Sjoerg       FH.CodeToInsert = FixIt.CodeToInsert;
23777330f729Sjoerg       SourceLocation BL = FileLoc.getLocWithOffset(FixIt.RemoveRange.first);
23787330f729Sjoerg       SourceLocation EL = FileLoc.getLocWithOffset(FixIt.RemoveRange.second);
23797330f729Sjoerg       FH.RemoveRange = CharSourceRange::getCharRange(BL, EL);
23807330f729Sjoerg     }
23817330f729Sjoerg 
23827330f729Sjoerg     Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
23837330f729Sjoerg                                       SD.Message, Loc, Ranges, FixIts));
23847330f729Sjoerg   }
23857330f729Sjoerg   Result.swap(Out);
23867330f729Sjoerg }
23877330f729Sjoerg 
addFileLevelDecl(Decl * D)23887330f729Sjoerg void ASTUnit::addFileLevelDecl(Decl *D) {
23897330f729Sjoerg   assert(D);
23907330f729Sjoerg 
23917330f729Sjoerg   // We only care about local declarations.
23927330f729Sjoerg   if (D->isFromASTFile())
23937330f729Sjoerg     return;
23947330f729Sjoerg 
23957330f729Sjoerg   SourceManager &SM = *SourceMgr;
23967330f729Sjoerg   SourceLocation Loc = D->getLocation();
23977330f729Sjoerg   if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
23987330f729Sjoerg     return;
23997330f729Sjoerg 
24007330f729Sjoerg   // We only keep track of the file-level declarations of each file.
24017330f729Sjoerg   if (!D->getLexicalDeclContext()->isFileContext())
24027330f729Sjoerg     return;
24037330f729Sjoerg 
24047330f729Sjoerg   SourceLocation FileLoc = SM.getFileLoc(Loc);
24057330f729Sjoerg   assert(SM.isLocalSourceLocation(FileLoc));
24067330f729Sjoerg   FileID FID;
24077330f729Sjoerg   unsigned Offset;
24087330f729Sjoerg   std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
24097330f729Sjoerg   if (FID.isInvalid())
24107330f729Sjoerg     return;
24117330f729Sjoerg 
2412*e038c9c4Sjoerg   std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
24137330f729Sjoerg   if (!Decls)
2414*e038c9c4Sjoerg     Decls = std::make_unique<LocDeclsTy>();
24157330f729Sjoerg 
24167330f729Sjoerg   std::pair<unsigned, Decl *> LocDecl(Offset, D);
24177330f729Sjoerg 
24187330f729Sjoerg   if (Decls->empty() || Decls->back().first <= Offset) {
24197330f729Sjoerg     Decls->push_back(LocDecl);
24207330f729Sjoerg     return;
24217330f729Sjoerg   }
24227330f729Sjoerg 
24237330f729Sjoerg   LocDeclsTy::iterator I =
24247330f729Sjoerg       llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
24257330f729Sjoerg 
24267330f729Sjoerg   Decls->insert(I, LocDecl);
24277330f729Sjoerg }
24287330f729Sjoerg 
findFileRegionDecls(FileID File,unsigned Offset,unsigned Length,SmallVectorImpl<Decl * > & Decls)24297330f729Sjoerg void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
24307330f729Sjoerg                                   SmallVectorImpl<Decl *> &Decls) {
24317330f729Sjoerg   if (File.isInvalid())
24327330f729Sjoerg     return;
24337330f729Sjoerg 
24347330f729Sjoerg   if (SourceMgr->isLoadedFileID(File)) {
24357330f729Sjoerg     assert(Ctx->getExternalSource() && "No external source!");
24367330f729Sjoerg     return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
24377330f729Sjoerg                                                          Decls);
24387330f729Sjoerg   }
24397330f729Sjoerg 
24407330f729Sjoerg   FileDeclsTy::iterator I = FileDecls.find(File);
24417330f729Sjoerg   if (I == FileDecls.end())
24427330f729Sjoerg     return;
24437330f729Sjoerg 
24447330f729Sjoerg   LocDeclsTy &LocDecls = *I->second;
24457330f729Sjoerg   if (LocDecls.empty())
24467330f729Sjoerg     return;
24477330f729Sjoerg 
24487330f729Sjoerg   LocDeclsTy::iterator BeginIt =
24497330f729Sjoerg       llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
24507330f729Sjoerg         return LD.first < Offset;
24517330f729Sjoerg       });
24527330f729Sjoerg   if (BeginIt != LocDecls.begin())
24537330f729Sjoerg     --BeginIt;
24547330f729Sjoerg 
24557330f729Sjoerg   // If we are pointing at a top-level decl inside an objc container, we need
24567330f729Sjoerg   // to backtrack until we find it otherwise we will fail to report that the
24577330f729Sjoerg   // region overlaps with an objc container.
24587330f729Sjoerg   while (BeginIt != LocDecls.begin() &&
24597330f729Sjoerg          BeginIt->second->isTopLevelDeclInObjCContainer())
24607330f729Sjoerg     --BeginIt;
24617330f729Sjoerg 
24627330f729Sjoerg   LocDeclsTy::iterator EndIt = llvm::upper_bound(
24637330f729Sjoerg       LocDecls, std::make_pair(Offset + Length, (Decl *)nullptr),
24647330f729Sjoerg       llvm::less_first());
24657330f729Sjoerg   if (EndIt != LocDecls.end())
24667330f729Sjoerg     ++EndIt;
24677330f729Sjoerg 
24687330f729Sjoerg   for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
24697330f729Sjoerg     Decls.push_back(DIt->second);
24707330f729Sjoerg }
24717330f729Sjoerg 
getLocation(const FileEntry * File,unsigned Line,unsigned Col) const24727330f729Sjoerg SourceLocation ASTUnit::getLocation(const FileEntry *File,
24737330f729Sjoerg                                     unsigned Line, unsigned Col) const {
24747330f729Sjoerg   const SourceManager &SM = getSourceManager();
24757330f729Sjoerg   SourceLocation Loc = SM.translateFileLineCol(File, Line, Col);
24767330f729Sjoerg   return SM.getMacroArgExpandedLocation(Loc);
24777330f729Sjoerg }
24787330f729Sjoerg 
getLocation(const FileEntry * File,unsigned Offset) const24797330f729Sjoerg SourceLocation ASTUnit::getLocation(const FileEntry *File,
24807330f729Sjoerg                                     unsigned Offset) const {
24817330f729Sjoerg   const SourceManager &SM = getSourceManager();
24827330f729Sjoerg   SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1);
24837330f729Sjoerg   return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
24847330f729Sjoerg }
24857330f729Sjoerg 
24867330f729Sjoerg /// If \arg Loc is a loaded location from the preamble, returns
24877330f729Sjoerg /// the corresponding local location of the main file, otherwise it returns
24887330f729Sjoerg /// \arg Loc.
mapLocationFromPreamble(SourceLocation Loc) const24897330f729Sjoerg SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {
24907330f729Sjoerg   FileID PreambleID;
24917330f729Sjoerg   if (SourceMgr)
24927330f729Sjoerg     PreambleID = SourceMgr->getPreambleFileID();
24937330f729Sjoerg 
24947330f729Sjoerg   if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
24957330f729Sjoerg     return Loc;
24967330f729Sjoerg 
24977330f729Sjoerg   unsigned Offs;
24987330f729Sjoerg   if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
24997330f729Sjoerg     SourceLocation FileLoc
25007330f729Sjoerg         = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
25017330f729Sjoerg     return FileLoc.getLocWithOffset(Offs);
25027330f729Sjoerg   }
25037330f729Sjoerg 
25047330f729Sjoerg   return Loc;
25057330f729Sjoerg }
25067330f729Sjoerg 
25077330f729Sjoerg /// If \arg Loc is a local location of the main file but inside the
25087330f729Sjoerg /// preamble chunk, returns the corresponding loaded location from the
25097330f729Sjoerg /// preamble, otherwise it returns \arg Loc.
mapLocationToPreamble(SourceLocation Loc) const25107330f729Sjoerg SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) const {
25117330f729Sjoerg   FileID PreambleID;
25127330f729Sjoerg   if (SourceMgr)
25137330f729Sjoerg     PreambleID = SourceMgr->getPreambleFileID();
25147330f729Sjoerg 
25157330f729Sjoerg   if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
25167330f729Sjoerg     return Loc;
25177330f729Sjoerg 
25187330f729Sjoerg   unsigned Offs;
25197330f729Sjoerg   if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
25207330f729Sjoerg       Offs < Preamble->getBounds().Size) {
25217330f729Sjoerg     SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
25227330f729Sjoerg     return FileLoc.getLocWithOffset(Offs);
25237330f729Sjoerg   }
25247330f729Sjoerg 
25257330f729Sjoerg   return Loc;
25267330f729Sjoerg }
25277330f729Sjoerg 
isInPreambleFileID(SourceLocation Loc) const25287330f729Sjoerg bool ASTUnit::isInPreambleFileID(SourceLocation Loc) const {
25297330f729Sjoerg   FileID FID;
25307330f729Sjoerg   if (SourceMgr)
25317330f729Sjoerg     FID = SourceMgr->getPreambleFileID();
25327330f729Sjoerg 
25337330f729Sjoerg   if (Loc.isInvalid() || FID.isInvalid())
25347330f729Sjoerg     return false;
25357330f729Sjoerg 
25367330f729Sjoerg   return SourceMgr->isInFileID(Loc, FID);
25377330f729Sjoerg }
25387330f729Sjoerg 
isInMainFileID(SourceLocation Loc) const25397330f729Sjoerg bool ASTUnit::isInMainFileID(SourceLocation Loc) const {
25407330f729Sjoerg   FileID FID;
25417330f729Sjoerg   if (SourceMgr)
25427330f729Sjoerg     FID = SourceMgr->getMainFileID();
25437330f729Sjoerg 
25447330f729Sjoerg   if (Loc.isInvalid() || FID.isInvalid())
25457330f729Sjoerg     return false;
25467330f729Sjoerg 
25477330f729Sjoerg   return SourceMgr->isInFileID(Loc, FID);
25487330f729Sjoerg }
25497330f729Sjoerg 
getEndOfPreambleFileID() const25507330f729Sjoerg SourceLocation ASTUnit::getEndOfPreambleFileID() const {
25517330f729Sjoerg   FileID FID;
25527330f729Sjoerg   if (SourceMgr)
25537330f729Sjoerg     FID = SourceMgr->getPreambleFileID();
25547330f729Sjoerg 
25557330f729Sjoerg   if (FID.isInvalid())
25567330f729Sjoerg     return {};
25577330f729Sjoerg 
25587330f729Sjoerg   return SourceMgr->getLocForEndOfFile(FID);
25597330f729Sjoerg }
25607330f729Sjoerg 
getStartOfMainFileID() const25617330f729Sjoerg SourceLocation ASTUnit::getStartOfMainFileID() const {
25627330f729Sjoerg   FileID FID;
25637330f729Sjoerg   if (SourceMgr)
25647330f729Sjoerg     FID = SourceMgr->getMainFileID();
25657330f729Sjoerg 
25667330f729Sjoerg   if (FID.isInvalid())
25677330f729Sjoerg     return {};
25687330f729Sjoerg 
25697330f729Sjoerg   return SourceMgr->getLocForStartOfFile(FID);
25707330f729Sjoerg }
25717330f729Sjoerg 
25727330f729Sjoerg llvm::iterator_range<PreprocessingRecord::iterator>
getLocalPreprocessingEntities() const25737330f729Sjoerg ASTUnit::getLocalPreprocessingEntities() const {
25747330f729Sjoerg   if (isMainFileAST()) {
25757330f729Sjoerg     serialization::ModuleFile &
25767330f729Sjoerg       Mod = Reader->getModuleManager().getPrimaryModule();
25777330f729Sjoerg     return Reader->getModulePreprocessedEntities(Mod);
25787330f729Sjoerg   }
25797330f729Sjoerg 
25807330f729Sjoerg   if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())
25817330f729Sjoerg     return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
25827330f729Sjoerg 
25837330f729Sjoerg   return llvm::make_range(PreprocessingRecord::iterator(),
25847330f729Sjoerg                           PreprocessingRecord::iterator());
25857330f729Sjoerg }
25867330f729Sjoerg 
visitLocalTopLevelDecls(void * context,DeclVisitorFn Fn)25877330f729Sjoerg bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {
25887330f729Sjoerg   if (isMainFileAST()) {
25897330f729Sjoerg     serialization::ModuleFile &
25907330f729Sjoerg       Mod = Reader->getModuleManager().getPrimaryModule();
25917330f729Sjoerg     for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
25927330f729Sjoerg       if (!Fn(context, D))
25937330f729Sjoerg         return false;
25947330f729Sjoerg     }
25957330f729Sjoerg 
25967330f729Sjoerg     return true;
25977330f729Sjoerg   }
25987330f729Sjoerg 
25997330f729Sjoerg   for (ASTUnit::top_level_iterator TL = top_level_begin(),
26007330f729Sjoerg                                 TLEnd = top_level_end();
26017330f729Sjoerg          TL != TLEnd; ++TL) {
26027330f729Sjoerg     if (!Fn(context, *TL))
26037330f729Sjoerg       return false;
26047330f729Sjoerg   }
26057330f729Sjoerg 
26067330f729Sjoerg   return true;
26077330f729Sjoerg }
26087330f729Sjoerg 
getPCHFile()26097330f729Sjoerg const FileEntry *ASTUnit::getPCHFile() {
26107330f729Sjoerg   if (!Reader)
26117330f729Sjoerg     return nullptr;
26127330f729Sjoerg 
26137330f729Sjoerg   serialization::ModuleFile *Mod = nullptr;
26147330f729Sjoerg   Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
26157330f729Sjoerg     switch (M.Kind) {
26167330f729Sjoerg     case serialization::MK_ImplicitModule:
26177330f729Sjoerg     case serialization::MK_ExplicitModule:
26187330f729Sjoerg     case serialization::MK_PrebuiltModule:
26197330f729Sjoerg       return true; // skip dependencies.
26207330f729Sjoerg     case serialization::MK_PCH:
26217330f729Sjoerg       Mod = &M;
26227330f729Sjoerg       return true; // found it.
26237330f729Sjoerg     case serialization::MK_Preamble:
26247330f729Sjoerg       return false; // look in dependencies.
26257330f729Sjoerg     case serialization::MK_MainFile:
26267330f729Sjoerg       return false; // look in dependencies.
26277330f729Sjoerg     }
26287330f729Sjoerg 
26297330f729Sjoerg     return true;
26307330f729Sjoerg   });
26317330f729Sjoerg   if (Mod)
26327330f729Sjoerg     return Mod->File;
26337330f729Sjoerg 
26347330f729Sjoerg   return nullptr;
26357330f729Sjoerg }
26367330f729Sjoerg 
isModuleFile() const26377330f729Sjoerg bool ASTUnit::isModuleFile() const {
26387330f729Sjoerg   return isMainFileAST() && getLangOpts().isCompilingModule();
26397330f729Sjoerg }
26407330f729Sjoerg 
getInputKind() const26417330f729Sjoerg InputKind ASTUnit::getInputKind() const {
26427330f729Sjoerg   auto &LangOpts = getLangOpts();
26437330f729Sjoerg 
26447330f729Sjoerg   Language Lang;
26457330f729Sjoerg   if (LangOpts.OpenCL)
26467330f729Sjoerg     Lang = Language::OpenCL;
26477330f729Sjoerg   else if (LangOpts.CUDA)
26487330f729Sjoerg     Lang = Language::CUDA;
26497330f729Sjoerg   else if (LangOpts.RenderScript)
26507330f729Sjoerg     Lang = Language::RenderScript;
26517330f729Sjoerg   else if (LangOpts.CPlusPlus)
26527330f729Sjoerg     Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
26537330f729Sjoerg   else
26547330f729Sjoerg     Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
26557330f729Sjoerg 
26567330f729Sjoerg   InputKind::Format Fmt = InputKind::Source;
26577330f729Sjoerg   if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
26587330f729Sjoerg     Fmt = InputKind::ModuleMap;
26597330f729Sjoerg 
26607330f729Sjoerg   // We don't know if input was preprocessed. Assume not.
26617330f729Sjoerg   bool PP = false;
26627330f729Sjoerg 
26637330f729Sjoerg   return InputKind(Lang, Fmt, PP);
26647330f729Sjoerg }
26657330f729Sjoerg 
26667330f729Sjoerg #ifndef NDEBUG
ConcurrencyState()26677330f729Sjoerg ASTUnit::ConcurrencyState::ConcurrencyState() {
26687330f729Sjoerg   Mutex = new std::recursive_mutex;
26697330f729Sjoerg }
26707330f729Sjoerg 
~ConcurrencyState()26717330f729Sjoerg ASTUnit::ConcurrencyState::~ConcurrencyState() {
26727330f729Sjoerg   delete static_cast<std::recursive_mutex *>(Mutex);
26737330f729Sjoerg }
26747330f729Sjoerg 
start()26757330f729Sjoerg void ASTUnit::ConcurrencyState::start() {
26767330f729Sjoerg   bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
26777330f729Sjoerg   assert(acquired && "Concurrent access to ASTUnit!");
26787330f729Sjoerg }
26797330f729Sjoerg 
finish()26807330f729Sjoerg void ASTUnit::ConcurrencyState::finish() {
26817330f729Sjoerg   static_cast<std::recursive_mutex *>(Mutex)->unlock();
26827330f729Sjoerg }
26837330f729Sjoerg 
26847330f729Sjoerg #else // NDEBUG
26857330f729Sjoerg 
ConcurrencyState()26867330f729Sjoerg ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
~ConcurrencyState()26877330f729Sjoerg ASTUnit::ConcurrencyState::~ConcurrencyState() {}
start()26887330f729Sjoerg void ASTUnit::ConcurrencyState::start() {}
finish()26897330f729Sjoerg void ASTUnit::ConcurrencyState::finish() {}
26907330f729Sjoerg 
26917330f729Sjoerg #endif // NDEBUG
2692