diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend')
14 files changed, 384 insertions, 144 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp index b84df94..f6f1551 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp @@ -45,8 +45,10 @@ void ASTMergeAction::ExecuteAction() { new ForwardingDiagnosticConsumer( *CI.getDiagnostics().getClient()), /*ShouldOwnClient=*/true)); - std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile( - ASTFiles[I], Diags, CI.getFileSystemOpts(), false); + std::unique_ptr<ASTUnit> Unit = + ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerOperations(), + Diags, CI.getFileSystemOpts(), false); + if (!Unit) continue; diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp index 4fd330d4..01c56bd 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp @@ -648,7 +648,9 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, } std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( - const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + const std::string &Filename, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics, bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) { @@ -705,10 +707,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( bool disableValid = false; if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) disableValid = true; - AST->Reader = new ASTReader(PP, Context, - /*isysroot=*/"", - /*DisableValidation=*/disableValid, - AllowPCHWithCompilerErrors); + AST->Reader = new ASTReader(PP, Context, *PCHContainerOps, + /*isysroot=*/"", + /*DisableValidation=*/disableValid, + AllowPCHWithCompilerErrors); AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>( *AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target, @@ -916,13 +918,16 @@ class PrecompilePreambleConsumer : public PCHGenerator { unsigned &Hash; std::vector<Decl *> TopLevelDecls; PrecompilePreambleAction *Action; + raw_ostream *Out; public: PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action, const Preprocessor &PP, StringRef isysroot, raw_ostream *Out) - : PCHGenerator(PP, "", nullptr, isysroot, Out, /*AllowASTWithErrors=*/true), - Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) { + : PCHGenerator(PP, "", nullptr, isysroot, std::make_shared<PCHBuffer>(), + /*AllowASTWithErrors=*/true), + Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action), + Out(Out) { Hash = 0; } @@ -943,6 +948,14 @@ public: void HandleTranslationUnit(ASTContext &Ctx) override { PCHGenerator::HandleTranslationUnit(Ctx); if (hasEmittedPCH()) { + // Write the generated bitstream to "Out". + *Out << getPCH(); + // Make sure it hits disk now. + Out->flush(); + // Free the buffer. + llvm::SmallVector<char, 0> Empty; + getPCH() = std::move(Empty); + // Translate the top-level declarations we captured during // parsing into declaration IDs in the precompiled // preamble. This will allow us to deserialize those top-level @@ -1015,14 +1028,16 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & /// /// \returns True if a failure occurred that causes the ASTUnit not to /// contain any translation-unit information, false otherwise. -bool ASTUnit::Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) { +bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, + std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) { SavedMainFileBuffer.reset(); if (!Invocation) return true; // Create the compiler instance to use for building the AST. - std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang( + new CompilerInstance(PCHContainerOps)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1323,6 +1338,7 @@ makeStandaloneDiagnostic(const LangOptions &LangOpts, /// Otherwise, returns a NULL pointer. std::unique_ptr<llvm::MemoryBuffer> ASTUnit::getMainBufferWithPrecompiledPreamble( + std::shared_ptr<PCHContainerOperations> PCHContainerOps, const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild, unsigned MaxLines) { @@ -1487,7 +1503,8 @@ ASTUnit::getMainBufferWithPrecompiledPreamble( PreprocessorOpts.PrecompiledPreambleBytes.second = false; // Create the compiler instance to use for building the precompiled preamble. - std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang( + new CompilerInstance(PCHContainerOps)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1702,12 +1719,13 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI, } 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) { + CompilerInvocation *CI, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + 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"); std::unique_ptr<ASTUnit> OwnAST; @@ -1746,7 +1764,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); // Create the compiler instance to use for building the AST. - std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang( + new CompilerInstance(PCHContainerOps)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -1841,7 +1860,9 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( return AST; } -bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { +bool ASTUnit::LoadFromCompilerInvocation( + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + bool PrecompilePreamble) { if (!Invocation) return true; @@ -1853,7 +1874,8 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (PrecompilePreamble) { PreambleRebuildCounter = 2; - OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); + OverrideMainBuffer = + getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation); } SimpleTimer ParsingTimer(WantTiming); @@ -1863,12 +1885,14 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> MemBufferCleanup(OverrideMainBuffer.get()); - return Parse(std::move(OverrideMainBuffer)); + return Parse(PCHContainerOps, std::move(OverrideMainBuffer)); } std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( - CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble, + CompilerInvocation *CI, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls, + bool CaptureDiagnostics, bool PrecompilePreamble, TranslationUnitKind TUKind, bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) { // Create the AST unit. @@ -1897,13 +1921,14 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > DiagCleanup(Diags.get()); - if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) + if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble)) return nullptr; return AST; } ASTUnit *ASTUnit::LoadFromCommandLine( const char **ArgBegin, const char **ArgEnd, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, bool OnlyLocalDecls, bool CaptureDiagnostics, ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName, @@ -1975,7 +2000,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get()); - if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) { + if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble)) { // Some error occurred, if caller wants to examine diagnostics, pass it the // ASTUnit. if (ErrAST) { @@ -1988,7 +2013,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine( return AST.release(); } -bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) { +bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, + ArrayRef<RemappedFile> RemappedFiles) { if (!Invocation) return true; @@ -2012,8 +2038,9 @@ bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) { // build a precompiled preamble, do so now. std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0) - OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); - + OverrideMainBuffer = + getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation); + // Clear out the diagnostics state. getDiagnostics().Reset(); ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); @@ -2021,7 +2048,7 @@ bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) { getDiagnostics().setNumWarnings(NumWarningsInPreamble); // Parse the sources - bool Result = Parse(std::move(OverrideMainBuffer)); + bool Result = Parse(PCHContainerOps, std::move(OverrideMainBuffer)); // If we're caching global code-completion results, and the top-level // declarations have changed, clear out the code-completion cache. @@ -2273,18 +2300,15 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, AllResults.size()); } - - -void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, - ArrayRef<RemappedFile> RemappedFiles, - bool IncludeMacros, - bool IncludeCodePatterns, - bool IncludeBriefComments, - CodeCompleteConsumer &Consumer, - DiagnosticsEngine &Diag, LangOptions &LangOpts, - SourceManager &SourceMgr, FileManager &FileMgr, - SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, - SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { +void ASTUnit::CodeComplete( + StringRef File, unsigned Line, unsigned Column, + ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros, + bool IncludeCodePatterns, bool IncludeBriefComments, + CodeCompleteConsumer &Consumer, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr, + FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, + SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { if (!Invocation) return; @@ -2318,7 +2342,8 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, LangOpts.SpellChecking = false; CCInvocation->getDiagnosticOpts().IgnoreWarnings = true; - std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang( + new CompilerInstance(PCHContainerOps)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> @@ -2389,7 +2414,7 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) { if (CompleteFileID == MainID && Line > 1) OverrideMainBuffer = getMainBufferWithPrecompiledPreamble( - *CCInvocation, false, Line - 1); + PCHContainerOps, *CCInvocation, false, Line - 1); } } } diff --git a/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp b/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp index f3677f8..be30d43 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -80,8 +80,9 @@ createASTReader(CompilerInstance &CI, StringRef pchFile, ASTDeserializationListener *deserialListener = nullptr) { Preprocessor &PP = CI.getPreprocessor(); std::unique_ptr<ASTReader> Reader; - Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"", - /*DisableValidation=*/true)); + Reader.reset(new ASTReader(PP, CI.getASTContext(), + *CI.getPCHContainerOperations(), + /*isysroot=*/"", /*DisableValidation=*/true)); for (unsigned ti = 0; ti < bufNames.size(); ++ti) { StringRef sr(bufNames[ti]); Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti])); @@ -145,7 +146,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient)); - std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); + std::unique_ptr<CompilerInstance> Clang( + new CompilerInstance(CI.getPCHContainerOperations())); Clang->setInvocation(CInvok.release()); Clang->setDiagnostics(Diags.get()); Clang->setTarget(TargetInfo::CreateTargetInfo( @@ -157,11 +159,9 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( &Clang->getPreprocessor()); Clang->createASTContext(); - SmallVector<char, 256> serialAST; - llvm::raw_svector_ostream OS(serialAST); - auto consumer = - llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr, - /*isysroot=*/"", &OS); + auto Buffer = std::make_shared<PCHBuffer>(); + auto consumer = llvm::make_unique<PCHGenerator>( + Clang->getPreprocessor(), "-", nullptr, /*isysroot=*/"", Buffer); Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); Clang->setASTConsumer(std::move(consumer)); @@ -198,7 +198,11 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( ParseAST(Clang->getSema()); Clang->getDiagnosticClient().EndSourceFile(); - SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str())); + assert(Buffer->IsComplete && "serialization did not complete"); + auto &serialAST = Buffer->Data; + SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy( + StringRef(serialAST.data(), serialAST.size()))); + serialAST.clear(); source->CIs.push_back(Clang.release()); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp index aef3905..6b0fed67 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp @@ -51,12 +51,13 @@ using namespace clang; -CompilerInstance::CompilerInstance(bool BuildingModule) - : ModuleLoader(BuildingModule), - Invocation(new CompilerInvocation()), ModuleManager(nullptr), - BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), - ModuleBuildFailed(false) { -} +CompilerInstance::CompilerInstance( + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + bool BuildingModule) + : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()), + ModuleManager(nullptr), ThePCHContainerOperations(PCHContainerOps), + BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), + ModuleBuildFailed(false) {} CompilerInstance::~CompilerInstance() { assert(OutputFiles.empty() && "Still output files in flight?"); @@ -321,7 +322,8 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { PP->getFileManager(), PPOpts); // Predefine macros and configure the preprocessor. - InitializePreprocessor(*PP, PPOpts, getFrontendOpts()); + InitializePreprocessor(*PP, PPOpts, *getPCHContainerOperations(), + getFrontendOpts()); // Initialize the header search object. ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), @@ -397,22 +399,24 @@ void CompilerInstance::createPCHExternalASTSource( ModuleManager = createPCHExternalASTSource( Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), - DeserializationListener, OwnDeserializationListener, Preamble, + *getPCHContainerOperations(), DeserializationListener, + OwnDeserializationListener, Preamble, getFrontendOpts().UseGlobalModuleIndex); } IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, + const PCHContainerOperations &PCHContainerOps, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex) { HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); - IntrusiveRefCntPtr<ASTReader> Reader( - new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(), - DisablePCHValidation, AllowPCHWithCompilerErrors, - /*AllowConfigurationMismatch*/ false, - HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); + IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( + PP, Context, PCHContainerOps, Sysroot.empty() ? "" : Sysroot.c_str(), + DisablePCHValidation, AllowPCHWithCompilerErrors, + /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders, + UseGlobalModuleIndex)); // We need the external source to be set up before we read the AST, because // eagerly-deserialized declarations may use it. @@ -918,7 +922,8 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, // Construct a compiler instance that will be used to actually create the // module. - CompilerInstance Instance(/*BuildingModule=*/true); + CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), + /*BuildingModule=*/true); Instance.setInvocation(&*Invocation); Instance.createDiagnostics(new ForwardingDiagnosticConsumer( @@ -1232,13 +1237,13 @@ void CompilerInstance::createModuleManager() { HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); std::string Sysroot = HSOpts.Sysroot; const PreprocessorOptions &PPOpts = getPreprocessorOpts(); - ModuleManager = new ASTReader(getPreprocessor(), *Context, - Sysroot.empty() ? "" : Sysroot.c_str(), - PPOpts.DisablePCHValidation, - /*AllowASTWithCompilerErrors=*/false, - /*AllowConfigurationMismatch=*/false, - HSOpts.ModulesValidateSystemHeaders, - getFrontendOpts().UseGlobalModuleIndex); + ModuleManager = new ASTReader( + getPreprocessor(), *Context, *getPCHContainerOperations(), + Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, + /*AllowASTWithCompilerErrors=*/false, + /*AllowConfigurationMismatch=*/false, + HSOpts.ModulesValidateSystemHeaders, + getFrontendOpts().UseGlobalModuleIndex); if (hasASTConsumer()) { ModuleManager->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); @@ -1279,6 +1284,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { ModuleFileStack.push_back(FileName); ModuleNameStack.push_back(StringRef()); if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(), + *CI.getPCHContainerOperations(), *this)) { CI.getDiagnostics().Report( SourceLocation(), CI.getFileManager().getBufferForFile(FileName) @@ -1644,8 +1650,8 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( llvm::sys::fs::create_directories( getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); GlobalModuleIndex::writeIndex( - getFileManager(), - getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + getFileManager(), *getPCHContainerOperations(), + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); ModuleManager->resetForReload(); ModuleManager->loadGlobalIndex(); GlobalIndex = ModuleManager->getGlobalIndex(); @@ -1672,8 +1678,8 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( } if (RecreateIndex) { GlobalModuleIndex::writeIndex( - getFileManager(), - getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + getFileManager(), *getPCHContainerOperations(), + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); ModuleManager->resetForReload(); ModuleManager->loadGlobalIndex(); GlobalIndex = ModuleManager->getGlobalIndex(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp index 4f7d15f..8546763 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp @@ -321,6 +321,29 @@ GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args, return Pattern; } +static bool parseDiagnosticLevelMask(StringRef FlagName, + const std::vector<std::string> &Levels, + DiagnosticsEngine *Diags, + DiagnosticLevelMask &M) { + bool Success = true; + for (const auto &Level : Levels) { + DiagnosticLevelMask const PM = + llvm::StringSwitch<DiagnosticLevelMask>(Level) + .Case("note", DiagnosticLevelMask::Note) + .Case("remark", DiagnosticLevelMask::Remark) + .Case("warning", DiagnosticLevelMask::Warning) + .Case("error", DiagnosticLevelMask::Error) + .Default(DiagnosticLevelMask::None); + if (PM == DiagnosticLevelMask::None) { + Success = false; + if (Diags) + Diags->Report(diag::err_drv_invalid_value) << FlagName << Level; + } + M = M | PM; + } + return Success; +} + static void parseSanitizerKinds(StringRef FlagName, const std::vector<std::string> &Sanitizers, DiagnosticsEngine &Diags, SanitizerSet &S) { @@ -532,8 +555,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fsanitize_coverage_8bit_counters); Opts.SanitizeMemoryTrackOrigins = getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags); - Opts.SanitizeUndefinedTrapOnError = - Args.hasArg(OPT_fsanitize_undefined_trap_on_error); Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); @@ -643,6 +664,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, parseSanitizerKinds("-fsanitize-recover=", Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags, Opts.SanitizeRecover); + parseSanitizerKinds("-fsanitize-trap=", + Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags, + Opts.SanitizeTrap); Opts.CudaGpuBinaryFileNames = Args.getAllArgValues(OPT_fcuda_include_gpubinary); @@ -748,11 +772,18 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, << Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args) << Format; } - + Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info); Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits); Opts.ShowPresumedLoc = !Args.hasArg(OPT_fno_diagnostics_use_presumed_location); Opts.VerifyDiagnostics = Args.hasArg(OPT_verify); + DiagnosticLevelMask DiagMask = DiagnosticLevelMask::None; + Success &= parseDiagnosticLevelMask("-verify-ignore-unexpected=", + Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), + Diags, DiagMask); + if (Args.hasArg(OPT_verify_ignore_unexpected)) + DiagMask = DiagnosticLevelMask::All; + Opts.setVerifyIgnoreUnexpected(DiagMask); Opts.ElideType = !Args.hasArg(OPT_fno_elide_type); Opts.ShowTemplateTree = Args.hasArg(OPT_fdiagnostics_show_template_tree); Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags); @@ -1065,8 +1096,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path); Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); - // -fmodules implies -fmodule-maps - Opts.ModuleMaps = Args.hasArg(OPT_fmodule_maps) || Args.hasArg(OPT_fmodules); + Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps); Opts.ModuleMapFileHomeIsCwd = Args.hasArg(OPT_fmodule_map_file_home_is_cwd); Opts.ModuleCachePruneInterval = getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60); @@ -1495,8 +1525,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, !Args.hasArg(OPT_fno_modules_search_all) && Args.hasArg(OPT_fmodules_search_all); Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery); - Opts.ModulesImplicitMaps = Args.hasFlag(OPT_fmodules_implicit_maps, - OPT_fno_modules_implicit_maps, true); Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); @@ -1803,7 +1831,7 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version); Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple)); - + Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ); // Use the default target triple if unspecified. if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getDefaultTargetTriple(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp index 9bba755..db9dd3b 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp @@ -191,7 +191,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); std::unique_ptr<ASTUnit> AST = - ASTUnit::LoadFromASTFile(InputFile, Diags, CI.getFileSystemOpts()); + ASTUnit::LoadFromASTFile(InputFile, CI.getPCHContainerOperations(), + Diags, CI.getFileSystemOpts()); if (!AST) goto failure; @@ -271,11 +272,10 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { // Check whether this is an acceptable AST file. - if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr, - CI.getLangOpts(), - CI.getTargetOpts(), - CI.getPreprocessorOpts(), - SpecificModuleCachePath)) { + if (ASTReader::isAcceptableASTFile( + Dir->path(), FileMgr, *CI.getPCHContainerOperations(), + CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), + SpecificModuleCachePath)) { PPOpts.ImplicitPCHInclude = Dir->path(); Found = true; break; @@ -443,8 +443,8 @@ bool FrontendAction::Execute() { if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() && CI.hasPreprocessor()) { GlobalModuleIndex::writeIndex( - CI.getFileManager(), - CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + CI.getFileManager(), *CI.getPCHContainerOperations(), + CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); } return true; diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp index 46cdeeb..6f202a1 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp @@ -14,6 +14,7 @@ #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/MultiplexConsumer.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Pragma.h" @@ -79,18 +80,28 @@ std::unique_ptr<ASTConsumer> GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; - raw_ostream *OS = + raw_pwrite_stream *OS = ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); if (!OS) return nullptr; if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); - return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile, - nullptr, Sysroot, OS); + + auto Buffer = std::make_shared<PCHBuffer>(); + std::vector<std::unique_ptr<ASTConsumer>> Consumers; + Consumers.push_back(llvm::make_unique<PCHGenerator>( + CI.getPreprocessor(), OutputFile, nullptr, Sysroot, Buffer)); + Consumers.push_back( + CI.getPCHContainerOperations()->CreatePCHContainerGenerator( + CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(), + InFile, OutputFile, OS, Buffer)); + + return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } -raw_ostream *GeneratePCHAction::ComputeASTConsumerArguments( +raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments( CompilerInstance &CI, StringRef InFile, std::string &Sysroot, std::string &OutputFile) { Sysroot = CI.getHeaderSearchOpts().Sysroot; @@ -102,7 +113,7 @@ raw_ostream *GeneratePCHAction::ComputeASTConsumerArguments( // We use createOutputFile here because this is exposed via libclang, and we // must disable the RemoveFileOnSignal behavior. // We use a temporary to avoid race conditions. - raw_ostream *OS = + raw_pwrite_stream *OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, /*RemoveFileOnSignal=*/false, InFile, /*Extension=*/"", /*useTemporary=*/true); @@ -118,13 +129,21 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; - raw_ostream *OS = + raw_pwrite_stream *OS = ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); if (!OS) return nullptr; - return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile, - Module, Sysroot, OS); + auto Buffer = std::make_shared<PCHBuffer>(); + std::vector<std::unique_ptr<ASTConsumer>> Consumers; + Consumers.push_back(llvm::make_unique<PCHGenerator>( + CI.getPreprocessor(), OutputFile, Module, Sysroot, Buffer)); + Consumers.push_back( + CI.getPCHContainerOperations()->CreatePCHContainerGenerator( + CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(), + InFile, OutputFile, OS, Buffer)); + return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } static SmallVectorImpl<char> & @@ -348,7 +367,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, return true; } -raw_ostream *GenerateModuleAction::ComputeASTConsumerArguments( +raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments( CompilerInstance &CI, StringRef InFile, std::string &Sysroot, std::string &OutputFile) { // If no output file was provided, figure out where this module would go @@ -363,7 +382,7 @@ raw_ostream *GenerateModuleAction::ComputeASTConsumerArguments( // We use createOutputFile here because this is exposed via libclang, and we // must disable the RemoveFileOnSignal behavior. // We use a temporary to avoid race conditions. - raw_ostream *OS = + raw_pwrite_stream *OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, /*RemoveFileOnSignal=*/false, InFile, /*Extension=*/"", /*useTemporary=*/true, @@ -395,13 +414,13 @@ void VerifyPCHAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot; - std::unique_ptr<ASTReader> Reader( - new ASTReader(CI.getPreprocessor(), CI.getASTContext(), - Sysroot.empty() ? "" : Sysroot.c_str(), - /*DisableValidation*/ false, - /*AllowPCHWithCompilerErrors*/ false, - /*AllowConfigurationMismatch*/ true, - /*ValidateSystemInputs*/ true)); + std::unique_ptr<ASTReader> Reader(new ASTReader( + CI.getPreprocessor(), CI.getASTContext(), *CI.getPCHContainerOperations(), + Sysroot.empty() ? "" : Sysroot.c_str(), + /*DisableValidation*/ false, + /*AllowPCHWithCompilerErrors*/ false, + /*AllowConfigurationMismatch*/ true, + /*ValidateSystemInputs*/ true)); Reader->ReadAST(getCurrentFile(), Preamble ? serialization::MK_Preamble @@ -550,9 +569,9 @@ void DumpModuleInfoAction::ExecuteAction() { Out << "Information for module file '" << getCurrentFile() << "':\n"; DumpModuleInfoListener Listener(Out); - ASTReader::readASTFileControlBlock(getCurrentFile(), - getCompilerInstance().getFileManager(), - Listener); + ASTReader::readASTFileControlBlock( + getCurrentFile(), getCompilerInstance().getFileManager(), + *getCompilerInstance().getPCHContainerOperations(), Listener); } //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp index dfc46f4..2417146 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp @@ -97,10 +97,11 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP, /// \brief Add an implicit \#include using the original file used to generate /// a PCH file. static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP, + const PCHContainerOperations &PCHContainerOps, StringRef ImplicitIncludePCH) { std::string OriginalFile = - ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(), - PP.getDiagnostics()); + ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(), + PCHContainerOps, PP.getDiagnostics()); if (OriginalFile.empty()) return; @@ -891,9 +892,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, /// InitializePreprocessor - Initialize the preprocessor getting it and the /// environment ready to process a single file. This returns true on error. /// -void clang::InitializePreprocessor(Preprocessor &PP, - const PreprocessorOptions &InitOpts, - const FrontendOptions &FEOpts) { +void clang::InitializePreprocessor( + Preprocessor &PP, const PreprocessorOptions &InitOpts, + const PCHContainerOperations &PCHContainerOps, + const FrontendOptions &FEOpts) { const LangOptions &LangOpts = PP.getLangOpts(); std::string PredefineBuffer; PredefineBuffer.reserve(4080); @@ -952,7 +954,8 @@ void clang::InitializePreprocessor(Preprocessor &PP, // Process -include-pch/-include-pth directives. if (!InitOpts.ImplicitPCHInclude.empty()) - AddImplicitIncludePCH(Builder, PP, InitOpts.ImplicitPCHInclude); + AddImplicitIncludePCH(Builder, PP, PCHContainerOps, + InitOpts.ImplicitPCHInclude); if (!InitOpts.ImplicitPTHInclude.empty()) AddImplicitIncludePTH(Builder, PP, InitOpts.ImplicitPTHInclude); diff --git a/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp b/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp index 219e949..a53f4d2 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp @@ -33,11 +33,13 @@ public: void ReaderInitialized(ASTReader *Reader) override; void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; + void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; void DeclRead(serialization::DeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD) override; + void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override; private: std::vector<ASTDeserializationListener *> Listeners; @@ -60,6 +62,12 @@ void MultiplexASTDeserializationListener::IdentifierRead( Listeners[i]->IdentifierRead(ID, II); } +void MultiplexASTDeserializationListener::MacroRead( + serialization::MacroID ID, MacroInfo *MI) { + for (auto &Listener : Listeners) + Listener->MacroRead(ID, MI); +} + void MultiplexASTDeserializationListener::TypeRead( serialization::TypeIdx Idx, QualType T) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) @@ -84,6 +92,12 @@ void MultiplexASTDeserializationListener::MacroDefinitionRead( Listeners[i]->MacroDefinitionRead(ID, MD); } +void MultiplexASTDeserializationListener::ModuleRead( + serialization::SubmoduleID ID, Module *Mod) { + for (auto &Listener : Listeners) + Listener->ModuleRead(ID, Mod); +} + // This ASTMutationListener forwards its notifications to a set of // child listeners. class MultiplexASTMutationListener : public ASTMutationListener { @@ -99,6 +113,7 @@ public: const VarTemplateSpecializationDecl *D) override; void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D) override; + void ResolvedExceptionSpec(const FunctionDecl *FD) override; void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; void ResolvedOperatorDelete(const CXXDestructorDecl *DD, const FunctionDecl *Delete) override; @@ -106,6 +121,7 @@ public: void StaticDataMemberInstantiated(const VarDecl *D) override; void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, const ObjCInterfaceDecl *IFD) override; + void FunctionDefinitionInstantiated(const FunctionDecl *D) override; void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, const ObjCPropertyDecl *OrigProp, const ObjCCategoryDecl *ClassExt) override; @@ -153,6 +169,11 @@ void MultiplexASTMutationListener::AddedCXXTemplateSpecialization( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->AddedCXXTemplateSpecialization(TD, D); } +void MultiplexASTMutationListener::ResolvedExceptionSpec( + const FunctionDecl *FD) { + for (auto &Listener : Listeners) + Listener->ResolvedExceptionSpec(FD); +} void MultiplexASTMutationListener::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) @@ -179,6 +200,11 @@ void MultiplexASTMutationListener::AddedObjCCategoryToInterface( for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->AddedObjCCategoryToInterface(CatD, IFD); } +void MultiplexASTMutationListener::FunctionDefinitionInstantiated( + const FunctionDecl *D) { + for (auto &Listener : Listeners) + Listener->FunctionDefinitionInstantiated(D); +} void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension( const ObjCPropertyDecl *Prop, const ObjCPropertyDecl *OrigProp, diff --git a/contrib/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp b/contrib/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp new file mode 100644 index 0000000..fd3278b --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Frontend/PCHContainerOperations.cpp @@ -0,0 +1,70 @@ +//===--- Frontend/PCHContainerOperations.cpp - PCH Containers ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines PCHContainerOperations and RawPCHContainerOperation. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/AST/ASTConsumer.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/raw_ostream.h" +#include "clang/Lex/ModuleLoader.h" +using namespace clang; + +PCHContainerOperations::~PCHContainerOperations() {} + +namespace { + +/// \brief A PCHContainerGenerator that writes out the PCH to a flat file. +class PCHContainerGenerator : public ASTConsumer { + std::shared_ptr<PCHBuffer> Buffer; + raw_pwrite_stream *OS; + +public: + PCHContainerGenerator(DiagnosticsEngine &Diags, + const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, const TargetOptions &TO, + const LangOptions &LO, const std::string &MainFileName, + const std::string &OutputFileName, + llvm::raw_pwrite_stream *OS, + std::shared_ptr<PCHBuffer> Buffer) + : Buffer(Buffer), OS(OS) {} + + virtual ~PCHContainerGenerator() {} + + void HandleTranslationUnit(ASTContext &Ctx) override { + if (Buffer->IsComplete) { + // Make sure it hits disk now. + *OS << Buffer->Data; + OS->flush(); + } + // Free the space of the temporary buffer. + llvm::SmallVector<char, 0> Empty; + Buffer->Data = std::move(Empty); + } +}; +} + +std::unique_ptr<ASTConsumer> +RawPCHContainerOperations::CreatePCHContainerGenerator( + DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, const TargetOptions &TO, + const LangOptions &LO, const std::string &MainFileName, + const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, + std::shared_ptr<PCHBuffer> Buffer) const { + return llvm::make_unique<PCHContainerGenerator>( + Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer); +} + +void RawPCHContainerOperations::ExtractPCH( + llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { + StreamFile.init((const unsigned char *)Buffer.getBufferStart(), + (const unsigned char *)Buffer.getBufferEnd()); +} diff --git a/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 6192554..a58c935 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -562,8 +562,13 @@ struct UnknownPragmaHandler : public PragmaHandler { const char *Prefix; PrintPPOutputPPCallbacks *Callbacks; - UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks) - : Prefix(prefix), Callbacks(callbacks) {} + // Set to true if tokens should be expanded + bool ShouldExpandTokens; + + UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks, + bool RequireTokenExpansion) + : Prefix(prefix), Callbacks(callbacks), + ShouldExpandTokens(RequireTokenExpansion) {} void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &PragmaTok) override { // Figure out what line we went to and insert the appropriate number of @@ -571,16 +576,24 @@ struct UnknownPragmaHandler : public PragmaHandler { Callbacks->startNewLineIfNeeded(); Callbacks->MoveToLine(PragmaTok.getLocation()); Callbacks->OS.write(Prefix, strlen(Prefix)); + + Token PrevToken; + Token PrevPrevToken; + PrevToken.startToken(); + PrevPrevToken.startToken(); + // Read and print all of the pragma tokens. while (PragmaTok.isNot(tok::eod)) { - if (PragmaTok.hasLeadingSpace()) + if (PragmaTok.hasLeadingSpace() || + Callbacks->AvoidConcat(PrevPrevToken, PrevToken, PragmaTok)) Callbacks->OS << ' '; std::string TokSpell = PP.getSpelling(PragmaTok); Callbacks->OS.write(&TokSpell[0], TokSpell.size()); - // Expand macros in pragmas with -fms-extensions. The assumption is that - // the majority of pragmas in such a file will be Microsoft pragmas. - if (PP.getLangOpts().MicrosoftExt) + PrevPrevToken = PrevToken; + PrevToken = PragmaTok; + + if (ShouldExpandTokens) PP.Lex(PragmaTok); else PP.LexUnexpandedToken(PragmaTok); @@ -718,10 +731,29 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks( PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.UseLineDirectives); - PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks)); - PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",Callbacks)); - PP.AddPragmaHandler("clang", - new UnknownPragmaHandler("#pragma clang", Callbacks)); + + // Expand macros in pragmas with -fms-extensions. The assumption is that + // the majority of pragmas in such a file will be Microsoft pragmas. + PP.AddPragmaHandler(new UnknownPragmaHandler( + "#pragma", Callbacks, + /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); + PP.AddPragmaHandler( + "GCC", new UnknownPragmaHandler( + "#pragma GCC", Callbacks, + /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); + PP.AddPragmaHandler( + "clang", new UnknownPragmaHandler( + "#pragma clang", Callbacks, + /*RequireTokenExpansion=*/PP.getLangOpts().MicrosoftExt)); + + // The tokens after pragma omp need to be expanded. + // + // OpenMP [2.1, Directive format] + // Preprocessing tokens following the #pragma omp are subject to macro + // replacement. + PP.AddPragmaHandler("omp", + new UnknownPragmaHandler("#pragma omp", Callbacks, + /*RequireTokenExpansion=*/true)); PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks)); diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp index a3e14f9..dc787ac 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp @@ -81,6 +81,13 @@ bool FixItRewriter::WriteFixedFiles( RewritesReceiver Rec(Rewrite); Editor.applyRewrites(Rec); + if (FixItOpts->InPlace) { + // Overwriting open files on Windows is tricky, but the rewriter can do it + // for us. + Rewrite.overwriteChangedFiles(); + return false; + } + for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) { const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first); int fd; diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp index 1b5eb28..dbc661b 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -48,9 +48,10 @@ FixItAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { namespace { class FixItRewriteInPlace : public FixItOptions { public: + FixItRewriteInPlace() { InPlace = true; } + std::string RewriteFilename(const std::string &Filename, int &fd) override { - fd = -1; - return Filename; + llvm_unreachable("don't call RewriteFilename for inplace rewrites"); } }; diff --git a/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index 910e394..55df936 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -691,7 +691,8 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, const char *Label, DirectiveList &Left, const_diag_iterator d2_begin, - const_diag_iterator d2_end) { + const_diag_iterator d2_end, + bool IgnoreUnexpected) { std::vector<Directive *> LeftOnly; DiagList Right(d2_begin, d2_end); @@ -727,7 +728,8 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, } // Now all that's left in Right are those that were not matched. unsigned num = PrintExpected(Diags, SourceMgr, LeftOnly, Label); - num += PrintUnexpected(Diags, &SourceMgr, Right.begin(), Right.end(), Label); + if (!IgnoreUnexpected) + num += PrintUnexpected(Diags, &SourceMgr, Right.begin(), Right.end(), Label); return num; } @@ -745,21 +747,28 @@ static unsigned CheckResults(DiagnosticsEngine &Diags, SourceManager &SourceMgr, // Seen \ Expected - set seen but not expected unsigned NumProblems = 0; + const DiagnosticLevelMask DiagMask = + Diags.getDiagnosticOptions().getVerifyIgnoreUnexpected(); + // See if there are error mismatches. NumProblems += CheckLists(Diags, SourceMgr, "error", ED.Errors, - Buffer.err_begin(), Buffer.err_end()); + Buffer.err_begin(), Buffer.err_end(), + bool(DiagnosticLevelMask::Error & DiagMask)); // See if there are warning mismatches. NumProblems += CheckLists(Diags, SourceMgr, "warning", ED.Warnings, - Buffer.warn_begin(), Buffer.warn_end()); + Buffer.warn_begin(), Buffer.warn_end(), + bool(DiagnosticLevelMask::Warning & DiagMask)); // See if there are remark mismatches. NumProblems += CheckLists(Diags, SourceMgr, "remark", ED.Remarks, - Buffer.remark_begin(), Buffer.remark_end()); + Buffer.remark_begin(), Buffer.remark_end(), + bool(DiagnosticLevelMask::Remark & DiagMask)); // See if there are note mismatches. NumProblems += CheckLists(Diags, SourceMgr, "note", ED.Notes, - Buffer.note_begin(), Buffer.note_end()); + Buffer.note_begin(), Buffer.note_end(), + bool(DiagnosticLevelMask::Note & DiagMask)); return NumProblems; } @@ -854,12 +863,20 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() { // Check that the expected diagnostics occurred. NumErrors += CheckResults(Diags, *SrcManager, *Buffer, ED); } else { - NumErrors += (PrintUnexpected(Diags, nullptr, Buffer->err_begin(), - Buffer->err_end(), "error") + - PrintUnexpected(Diags, nullptr, Buffer->warn_begin(), - Buffer->warn_end(), "warn") + - PrintUnexpected(Diags, nullptr, Buffer->note_begin(), - Buffer->note_end(), "note")); + const DiagnosticLevelMask DiagMask = + ~Diags.getDiagnosticOptions().getVerifyIgnoreUnexpected(); + if (bool(DiagnosticLevelMask::Error & DiagMask)) + NumErrors += PrintUnexpected(Diags, nullptr, Buffer->err_begin(), + Buffer->err_end(), "error"); + if (bool(DiagnosticLevelMask::Warning & DiagMask)) + NumErrors += PrintUnexpected(Diags, nullptr, Buffer->warn_begin(), + Buffer->warn_end(), "warn"); + if (bool(DiagnosticLevelMask::Remark & DiagMask)) + NumErrors += PrintUnexpected(Diags, nullptr, Buffer->remark_begin(), + Buffer->remark_end(), "remark"); + if (bool(DiagnosticLevelMask::Note & DiagMask)) + NumErrors += PrintUnexpected(Diags, nullptr, Buffer->note_begin(), + Buffer->note_end(), "note"); } Diags.setClient(CurClient, Owner.release() != nullptr); |