diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp | 988 |
1 files changed, 460 insertions, 528 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp index a8c5876..fc44d9f 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Basic/VirtualFileSystem.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -35,9 +36,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" -#include "llvm/Support/Atomic.h" #include "llvm/Support/CrashRecoveryContext.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" @@ -45,9 +44,9 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" +#include <atomic> #include <cstdio> #include <cstdlib> -#include <sys/stat.h> using namespace clang; using llvm::TimeRecord; @@ -191,10 +190,7 @@ struct ASTUnit::ASTWriterData { }; void ASTUnit::clearFileLevelDecls() { - for (FileDeclsTy::iterator - I = FileDecls.begin(), E = FileDecls.end(); I != E; ++I) - delete I->second; - FileDecls.clear(); + llvm::DeleteContainerSeconds(FileDecls); } void ASTUnit::CleanTemporaryFiles() { @@ -214,27 +210,25 @@ const unsigned DefaultPreambleRebuildInterval = 5; /// \brief Tracks the number of ASTUnit objects that are currently active. /// /// Used for debugging purposes only. -static llvm::sys::cas_flag ActiveASTUnitObjects; +static std::atomic<unsigned> ActiveASTUnitObjects; ASTUnit::ASTUnit(bool _MainFileIsAST) - : Reader(0), HadModuleLoaderFatalFailure(false), + : Reader(nullptr), HadModuleLoaderFatalFailure(false), OnlyLocalDecls(false), CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), OwnsRemappedFileBuffers(true), NumStoredDiagnosticsFromDriver(0), - PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), - NumWarningsInPreamble(0), + PreambleRebuildCounter(0), SavedMainFileBuffer(nullptr), + PreambleBuffer(nullptr), NumWarningsInPreamble(0), ShouldCacheCodeCompletionResults(false), IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false), CompletionCacheTopLevelHashValue(0), PreambleTopLevelHashValue(0), CurrentTopLevelHashValue(0), UnsafeToFree(false) { - if (getenv("LIBCLANG_OBJTRACKING")) { - llvm::sys::AtomicIncrement(&ActiveASTUnitObjects); - fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects); - } + if (getenv("LIBCLANG_OBJTRACKING")) + fprintf(stderr, "+++ %u translation units\n", ++ActiveASTUnitObjects); } ASTUnit::~ASTUnit() { @@ -252,14 +246,10 @@ ASTUnit::~ASTUnit() { // perform this operation here because we explicitly request that the // compiler instance *not* free these buffers for each invocation of the // parser. - if (Invocation.getPtr() && OwnsRemappedFileBuffers) { + if (Invocation.get() && OwnsRemappedFileBuffers) { PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); - for (PreprocessorOptions::remapped_file_buffer_iterator - FB = PPOpts.remapped_file_buffer_begin(), - FBEnd = PPOpts.remapped_file_buffer_end(); - FB != FBEnd; - ++FB) - delete FB->second; + for (const auto &RB : PPOpts.RemappedFileBuffers) + delete RB.second; } delete SavedMainFileBuffer; @@ -267,10 +257,8 @@ ASTUnit::~ASTUnit() { ClearCachedCompletionResults(); - if (getenv("LIBCLANG_OBJTRACKING")) { - llvm::sys::AtomicDecrement(&ActiveASTUnitObjects); - fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects); - } + if (getenv("LIBCLANG_OBJTRACKING")) + fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects); } void ASTUnit::setPreprocessor(Preprocessor *pp) { PP = pp; } @@ -500,7 +488,7 @@ void ASTUnit::CacheCodeCompletionResults() { void ASTUnit::ClearCachedCompletionResults() { CachedCompletionResults.clear(); CachedCompletionTypes.clear(); - CachedCompletionAllocator = 0; + CachedCompletionAllocator = nullptr; } namespace { @@ -511,23 +499,20 @@ class ASTInfoCollector : public ASTReaderListener { Preprocessor &PP; ASTContext &Context; LangOptions &LangOpt; - IntrusiveRefCntPtr<TargetOptions> &TargetOpts; + std::shared_ptr<TargetOptions> &TargetOpts; IntrusiveRefCntPtr<TargetInfo> &Target; unsigned &Counter; bool InitializedLanguage; public: - ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, - IntrusiveRefCntPtr<TargetOptions> &TargetOpts, - IntrusiveRefCntPtr<TargetInfo> &Target, - unsigned &Counter) - : PP(PP), Context(Context), LangOpt(LangOpt), - TargetOpts(TargetOpts), Target(Target), - Counter(Counter), - InitializedLanguage(false) {} - - virtual bool ReadLanguageOptions(const LangOptions &LangOpts, - bool Complain) { + ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, + std::shared_ptr<TargetOptions> &TargetOpts, + IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter) + : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts), + Target(Target), Counter(Counter), InitializedLanguage(false) {} + + bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain) override { if (InitializedLanguage) return false; @@ -538,21 +523,22 @@ public: return false; } - virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) { + bool ReadTargetOptions(const TargetOptions &TargetOpts, + bool Complain) override { // If we've already initialized the target, don't do it again. if (Target) return false; - - this->TargetOpts = new TargetOptions(TargetOpts); - Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), - &*this->TargetOpts); + + this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts); + Target = + TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts); updated(); return false; } - virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value) { + void ReadCounter(const serialization::ModuleFile &M, + unsigned Value) override { Counter = Value; } @@ -565,7 +551,7 @@ private: // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. - Target->setForcedLangOptions(LangOpt); + Target->adjust(LangOpt); // Initialize the preprocessor. PP.Initialize(*Target); @@ -588,16 +574,16 @@ class StoredDiagnosticConsumer : public DiagnosticConsumer { public: explicit StoredDiagnosticConsumer( SmallVectorImpl<StoredDiagnostic> &StoredDiags) - : StoredDiags(StoredDiags), SourceMgr(0) { } + : StoredDiags(StoredDiags), SourceMgr(nullptr) {} - virtual void BeginSourceFile(const LangOptions &LangOpts, - const Preprocessor *PP = 0) { + void BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP = nullptr) override { if (PP) SourceMgr = &PP->getSourceManager(); } - virtual void HandleDiagnostic(DiagnosticsEngine::Level Level, - const Diagnostic &Info); + void HandleDiagnostic(DiagnosticsEngine::Level Level, + const Diagnostic &Info) override; }; /// \brief RAII object that optionally captures diagnostics, if @@ -610,9 +596,9 @@ class CaptureDroppedDiagnostics { public: CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags, SmallVectorImpl<StoredDiagnostic> &StoredDiags) - : Diags(Diags), Client(StoredDiags), PreviousClient(0) + : Diags(Diags), Client(StoredDiags), PreviousClient(nullptr) { - if (RequestCapture || Diags.getClient() == 0) { + if (RequestCapture || Diags.getClient() == nullptr) { PreviousClient = Diags.takeClient(); Diags.setClient(&Client); } @@ -643,13 +629,13 @@ void StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level, ASTMutationListener *ASTUnit::getASTMutationListener() { if (WriterData) return &WriterData->Writer; - return 0; + return nullptr; } ASTDeserializationListener *ASTUnit::getDeserializationListener() { if (WriterData) return &WriterData->Writer; - return 0; + return nullptr; } llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, @@ -662,10 +648,10 @@ llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, const char **ArgBegin, const char **ArgEnd, ASTUnit &AST, bool CaptureDiagnostics) { - if (!Diags.getPtr()) { + if (!Diags.get()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. - DiagnosticConsumer *Client = 0; + DiagnosticConsumer *Client = nullptr; if (CaptureDiagnostics) Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(), @@ -680,129 +666,74 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, - RemappedFile *RemappedFiles, - unsigned NumRemappedFiles, + ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics, bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) { - OwningPtr<ASTUnit> AST(new ASTUnit(true)); + std::unique_ptr<ASTUnit> AST(new ASTUnit(true)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get()); llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > - DiagCleanup(Diags.getPtr()); + DiagCleanup(Diags.get()); - ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); + ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->Diagnostics = Diags; - AST->FileMgr = new FileManager(FileSystemOpts); + IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem(); + AST->FileMgr = new FileManager(FileSystemOpts, VFS); AST->UserFilesAreVolatile = UserFilesAreVolatile; AST->SourceMgr = new SourceManager(AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile); AST->HSOpts = new HeaderSearchOptions(); - + AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts, AST->getSourceManager(), AST->getDiagnostics(), AST->ASTFileLangOpts, - /*Target=*/0)); - - for (unsigned I = 0; I != NumRemappedFiles; ++I) { - FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; - if (const llvm::MemoryBuffer * - memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { - // Create the file entry for the file that we're mapping from. - const FileEntry *FromFile - = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, - memBuf->getBufferSize(), - 0); - if (!FromFile) { - AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) - << RemappedFiles[I].first; - delete memBuf; - continue; - } - - // Override the contents of the "from" file with the contents of - // the "to" file. - AST->getSourceManager().overrideFileContents(FromFile, memBuf); + /*Target=*/nullptr)); - } else { - const char *fname = fileOrBuf.get<const char *>(); - const FileEntry *ToFile = AST->FileMgr->getFile(fname); - if (!ToFile) { - AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file) - << RemappedFiles[I].first << fname; - continue; - } + PreprocessorOptions *PPOpts = new PreprocessorOptions(); + + for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) + PPOpts->addRemappedFile(RemappedFiles[I].first, RemappedFiles[I].second); - // Create the file entry for the file that we're mapping from. - const FileEntry *FromFile - = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, - ToFile->getSize(), - 0); - if (!FromFile) { - AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) - << RemappedFiles[I].first; - delete memBuf; - continue; - } - - // Override the contents of the "from" file with the contents of - // the "to" file. - AST->getSourceManager().overrideFileContents(FromFile, ToFile); - } - } - // Gather Info for preprocessor construction later on. HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); unsigned Counter; - OwningPtr<ASTReader> Reader; - - AST->PP = new Preprocessor(new PreprocessorOptions(), - AST->getDiagnostics(), AST->ASTFileLangOpts, - /*Target=*/0, AST->getSourceManager(), HeaderInfo, - *AST, - /*IILookup=*/0, - /*OwnsHeaderSearch=*/false, - /*DelayInitialization=*/true); + AST->PP = + new Preprocessor(PPOpts, AST->getDiagnostics(), AST->ASTFileLangOpts, + AST->getSourceManager(), HeaderInfo, *AST, + /*IILookup=*/nullptr, + /*OwnsHeaderSearch=*/false); Preprocessor &PP = *AST->PP; - AST->Ctx = new ASTContext(AST->ASTFileLangOpts, - AST->getSourceManager(), - /*Target=*/0, - PP.getIdentifierTable(), - PP.getSelectorTable(), - PP.getBuiltinInfo(), - /* size_reserve = */0, - /*DelayInitialization=*/true); + AST->Ctx = new ASTContext(AST->ASTFileLangOpts, AST->getSourceManager(), + PP.getIdentifierTable(), PP.getSelectorTable(), + PP.getBuiltinInfo()); ASTContext &Context = *AST->Ctx; bool disableValid = false; if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) disableValid = true; - Reader.reset(new ASTReader(PP, Context, + AST->Reader = new ASTReader(PP, Context, /*isysroot=*/"", /*DisableValidation=*/disableValid, - AllowPCHWithCompilerErrors)); - - // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> - ReaderCleanup(Reader.get()); + AllowPCHWithCompilerErrors); - Reader->setListener(new ASTInfoCollector(*AST->PP, Context, + AST->Reader->setListener(new ASTInfoCollector(*AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target, Counter)); - switch (Reader->ReadAST(Filename, serialization::MK_MainFile, + switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile, SourceLocation(), ASTReader::ARR_None)) { case ASTReader::Success: break; @@ -814,24 +745,17 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); - return NULL; + return nullptr; } - AST->OriginalSourceFile = Reader->getOriginalSourceFile(); + AST->OriginalSourceFile = AST->Reader->getOriginalSourceFile(); PP.setCounterValue(Counter); // Attach the AST reader to the AST context as an external AST // source, so that declarations will be deserialized from the // AST file as needed. - ASTReader *ReaderPtr = Reader.get(); - OwningPtr<ExternalASTSource> Source(Reader.take()); - - // Unregister the cleanup for ASTReader. It will get cleaned up - // by the ASTUnit cleanup. - ReaderCleanup.unregister(); - - Context.setExternalSource(Source); + Context.setExternalSource(AST->Reader); // Create an AST consumer, even though it isn't used. AST->Consumer.reset(new ASTConsumer); @@ -839,13 +763,12 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, // Create a semantic analysis object and tell the AST reader about it. AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); AST->TheSema->Initialize(); - ReaderPtr->InitializeSema(*AST->TheSema); - AST->Reader = ReaderPtr; + AST->Reader->InitializeSema(*AST->TheSema); // Tell the diagnostic client that we have started a source file. AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP); - return AST.take(); + return AST.release(); } namespace { @@ -857,9 +780,9 @@ class MacroDefinitionTrackerPPCallbacks : public PPCallbacks { public: explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { } - - virtual void MacroDefined(const Token &MacroNameTok, - const MacroDirective *MD) { + + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash); } }; @@ -881,10 +804,9 @@ void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { // For an unscoped enum include the enumerators in the hash since they // enter the top-level namespace. if (!EnumD->isScoped()) { - for (EnumDecl::enumerator_iterator EI = EnumD->enumerator_begin(), - EE = EnumD->enumerator_end(); EI != EE; ++EI) { - if ((*EI)->getIdentifier()) - Hash = llvm::HashString((*EI)->getIdentifier()->getName(), Hash); + for (const auto *EI : EnumD->enumerators()) { + if (EI->getIdentifier()) + Hash = llvm::HashString(EI->getIdentifier()->getName(), Hash); } } } @@ -937,31 +859,30 @@ public: void handleFileLevelDecl(Decl *D) { Unit.addFileLevelDecl(D); if (NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(D)) { - for (NamespaceDecl::decl_iterator - I = NSD->decls_begin(), E = NSD->decls_end(); I != E; ++I) - handleFileLevelDecl(*I); + for (auto *I : NSD->decls()) + handleFileLevelDecl(I); } } - bool HandleTopLevelDecl(DeclGroupRef D) { + bool HandleTopLevelDecl(DeclGroupRef D) override { for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) handleTopLevelDecl(*it); return true; } // We're not interested in "interesting" decls. - void HandleInterestingDecl(DeclGroupRef) {} + void HandleInterestingDecl(DeclGroupRef) override {} - void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { + void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override { for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) handleTopLevelDecl(*it); } - virtual ASTMutationListener *GetASTMutationListener() { + ASTMutationListener *GetASTMutationListener() override { return Unit.getASTMutationListener(); } - virtual ASTDeserializationListener *GetASTDeserializationListener() { + ASTDeserializationListener *GetASTDeserializationListener() override { return Unit.getDeserializationListener(); } }; @@ -970,8 +891,8 @@ class TopLevelDeclTrackerAction : public ASTFrontendAction { public: ASTUnit &Unit; - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { + ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { CI.getPreprocessor().addPPCallbacks( new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); return new TopLevelDeclTrackerConsumer(Unit, @@ -981,8 +902,8 @@ public: public: TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} - virtual bool hasCodeCompletionSupport() const { return false; } - virtual TranslationUnitKind getTranslationUnitKind() { + bool hasCodeCompletionSupport() const override { return false; } + TranslationUnitKind getTranslationUnitKind() override { return Unit.getTranslationUnitKind(); } }; @@ -995,15 +916,15 @@ public: explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit), HasEmittedPreamblePCH(false) {} - virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile); + ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; } void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; } - virtual bool shouldEraseOutputFiles() { return !hasEmittedPreamblePCH(); } + bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); } - virtual bool hasCodeCompletionSupport() const { return false; } - virtual bool hasASTFileSupport() const { return false; } - virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; } + bool hasCodeCompletionSupport() const override { return false; } + bool hasASTFileSupport() const override { return false; } + TranslationUnitKind getTranslationUnitKind() override { return TU_Prefix; } }; class PrecompilePreambleConsumer : public PCHGenerator { @@ -1016,12 +937,12 @@ public: PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action, const Preprocessor &PP, StringRef isysroot, raw_ostream *Out) - : PCHGenerator(PP, "", 0, isysroot, Out, /*AllowASTWithErrors=*/true), + : PCHGenerator(PP, "", nullptr, isysroot, Out, /*AllowASTWithErrors=*/true), Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) { Hash = 0; } - virtual bool HandleTopLevelDecl(DeclGroupRef D) { + bool HandleTopLevelDecl(DeclGroupRef D) override { for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { Decl *D = *it; // FIXME: Currently ObjC method declarations are incorrectly being @@ -1036,7 +957,7 @@ public: return true; } - virtual void HandleTranslationUnit(ASTContext &Ctx) { + void HandleTranslationUnit(ASTContext &Ctx) override { PCHGenerator::HandleTranslationUnit(Ctx); if (hasEmittedPCH()) { // Translate the top-level declarations we captured during @@ -1062,10 +983,10 @@ ASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; - raw_ostream *OS = 0; + raw_ostream *OS = nullptr; if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS)) - return 0; + return nullptr; if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); @@ -1112,15 +1033,15 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & /// contain any translation-unit information, false otherwise. bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { delete SavedMainFileBuffer; - SavedMainFileBuffer = 0; - + SavedMainFileBuffer = nullptr; + if (!Invocation) { delete OverrideMainBuffer; return true; } // Create the compiler instance to use for building the AST. - OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1129,7 +1050,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { IntrusiveRefCntPtr<CompilerInvocation> CCInvocation(new CompilerInvocation(*Invocation)); - Clang->setInvocation(CCInvocation.getPtr()); + Clang->setInvocation(CCInvocation.get()); OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile(); // Set up diagnostics, capturing any diagnostics that would @@ -1137,8 +1058,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { Clang->setDiagnostics(&getDiagnostics()); // Create the target instance. - Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), - &Clang->getTargetOpts())); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) { delete OverrideMainBuffer; return true; @@ -1148,7 +1069,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. - Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); + Clang->getTarget().adjust(Clang->getLangOpts()); assert(Clang->getFrontendOpts().Inputs.size() == 1 && "Invocation must have exactly one source file!"); @@ -1158,17 +1079,22 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { "IR inputs not support here!"); // Configure the various subsystems. - // FIXME: Should we retain the previous file manager? - LangOpts = &Clang->getLangOpts(); + LangOpts = Clang->getInvocation().LangOpts; FileSystemOpts = Clang->getFileSystemOpts(); - FileMgr = new FileManager(FileSystemOpts); + IntrusiveRefCntPtr<vfs::FileSystem> VFS = + createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics()); + if (!VFS) { + delete OverrideMainBuffer; + return true; + } + FileMgr = new FileManager(FileSystemOpts, VFS); SourceMgr = new SourceManager(getDiagnostics(), *FileMgr, UserFilesAreVolatile); TheSema.reset(); - Ctx = 0; - PP = 0; - Reader = 0; - + Ctx = nullptr; + PP = nullptr; + Reader = nullptr; + // Clear out old caches and data. TopLevelDecls.clear(); clearFileLevelDecls(); @@ -1206,10 +1132,10 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // Keep track of the override buffer; SavedMainFileBuffer = OverrideMainBuffer; } - - OwningPtr<TopLevelDeclTrackerAction> Act( - new TopLevelDeclTrackerAction(*this)); - + + std::unique_ptr<TopLevelDeclTrackerAction> Act( + new TopLevelDeclTrackerAction(*this)); + // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> ActCleanup(Act.get()); @@ -1219,9 +1145,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { if (OverrideMainBuffer) { std::string ModName = getPreambleFile(this); - TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, - getSourceManager(), PreambleDiagnostics, - StoredDiagnostics); + TranslateStoredDiagnostics(getFileManager(), getSourceManager(), + PreambleDiagnostics, StoredDiagnostics); } if (!Act->Execute()) @@ -1239,7 +1164,7 @@ error: // Remove the overridden buffer we used for the preamble. if (OverrideMainBuffer) { delete OverrideMainBuffer; - SavedMainFileBuffer = 0; + SavedMainFileBuffer = nullptr; } // Keep the ownership of the data in the ASTUnit because the client may @@ -1279,17 +1204,13 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, // Try to determine if the main file has been remapped, either from the // command line (to another file) or directly through the compiler invocation // (to a memory buffer). - llvm::MemoryBuffer *Buffer = 0; + llvm::MemoryBuffer *Buffer = nullptr; std::string MainFilePath(FrontendOpts.Inputs[0].getFile()); llvm::sys::fs::UniqueID MainFileID; if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) { // Check whether there is a file-file remapping of the main file - for (PreprocessorOptions::remapped_file_iterator - M = PreprocessorOpts.remapped_file_begin(), - E = PreprocessorOpts.remapped_file_end(); - M != E; - ++M) { - std::string MPath(M->first); + for (const auto &RF : PreprocessorOpts.RemappedFiles) { + std::string MPath(RF.first); llvm::sys::fs::UniqueID MID; if (!llvm::sys::fs::getUniqueID(MPath, MID)) { if (MainFileID == MID) { @@ -1298,11 +1219,10 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, delete Buffer; CreatedBuffer = false; } - - Buffer = getBufferForFile(M->second); + + Buffer = getBufferForFile(RF.second); if (!Buffer) - return std::make_pair((llvm::MemoryBuffer*)0, - std::make_pair(0, true)); + return std::make_pair(nullptr, std::make_pair(0, true)); CreatedBuffer = true; } } @@ -1310,12 +1230,8 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, // Check whether there is a file-buffer remapping. It supercedes the // file-file remapping. - for (PreprocessorOptions::remapped_file_buffer_iterator - M = PreprocessorOpts.remapped_file_buffer_begin(), - E = PreprocessorOpts.remapped_file_buffer_end(); - M != E; - ++M) { - std::string MPath(M->first); + for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) { + std::string MPath(RB.first); llvm::sys::fs::UniqueID MID; if (!llvm::sys::fs::getUniqueID(MPath, MID)) { if (MainFileID == MID) { @@ -1324,8 +1240,8 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, delete Buffer; CreatedBuffer = false; } - - Buffer = const_cast<llvm::MemoryBuffer *>(M->second); + + Buffer = const_cast<llvm::MemoryBuffer *>(RB.second); } } } @@ -1335,8 +1251,8 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, if (!Buffer) { Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile()); if (!Buffer) - return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); - + return std::make_pair(nullptr, std::make_pair(0, true)); + CreatedBuffer = true; } @@ -1345,20 +1261,83 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, MaxLines)); } -static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, - unsigned NewSize, - StringRef NewName) { - llvm::MemoryBuffer *Result - = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); - memcpy(const_cast<char*>(Result->getBufferStart()), - Old->getBufferStart(), Old->getBufferSize()); - memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), - ' ', NewSize - Old->getBufferSize() - 1); - const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; - +ASTUnit::PreambleFileHash +ASTUnit::PreambleFileHash::createForFile(off_t Size, time_t ModTime) { + PreambleFileHash Result; + Result.Size = Size; + Result.ModTime = ModTime; + memset(Result.MD5, 0, sizeof(Result.MD5)); + return Result; +} + +ASTUnit::PreambleFileHash ASTUnit::PreambleFileHash::createForMemoryBuffer( + const llvm::MemoryBuffer *Buffer) { + PreambleFileHash Result; + Result.Size = Buffer->getBufferSize(); + Result.ModTime = 0; + + llvm::MD5 MD5Ctx; + MD5Ctx.update(Buffer->getBuffer().data()); + MD5Ctx.final(Result.MD5); + return Result; } +namespace clang { +bool operator==(const ASTUnit::PreambleFileHash &LHS, + const ASTUnit::PreambleFileHash &RHS) { + return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime && + memcmp(LHS.MD5, RHS.MD5, sizeof(LHS.MD5)) == 0; +} +} // namespace clang + +static std::pair<unsigned, unsigned> +makeStandaloneRange(CharSourceRange Range, const SourceManager &SM, + const LangOptions &LangOpts) { + CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts); + unsigned Offset = SM.getFileOffset(FileRange.getBegin()); + unsigned EndOffset = SM.getFileOffset(FileRange.getEnd()); + return std::make_pair(Offset, EndOffset); +} + +static void makeStandaloneFixIt(const SourceManager &SM, + const LangOptions &LangOpts, + const FixItHint &InFix, + ASTUnit::StandaloneFixIt &OutFix) { + OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts); + OutFix.InsertFromRange = makeStandaloneRange(InFix.InsertFromRange, SM, + LangOpts); + OutFix.CodeToInsert = InFix.CodeToInsert; + OutFix.BeforePreviousInsertions = InFix.BeforePreviousInsertions; +} + +static void makeStandaloneDiagnostic(const LangOptions &LangOpts, + const StoredDiagnostic &InDiag, + ASTUnit::StandaloneDiagnostic &OutDiag) { + OutDiag.ID = InDiag.getID(); + OutDiag.Level = InDiag.getLevel(); + OutDiag.Message = InDiag.getMessage(); + OutDiag.LocOffset = 0; + if (InDiag.getLocation().isInvalid()) + return; + const SourceManager &SM = InDiag.getLocation().getManager(); + SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation()); + OutDiag.Filename = SM.getFilename(FileLoc); + if (OutDiag.Filename.empty()) + return; + OutDiag.LocOffset = SM.getFileOffset(FileLoc); + for (StoredDiagnostic::range_iterator + I = InDiag.range_begin(), E = InDiag.range_end(); I != E; ++I) { + OutDiag.Ranges.push_back(makeStandaloneRange(*I, SM, LangOpts)); + } + for (StoredDiagnostic::fixit_iterator + I = InDiag.fixit_begin(), E = InDiag.fixit_end(); I != E; ++I) { + ASTUnit::StandaloneFixIt Fix; + makeStandaloneFixIt(SM, LangOpts, *I, Fix); + OutDiag.FixIts.push_back(Fix); + } +} + /// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing /// the source file. /// @@ -1395,7 +1374,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); // If ComputePreamble() Take ownership of the preamble buffer. - OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer; + std::unique_ptr<llvm::MemoryBuffer> OwnedPreambleBuffer; if (CreatedPreambleBuffer) OwnedPreambleBuffer.reset(NewPreamble.first); @@ -1407,7 +1386,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // The next time we actually see a preamble, precompile it. PreambleRebuildCounter = 1; - return 0; + return nullptr; } if (!Preamble.empty()) { @@ -1417,7 +1396,6 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // new main file. if (Preamble.size() == NewPreamble.second.first && PreambleEndsAtStartOfLine == NewPreamble.second.second && - NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(), NewPreamble.second.first) == 0) { // The preamble has not changed. We may be able to re-use the precompiled @@ -1428,40 +1406,36 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // First, make a record of those files that have been overridden via // remapping or unsaved_files. - llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; - for (PreprocessorOptions::remapped_file_iterator - R = PreprocessorOpts.remapped_file_begin(), - REnd = PreprocessorOpts.remapped_file_end(); - !AnyFileChanged && R != REnd; - ++R) { - llvm::sys::fs::file_status Status; - if (FileMgr->getNoncachedStatValue(R->second, Status)) { + llvm::StringMap<PreambleFileHash> OverriddenFiles; + for (const auto &R : PreprocessorOpts.RemappedFiles) { + if (AnyFileChanged) + break; + + vfs::Status Status; + if (FileMgr->getNoncachedStatValue(R.second, Status)) { // If we can't stat the file we're remapping to, assume that something // horrible happened. AnyFileChanged = true; break; } - OverriddenFiles[R->first] = std::make_pair( + OverriddenFiles[R.first] = PreambleFileHash::createForFile( Status.getSize(), Status.getLastModificationTime().toEpochTime()); } - for (PreprocessorOptions::remapped_file_buffer_iterator - R = PreprocessorOpts.remapped_file_buffer_begin(), - REnd = PreprocessorOpts.remapped_file_buffer_end(); - !AnyFileChanged && R != REnd; - ++R) { - // FIXME: Should we actually compare the contents of file->buffer - // remappings? - OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), - 0); + + for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) { + if (AnyFileChanged) + break; + OverriddenFiles[RB.first] = + PreambleFileHash::createForMemoryBuffer(RB.second); } // Check whether anything has changed. - for (llvm::StringMap<std::pair<off_t, time_t> >::iterator + for (llvm::StringMap<PreambleFileHash>::iterator F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); !AnyFileChanged && F != FEnd; ++F) { - llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden + llvm::StringMap<PreambleFileHash>::iterator Overridden = OverriddenFiles.find(F->first()); if (Overridden != OverriddenFiles.end()) { // This file was remapped; check whether the newly-mapped file @@ -1472,13 +1446,13 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( } // The file was not remapped; check whether it has changed on disk. - llvm::sys::fs::file_status Status; + vfs::Status Status; if (FileMgr->getNoncachedStatValue(F->first(), Status)) { // If we can't stat the file, assume that something horrible happened. AnyFileChanged = true; - } else if (Status.getSize() != uint64_t(F->second.first) || + } else if (Status.getSize() != uint64_t(F->second.Size) || Status.getLastModificationTime().toEpochTime() != - uint64_t(F->second.second)) + uint64_t(F->second.ModTime)) AnyFileChanged = true; } @@ -1492,18 +1466,15 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( PreambleInvocation->getDiagnosticOpts()); getDiagnostics().setNumWarnings(NumWarningsInPreamble); - // Create a version of the main file buffer that is padded to - // buffer size we reserved when creating the preamble. - return CreatePaddedMainFileBuffer(NewPreamble.first, - PreambleReservedSize, - FrontendOpts.Inputs[0].getFile()); + return llvm::MemoryBuffer::getMemBufferCopy( + NewPreamble.first->getBuffer(), FrontendOpts.Inputs[0].getFile()); } } // If we aren't allowed to rebuild the precompiled preamble, just // return now. if (!AllowRebuild) - return 0; + return nullptr; // We can't reuse the previously-computed preamble. Build a new one. Preamble.clear(); @@ -1513,7 +1484,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( } else if (!AllowRebuild) { // We aren't allowed to rebuild the precompiled preamble; just // return now. - return 0; + return nullptr; } // If the preamble rebuild counter > 1, it's because we previously @@ -1521,7 +1492,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // again. Decrement the counter and return a failure. if (PreambleRebuildCounter > 1) { --PreambleRebuildCounter; - return 0; + return nullptr; } // Create a temporary file for the precompiled preamble. In rare @@ -1530,26 +1501,16 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( if (PreamblePCHPath.empty()) { // Try again next time. PreambleRebuildCounter = 1; - return 0; + return nullptr; } // We did not previously compute a preamble, or it can't be reused anyway. SimpleTimer PreambleTimer(WantTiming); PreambleTimer.setOutput("Precompiling preamble"); - - // Create a new buffer that stores the preamble. The buffer also contains - // extra space for the original contents of the file (which will be present - // when we actually parse the file) along with more room in case the file - // grows. - PreambleReservedSize = NewPreamble.first->getBufferSize(); - if (PreambleReservedSize < 4096) - PreambleReservedSize = 8191; - else - PreambleReservedSize *= 2; // Save the preamble text for later; we'll need to compare against it for // subsequent reparses. - StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].getFile(); + StringRef MainFilename = FrontendOpts.Inputs[0].getFile(); Preamble.assign(FileMgr->getFile(MainFilename), NewPreamble.first->getBufferStart(), NewPreamble.first->getBufferStart() @@ -1558,13 +1519,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( delete PreambleBuffer; PreambleBuffer - = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, - FrontendOpts.Inputs[0].getFile()); - memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), - NewPreamble.first->getBufferStart(), Preamble.size()); - memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), - ' ', PreambleReservedSize - Preamble.size() - 1); - const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; + = llvm::MemoryBuffer::getMemBufferCopy( + NewPreamble.first->getBuffer().slice(0, Preamble.size()), MainFilename); // Remap the main source file to the preamble buffer. StringRef MainFilePath = FrontendOpts.Inputs[0].getFile(); @@ -1578,7 +1534,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( PreprocessorOpts.PrecompiledPreambleBytes.second = false; // Create the compiler instance to use for building the precompiled preamble. - OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1591,22 +1547,21 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( Clang->setDiagnostics(&getDiagnostics()); // Create the target instance. - Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), - &Clang->getTargetOpts())); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) { llvm::sys::fs::remove(FrontendOpts.OutputFile); Preamble.clear(); PreambleRebuildCounter = DefaultPreambleRebuildInterval; - PreprocessorOpts.eraseRemappedFile( - PreprocessorOpts.remapped_file_buffer_end() - 1); - return 0; + PreprocessorOpts.RemappedFileBuffers.pop_back(); + return nullptr; } // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. - Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); + Clang->getTarget().adjust(Clang->getLangOpts()); assert(Clang->getFrontendOpts().Inputs.size() == 1 && "Invocation must have exactly one source file!"); @@ -1621,28 +1576,49 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( checkAndRemoveNonDriverDiags(StoredDiagnostics); TopLevelDecls.clear(); TopLevelDeclsInPreamble.clear(); - + PreambleDiagnostics.clear(); + + IntrusiveRefCntPtr<vfs::FileSystem> VFS = + createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics()); + if (!VFS) + return nullptr; + // Create a file manager object to provide access to and cache the filesystem. - Clang->setFileManager(new FileManager(Clang->getFileSystemOpts())); + Clang->setFileManager(new FileManager(Clang->getFileSystemOpts(), VFS)); // Create the source manager. Clang->setSourceManager(new SourceManager(getDiagnostics(), Clang->getFileManager())); - - OwningPtr<PrecompilePreambleAction> Act; + + auto PreambleDepCollector = std::make_shared<DependencyCollector>(); + Clang->addDependencyCollector(PreambleDepCollector); + + std::unique_ptr<PrecompilePreambleAction> Act; Act.reset(new PrecompilePreambleAction(*this)); if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { llvm::sys::fs::remove(FrontendOpts.OutputFile); Preamble.clear(); PreambleRebuildCounter = DefaultPreambleRebuildInterval; - PreprocessorOpts.eraseRemappedFile( - PreprocessorOpts.remapped_file_buffer_end() - 1); - return 0; + PreprocessorOpts.RemappedFileBuffers.pop_back(); + return nullptr; } Act->Execute(); + + // Transfer any diagnostics generated when parsing the preamble into the set + // of preamble diagnostics. + for (stored_diag_iterator + I = stored_diag_afterDriver_begin(), + E = stored_diag_end(); I != E; ++I) { + StandaloneDiagnostic Diag; + makeStandaloneDiagnostic(Clang->getLangOpts(), *I, Diag); + PreambleDiagnostics.push_back(Diag); + } + Act->EndSourceFile(); + checkAndRemoveNonDriverDiags(StoredDiagnostics); + if (!Act->hasEmittedPreamblePCH()) { // The preamble PCH failed (e.g. there was a module loading fatal error), // so no precompiled header was generated. Forget that we even tried. @@ -1651,18 +1627,10 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( Preamble.clear(); TopLevelDeclsInPreamble.clear(); PreambleRebuildCounter = DefaultPreambleRebuildInterval; - PreprocessorOpts.eraseRemappedFile( - PreprocessorOpts.remapped_file_buffer_end() - 1); - return 0; + PreprocessorOpts.RemappedFileBuffers.pop_back(); + return nullptr; } - // Transfer any diagnostics generated when parsing the preamble into the set - // of preamble diagnostics. - PreambleDiagnostics.clear(); - PreambleDiagnostics.insert(PreambleDiagnostics.end(), - stored_diag_afterDriver_begin(), stored_diag_end()); - checkAndRemoveNonDriverDiags(StoredDiagnostics); - // Keep track of the preamble we precompiled. setPreambleFile(this, FrontendOpts.OutputFile); NumWarningsInPreamble = getDiagnostics().getNumWarnings(); @@ -1671,24 +1639,23 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // so we can verify whether they have changed or not. FilesInPreamble.clear(); SourceManager &SourceMgr = Clang->getSourceManager(); - const llvm::MemoryBuffer *MainFileBuffer - = SourceMgr.getBuffer(SourceMgr.getMainFileID()); - for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), - FEnd = SourceMgr.fileinfo_end(); - F != FEnd; - ++F) { - const FileEntry *File = F->second->OrigEntry; - if (!File || F->second->getRawBuffer() == MainFileBuffer) + for (auto &Filename : PreambleDepCollector->getDependencies()) { + const FileEntry *File = Clang->getFileManager().getFile(Filename); + if (!File || File == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())) continue; - - FilesInPreamble[File->getName()] - = std::make_pair(F->second->getSize(), File->getModificationTime()); + if (time_t ModTime = File->getModificationTime()) { + FilesInPreamble[File->getName()] = PreambleFileHash::createForFile( + File->getSize(), ModTime); + } else { + llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File); + FilesInPreamble[File->getName()] = + PreambleFileHash::createForMemoryBuffer(Buffer); + } } - + PreambleRebuildCounter = 1; - PreprocessorOpts.eraseRemappedFile( - PreprocessorOpts.remapped_file_buffer_end() - 1); - + PreprocessorOpts.RemappedFileBuffers.pop_back(); + // If the hash of top-level entities differs from the hash of the top-level // entities the last time we rebuilt the preamble, clear out the completion // cache. @@ -1697,9 +1664,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( PreambleTopLevelHashValue = CurrentTopLevelHashValue; } - return CreatePaddedMainFileBuffer(NewPreamble.first, - PreambleReservedSize, - FrontendOpts.Inputs[0].getFile()); + return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.first->getBuffer(), + MainFilename); } void ASTUnit::RealizeTopLevelDeclsFromPreamble() { @@ -1718,14 +1684,20 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { } void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) { - // Steal the created target, context, and preprocessor. + // Steal the created target, context, and preprocessor if they have been + // created. + assert(CI.hasInvocation() && "missing invocation"); + LangOpts = CI.getInvocation().LangOpts; TheSema.reset(CI.takeSema()); Consumer.reset(CI.takeASTConsumer()); - Ctx = &CI.getASTContext(); - PP = &CI.getPreprocessor(); - CI.setSourceManager(0); - CI.setFileManager(0); - Target = &CI.getTarget(); + if (CI.hasASTContext()) + Ctx = &CI.getASTContext(); + if (CI.hasPreprocessor()) + PP = &CI.getPreprocessor(); + CI.setSourceManager(nullptr); + CI.setFileManager(nullptr); + if (CI.hasTarget()) + Target = &CI.getTarget(); Reader = CI.getModuleManager(); HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure(); } @@ -1761,41 +1733,41 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool CaptureDiagnostics, bool UserFilesAreVolatile) { - OwningPtr<ASTUnit> AST; + std::unique_ptr<ASTUnit> AST; AST.reset(new ASTUnit(false)); - ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); + ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; AST->Invocation = CI; AST->FileSystemOpts = CI->getFileSystemOpts(); - AST->FileMgr = new FileManager(AST->FileSystemOpts); + IntrusiveRefCntPtr<vfs::FileSystem> VFS = + createVFSFromCompilerInvocation(*CI, *Diags); + if (!VFS) + return nullptr; + AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); AST->UserFilesAreVolatile = UserFilesAreVolatile; AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile); - return AST.take(); + return AST.release(); } -ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - ASTFrontendAction *Action, - ASTUnit *Unit, - bool Persistent, - StringRef ResourceFilesPath, - bool OnlyLocalDecls, - bool CaptureDiagnostics, - bool PrecompilePreamble, - bool CacheCodeCompletionResults, - bool IncludeBriefCommentsInCodeCompletion, - bool UserFilesAreVolatile, - OwningPtr<ASTUnit> *ErrAST) { +ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( + CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + ASTFrontendAction *Action, ASTUnit *Unit, bool Persistent, + StringRef ResourceFilesPath, bool OnlyLocalDecls, bool CaptureDiagnostics, + bool PrecompilePreamble, bool CacheCodeCompletionResults, + bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile, + std::unique_ptr<ASTUnit> *ErrAST) { assert(CI && "A CompilerInvocation is required"); - OwningPtr<ASTUnit> OwnAST; + std::unique_ptr<ASTUnit> OwnAST; ASTUnit *AST = Unit; if (!AST) { // Create the AST unit. OwnAST.reset(create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile)); AST = OwnAST.get(); + if (!AST) + return nullptr; } if (!ResourceFilesPath.empty()) { @@ -1816,7 +1788,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, ASTUnitCleanup(OwnAST.get()); llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > - DiagCleanup(Diags.getPtr()); + DiagCleanup(Diags.get()); // We'll manage file buffers ourselves. CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; @@ -1824,7 +1796,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); // Create the compiler instance to use for building the AST. - OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1838,16 +1810,16 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, Clang->setDiagnostics(&AST->getDiagnostics()); // Create the target instance. - Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), - &Clang->getTargetOpts())); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) - return 0; + return nullptr; // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. - Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); + Clang->getTarget().adjust(Clang->getLangOpts()); assert(Clang->getFrontendOpts().Inputs.size() == 1 && "Invocation must have exactly one source file!"); @@ -1858,10 +1830,10 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, // Configure the various subsystems. AST->TheSema.reset(); - AST->Ctx = 0; - AST->PP = 0; - AST->Reader = 0; - + AST->Ctx = nullptr; + AST->PP = nullptr; + AST->Reader = nullptr; + // Create a file manager object to provide access to and cache the filesystem. Clang->setFileManager(&AST->getFileManager()); @@ -1870,7 +1842,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, ASTFrontendAction *Act = Action; - OwningPtr<TopLevelDeclTrackerAction> TrackerAct; + std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct; if (!Act) { TrackerAct.reset(new TopLevelDeclTrackerAction(*AST)); Act = TrackerAct.get(); @@ -1885,7 +1857,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, if (OwnAST && ErrAST) ErrAST->swap(OwnAST); - return 0; + return nullptr; } if (Persistent && !TrackerAct) { @@ -1903,7 +1875,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, if (OwnAST && ErrAST) ErrAST->swap(OwnAST); - return 0; + return nullptr; } // Steal the created target, context, and preprocessor. @@ -1912,7 +1884,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, Act->EndSourceFile(); if (OwnAST) - return OwnAST.take(); + return OwnAST.release(); else return AST; } @@ -1926,7 +1898,7 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { Invocation->getFrontendOpts().DisableFree = false; ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); - llvm::MemoryBuffer *OverrideMainBuffer = 0; + llvm::MemoryBuffer *OverrideMainBuffer = nullptr; if (PrecompilePreamble) { PreambleRebuildCounter = 2; OverrideMainBuffer @@ -1943,19 +1915,14 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { return Parse(OverrideMainBuffer); } -ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - bool OnlyLocalDecls, - bool CaptureDiagnostics, - bool PrecompilePreamble, - TranslationUnitKind TUKind, - bool CacheCodeCompletionResults, - bool IncludeBriefCommentsInCodeCompletion, - bool UserFilesAreVolatile) { +std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( + CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble, + TranslationUnitKind TUKind, bool CacheCodeCompletionResults, + bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) { // Create the AST unit. - OwningPtr<ASTUnit> AST; - AST.reset(new ASTUnit(false)); - ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); + std::unique_ptr<ASTUnit> AST(new ASTUnit(false)); + ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; @@ -1965,7 +1932,11 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, = IncludeBriefCommentsInCodeCompletion; AST->Invocation = CI; AST->FileSystemOpts = CI->getFileSystemOpts(); - AST->FileMgr = new FileManager(AST->FileSystemOpts); + IntrusiveRefCntPtr<vfs::FileSystem> VFS = + createVFSFromCompilerInvocation(*CI, *Diags); + if (!VFS) + return nullptr; + AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); AST->UserFilesAreVolatile = UserFilesAreVolatile; // Recover resources if we crash before exiting this method. @@ -1973,30 +1944,24 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, ASTUnitCleanup(AST.get()); llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > - DiagCleanup(Diags.getPtr()); - - return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); -} - -ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, - const char **ArgEnd, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - StringRef ResourceFilesPath, - bool OnlyLocalDecls, - bool CaptureDiagnostics, - RemappedFile *RemappedFiles, - unsigned NumRemappedFiles, - bool RemappedFilesKeepOriginalName, - bool PrecompilePreamble, - TranslationUnitKind TUKind, - bool CacheCodeCompletionResults, - bool IncludeBriefCommentsInCodeCompletion, - bool AllowPCHWithCompilerErrors, - bool SkipFunctionBodies, - bool UserFilesAreVolatile, - bool ForSerialization, - OwningPtr<ASTUnit> *ErrAST) { - if (!Diags.getPtr()) { + DiagCleanup(Diags.get()); + + if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) + return nullptr; + return AST; +} + +ASTUnit *ASTUnit::LoadFromCommandLine( + const char **ArgBegin, const char **ArgEnd, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, + bool OnlyLocalDecls, bool CaptureDiagnostics, + ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName, + bool PrecompilePreamble, TranslationUnitKind TUKind, + bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion, + bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies, + bool UserFilesAreVolatile, bool ForSerialization, + std::unique_ptr<ASTUnit> *ErrAST) { + if (!Diags.get()) { // No diagnostics engine was provided, so create our own diagnostics object // with the default options. Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); @@ -2015,19 +1980,13 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, llvm::makeArrayRef(ArgBegin, ArgEnd), Diags); if (!CI) - return 0; + return nullptr; } // Override any files that need remapping - for (unsigned I = 0; I != NumRemappedFiles; ++I) { - FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; - if (const llvm::MemoryBuffer * - memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { - CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf); - } else { - const char *fname = fileOrBuf.get<const char *>(); - CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname); - } + for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) { + CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, + RemappedFiles[I].second); } PreprocessorOptions &PPOpts = CI->getPreprocessorOpts(); PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName; @@ -2039,13 +1998,17 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies; // Create the AST unit. - OwningPtr<ASTUnit> AST; + std::unique_ptr<ASTUnit> AST; AST.reset(new ASTUnit(false)); ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; - Diags = 0; // Zero out now to ease cleanup during crash recovery. + Diags = nullptr; // Zero out now to ease cleanup during crash recovery. AST->FileSystemOpts = CI->getFileSystemOpts(); - AST->FileMgr = new FileManager(AST->FileSystemOpts); + IntrusiveRefCntPtr<vfs::FileSystem> VFS = + createVFSFromCompilerInvocation(*CI, *Diags); + if (!VFS) + return nullptr; + AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->TUKind = TUKind; @@ -2058,8 +2021,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, AST->Invocation = CI; if (ForSerialization) AST->WriterData.reset(new ASTWriterData()); - CI = 0; // Zero out now to ease cleanup during crash recovery. - + CI = nullptr; // Zero out now to ease cleanup during crash recovery. + // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get()); @@ -2071,13 +2034,13 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics); ErrAST->swap(AST); } - return 0; + return nullptr; } - return AST.take(); + return AST.release(); } -bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { +bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) { if (!Invocation) return true; @@ -2088,30 +2051,18 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { // Remap files. PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); - for (PreprocessorOptions::remapped_file_buffer_iterator - R = PPOpts.remapped_file_buffer_begin(), - REnd = PPOpts.remapped_file_buffer_end(); - R != REnd; - ++R) { - delete R->second; - } + for (const auto &RB : PPOpts.RemappedFileBuffers) + delete RB.second; + Invocation->getPreprocessorOpts().clearRemappedFiles(); - for (unsigned I = 0; I != NumRemappedFiles; ++I) { - FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; - if (const llvm::MemoryBuffer * - memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { - Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, - memBuf); - } else { - const char *fname = fileOrBuf.get<const char *>(); - Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, - fname); - } + for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) { + Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, + RemappedFiles[I].second); } - + // If we have a preamble file lying around, or if we might try to // build a precompiled preamble, do so now. - llvm::MemoryBuffer *OverrideMainBuffer = 0; + llvm::MemoryBuffer *OverrideMainBuffer = nullptr; if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0) OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); @@ -2178,23 +2129,22 @@ namespace { | (1LL << CodeCompletionContext::CCC_UnionTag) | (1LL << CodeCompletionContext::CCC_ClassOrStructTag); } - - virtual void ProcessCodeCompleteResults(Sema &S, - CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults); - - virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates) { + + void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) override; + + void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates) override { Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); } - - virtual CodeCompletionAllocator &getAllocator() { + + CodeCompletionAllocator &getAllocator() override { return Next.getAllocator(); } - virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return Next.getCodeCompletionTUInfo(); } }; @@ -2378,8 +2328,7 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, - RemappedFile *RemappedFiles, - unsigned NumRemappedFiles, + ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros, bool IncludeCodePatterns, bool IncludeBriefComments, @@ -2417,7 +2366,7 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // Set the language options appropriately. LangOpts = *CCInvocation->getLangOpts(); - OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -2434,10 +2383,10 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts()); // Create the target instance. - Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), - &Clang->getTargetOpts())); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) { - Clang->setInvocation(0); + Clang->setInvocation(nullptr); return; } @@ -2445,7 +2394,7 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. - Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); + Clang->getTarget().adjust(Clang->getLangOpts()); assert(Clang->getFrontendOpts().Inputs.size() == 1 && "Invocation must have exactly one source file!"); @@ -2462,18 +2411,12 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // Remap files. PreprocessorOpts.clearRemappedFiles(); PreprocessorOpts.RetainRemappedFileBuffers = true; - for (unsigned I = 0; I != NumRemappedFiles; ++I) { - FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; - if (const llvm::MemoryBuffer * - memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { - PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf); - OwnedBuffers.push_back(memBuf); - } else { - const char *fname = fileOrBuf.get<const char *>(); - PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname); - } + for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) { + PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, + RemappedFiles[I].second); + OwnedBuffers.push_back(RemappedFiles[I].second); } - + // Use the code completion consumer we were given, but adding any cached // code-completion results. AugmentedCodeCompleteConsumer *AugmentedConsumer @@ -2484,7 +2427,7 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // the use of the precompiled preamble if we're if the completion // point is within the main file, after the end of the precompiled // preamble. - llvm::MemoryBuffer *OverrideMainBuffer = 0; + llvm::MemoryBuffer *OverrideMainBuffer = nullptr; if (!getPreambleFile(this).empty()) { std::string CompleteFilePath(File); llvm::sys::fs::UniqueID CompleteFileID; @@ -2520,8 +2463,8 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // Disable the preprocessing record if modules are not enabled. if (!Clang->getLangOpts().Modules) PreprocessorOpts.DetailedRecord = false; - - OwningPtr<SyntaxOnlyAction> Act; + + std::unique_ptr<SyntaxOnlyAction> Act; Act.reset(new SyntaxOnlyAction); if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { Act->Execute(); @@ -2554,8 +2497,7 @@ bool ASTUnit::Save(StringRef File) { } if (llvm::sys::fs::rename(TempPath.str(), File)) { - bool exists; - llvm::sys::fs::remove(TempPath.str(), exists); + llvm::sys::fs::remove(TempPath.str()); return true; } @@ -2567,7 +2509,7 @@ static bool serializeUnit(ASTWriter &Writer, Sema &S, bool hasErrors, raw_ostream &OS) { - Writer.WriteAST(S, std::string(), 0, "", hasErrors); + Writer.WriteAST(S, std::string(), nullptr, "", hasErrors); // Write the generated bitstream to "Out". if (!Buffer.empty()) @@ -2591,68 +2533,57 @@ bool ASTUnit::serialize(raw_ostream &OS) { typedef ContinuousRangeMap<unsigned, int, 2> SLocRemap; -static void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) { - unsigned Raw = L.getRawEncoding(); - const unsigned MacroBit = 1U << 31; - L = SourceLocation::getFromRawEncoding((Raw & MacroBit) | - ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second)); -} - void ASTUnit::TranslateStoredDiagnostics( - ASTReader *MMan, - StringRef ModName, + FileManager &FileMgr, SourceManager &SrcMgr, - const SmallVectorImpl<StoredDiagnostic> &Diags, + const SmallVectorImpl<StandaloneDiagnostic> &Diags, SmallVectorImpl<StoredDiagnostic> &Out) { - // The stored diagnostic has the old source manager in it; update - // the locations to refer into the new source manager. We also need to remap - // all the locations to the new view. This includes the diag location, any - // associated source ranges, and the source ranges of associated fix-its. + // Map the standalone diagnostic into the new source manager. We also need to + // remap all the locations to the new view. This includes the diag location, + // any associated source ranges, and the source ranges of associated fix-its. // FIXME: There should be a cleaner way to do this. SmallVector<StoredDiagnostic, 4> Result; Result.reserve(Diags.size()); - assert(MMan && "Don't have a module manager"); - serialization::ModuleFile *Mod = MMan->ModuleMgr.lookup(ModName); - assert(Mod && "Don't have preamble module"); - SLocRemap &Remap = Mod->SLocRemap; for (unsigned I = 0, N = Diags.size(); I != N; ++I) { // Rebuild the StoredDiagnostic. - const StoredDiagnostic &SD = Diags[I]; - SourceLocation L = SD.getLocation(); - TranslateSLoc(L, Remap); + const StandaloneDiagnostic &SD = Diags[I]; + if (SD.Filename.empty()) + continue; + const FileEntry *FE = FileMgr.getFile(SD.Filename); + if (!FE) + continue; + FileID FID = SrcMgr.translateFile(FE); + SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID); + if (FileLoc.isInvalid()) + continue; + SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset); FullSourceLoc Loc(L, SrcMgr); SmallVector<CharSourceRange, 4> Ranges; - Ranges.reserve(SD.range_size()); - for (StoredDiagnostic::range_iterator I = SD.range_begin(), - E = SD.range_end(); - I != E; ++I) { - SourceLocation BL = I->getBegin(); - TranslateSLoc(BL, Remap); - SourceLocation EL = I->getEnd(); - TranslateSLoc(EL, Remap); - Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange())); + Ranges.reserve(SD.Ranges.size()); + for (std::vector<std::pair<unsigned, unsigned> >::const_iterator + I = SD.Ranges.begin(), E = SD.Ranges.end(); I != E; ++I) { + SourceLocation BL = FileLoc.getLocWithOffset((*I).first); + SourceLocation EL = FileLoc.getLocWithOffset((*I).second); + Ranges.push_back(CharSourceRange::getCharRange(BL, EL)); } SmallVector<FixItHint, 2> FixIts; - FixIts.reserve(SD.fixit_size()); - for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(), - E = SD.fixit_end(); + FixIts.reserve(SD.FixIts.size()); + for (std::vector<StandaloneFixIt>::const_iterator + I = SD.FixIts.begin(), E = SD.FixIts.end(); I != E; ++I) { FixIts.push_back(FixItHint()); FixItHint &FH = FixIts.back(); FH.CodeToInsert = I->CodeToInsert; - SourceLocation BL = I->RemoveRange.getBegin(); - TranslateSLoc(BL, Remap); - SourceLocation EL = I->RemoveRange.getEnd(); - TranslateSLoc(EL, Remap); - FH.RemoveRange = CharSourceRange(SourceRange(BL, EL), - I->RemoveRange.isTokenRange()); + SourceLocation BL = FileLoc.getLocWithOffset(I->RemoveRange.first); + SourceLocation EL = FileLoc.getLocWithOffset(I->RemoveRange.second); + FH.RemoveRange = CharSourceRange::getCharRange(BL, EL); } - Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(), - SD.getMessage(), Loc, Ranges, FixIts)); + Result.push_back(StoredDiagnostic(SD.Level, SD.ID, + SD.Message, Loc, Ranges, FixIts)); } Result.swap(Out); } @@ -2677,7 +2608,7 @@ void ASTUnit::addFileLevelDecl(Decl *D) { assert(SM.isLocalSourceLocation(FileLoc)); FileID FID; unsigned Offset; - llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc); + std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc); if (FID.isInvalid()) return; @@ -2719,7 +2650,8 @@ void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, LocDeclsTy::iterator BeginIt = std::lower_bound(LocDecls.begin(), LocDecls.end(), - std::make_pair(Offset, (Decl *)0), llvm::less_first()); + std::make_pair(Offset, (Decl *)nullptr), + llvm::less_first()); if (BeginIt != LocDecls.begin()) --BeginIt; @@ -2732,7 +2664,7 @@ void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, LocDeclsTy::iterator EndIt = std::upper_bound( LocDecls.begin(), LocDecls.end(), - std::make_pair(Offset + Length, (Decl *)0), llvm::less_first()); + std::make_pair(Offset + Length, (Decl *)nullptr), llvm::less_first()); if (EndIt != LocDecls.end()) ++EndIt; @@ -2860,7 +2792,7 @@ bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) { serialization::ModuleFile & Mod = Reader->getModuleManager().getPrimaryModule(); ASTReader::ModuleDeclIterator MDI, MDE; - llvm::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod); + std::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod); for (; MDI != MDE; ++MDI) { if (!Fn(context, *MDI)) return false; @@ -2882,7 +2814,7 @@ bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) { namespace { struct PCHLocatorInfo { serialization::ModuleFile *Mod; - PCHLocatorInfo() : Mod(0) {} + PCHLocatorInfo() : Mod(nullptr) {} }; } @@ -2905,14 +2837,14 @@ static bool PCHLocator(serialization::ModuleFile &M, void *UserData) { const FileEntry *ASTUnit::getPCHFile() { if (!Reader) - return 0; + return nullptr; PCHLocatorInfo Info; Reader->getModuleManager().visit(PCHLocator, &Info); if (Info.Mod) return Info.Mod->File; - return 0; + return nullptr; } bool ASTUnit::isModuleFile() { @@ -2953,7 +2885,7 @@ void ASTUnit::ConcurrencyState::finish() { #else // NDEBUG -ASTUnit::ConcurrencyState::ConcurrencyState() {} +ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = 0; } ASTUnit::ConcurrencyState::~ConcurrencyState() {} void ASTUnit::ConcurrencyState::start() {} void ASTUnit::ConcurrencyState::finish() {} |