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