diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend')
31 files changed, 1708 insertions, 1003 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp index 54a6d47..f53c614 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp @@ -57,7 +57,8 @@ namespace { bool ShowColors = Out.has_colors(); if (ShowColors) Out.changeColor(raw_ostream::BLUE); - Out << (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n"; + Out << ((Dump || DumpLookups) ? "Dumping " : "Printing ") << getName(D) + << ":\n"; if (ShowColors) Out.resetColor(); print(D); @@ -79,9 +80,13 @@ namespace { } void print(Decl *D) { if (DumpLookups) { - if (DeclContext *DC = dyn_cast<DeclContext>(D)) - DC->dumpLookups(Out); - else + if (DeclContext *DC = dyn_cast<DeclContext>(D)) { + if (DC == DC->getPrimaryContext()) + DC->dumpLookups(Out, Dump); + else + Out << "Lookup map is in primary DeclContext " + << DC->getPrimaryContext() << "\n"; + } else Out << "Not a DeclContext\n"; } else if (Dump) D->dump(Out); @@ -118,17 +123,21 @@ namespace { }; } // end anonymous namespace -ASTConsumer *clang::CreateASTPrinter(raw_ostream *Out, - StringRef FilterString) { - return new ASTPrinter(Out, /*Dump=*/ false, FilterString); +std::unique_ptr<ASTConsumer> clang::CreateASTPrinter(raw_ostream *Out, + StringRef FilterString) { + return llvm::make_unique<ASTPrinter>(Out, /*Dump=*/false, FilterString); } -ASTConsumer *clang::CreateASTDumper(StringRef FilterString, bool DumpLookups) { - return new ASTPrinter(nullptr, /*Dump=*/true, FilterString, DumpLookups); +std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString, + bool DumpDecls, + bool DumpLookups) { + assert((DumpDecls || DumpLookups) && "nothing to dump"); + return llvm::make_unique<ASTPrinter>(nullptr, DumpDecls, FilterString, + DumpLookups); } -ASTConsumer *clang::CreateASTDeclNodeLister() { - return new ASTDeclNodeLister(nullptr); +std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() { + return llvm::make_unique<ASTDeclNodeLister>(nullptr); } //===----------------------------------------------------------------------===// @@ -164,8 +173,9 @@ void ASTViewer::HandleTopLevelSingleDecl(Decl *D) { } } - -ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); } +std::unique_ptr<ASTConsumer> clang::CreateASTViewer() { + return llvm::make_unique<ASTViewer>(); +} //===----------------------------------------------------------------------===// /// DeclContextPrinter - Decl and DeclContext Visualization @@ -475,6 +485,6 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, } } } -ASTConsumer *clang::CreateDeclContextPrinter() { - return new DeclContextPrinter(); +std::unique_ptr<ASTConsumer> clang::CreateDeclContextPrinter() { + return llvm::make_unique<DeclContextPrinter>(); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp index ff6434c..216ac6a 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTMerge.cpp @@ -16,8 +16,8 @@ using namespace clang; -ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { return AdaptedAction->CreateASTConsumer(CI, InFile); } @@ -45,8 +45,8 @@ void ASTMergeAction::ExecuteAction() { new ForwardingDiagnosticConsumer( *CI.getDiagnostics().getClient()), /*ShouldOwnClient=*/true)); - ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, - CI.getFileSystemOpts(), false); + std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile( + ASTFiles[I], Diags, CI.getFileSystemOpts(), false); if (!Unit) continue; @@ -66,8 +66,6 @@ void ASTMergeAction::ExecuteAction() { Importer.Import(D); } - - delete Unit; } AdaptedAction->ExecuteAction(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp index fc44d9f..a3998fa 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ASTUnit.cpp @@ -105,7 +105,8 @@ static llvm::sys::SmartMutex<false> &getOnDiskMutex() { static void cleanupOnDiskMapAtExit(); -typedef llvm::DenseMap<const ASTUnit *, OnDiskData *> OnDiskDataMap; +typedef llvm::DenseMap<const ASTUnit *, + std::unique_ptr<OnDiskData>> OnDiskDataMap; static OnDiskDataMap &getOnDiskDataMap() { static OnDiskDataMap M; static bool hasRegisteredAtExit = false; @@ -132,9 +133,9 @@ static OnDiskData &getOnDiskData(const ASTUnit *AU) { // DenseMap. llvm::MutexGuard Guard(getOnDiskMutex()); OnDiskDataMap &M = getOnDiskDataMap(); - OnDiskData *&D = M[AU]; + auto &D = M[AU]; if (!D) - D = new OnDiskData(); + D = llvm::make_unique<OnDiskData>(); return *D; } @@ -150,7 +151,6 @@ static void removeOnDiskEntry(const ASTUnit *AU) { OnDiskDataMap::iterator I = M.find(AU); if (I != M.end()) { I->second->Cleanup(); - delete I->second; M.erase(AU); } } @@ -219,8 +219,8 @@ ASTUnit::ASTUnit(bool _MainFileIsAST) TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), OwnsRemappedFileBuffers(true), NumStoredDiagnosticsFromDriver(0), - PreambleRebuildCounter(0), SavedMainFileBuffer(nullptr), - PreambleBuffer(nullptr), NumWarningsInPreamble(0), + PreambleRebuildCounter(0), + NumWarningsInPreamble(0), ShouldCacheCodeCompletionResults(false), IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false), CompletionCacheTopLevelHashValue(0), @@ -251,9 +251,6 @@ ASTUnit::~ASTUnit() { for (const auto &RB : PPOpts.RemappedFileBuffers) delete RB.second; } - - delete SavedMainFileBuffer; - delete PreambleBuffer; ClearCachedCompletionResults(); @@ -511,8 +508,8 @@ public: : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts), Target(Target), Counter(Counter), InitializedLanguage(false) {} - bool ReadLanguageOptions(const LangOptions &LangOpts, - bool Complain) override { + bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, + bool AllowCompatibleDifferences) override { if (InitializedLanguage) return false; @@ -592,6 +589,7 @@ class CaptureDroppedDiagnostics { DiagnosticsEngine &Diags; StoredDiagnosticConsumer Client; DiagnosticConsumer *PreviousClient; + std::unique_ptr<DiagnosticConsumer> OwningPreviousClient; public: CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags, @@ -599,16 +597,15 @@ public: : Diags(Diags), Client(StoredDiags), PreviousClient(nullptr) { if (RequestCapture || Diags.getClient() == nullptr) { - PreviousClient = Diags.takeClient(); - Diags.setClient(&Client); + OwningPreviousClient = Diags.takeClient(); + PreviousClient = Diags.getClient(); + Diags.setClient(&Client, false); } } ~CaptureDroppedDiagnostics() { - if (Diags.getClient() == &Client) { - Diags.takeClient(); - Diags.setClient(PreviousClient); - } + if (Diags.getClient() == &Client) + Diags.setClient(PreviousClient, !!OwningPreviousClient.release()); } }; @@ -638,38 +635,30 @@ ASTDeserializationListener *ASTUnit::getDeserializationListener() { return nullptr; } -llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, - std::string *ErrorStr) { +std::unique_ptr<llvm::MemoryBuffer> +ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) { assert(FileMgr); - return FileMgr->getBufferForFile(Filename, ErrorStr); + auto Buffer = FileMgr->getBufferForFile(Filename); + if (Buffer) + return std::move(*Buffer); + if (ErrorStr) + *ErrorStr = Buffer.getError().message(); + return nullptr; } /// \brief Configure the diagnostics object for use with ASTUnit. -void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, - const char **ArgBegin, const char **ArgEnd, +void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, ASTUnit &AST, bool CaptureDiagnostics) { - if (!Diags.get()) { - // No diagnostics engine was provided, so create our own diagnostics object - // with the default options. - DiagnosticConsumer *Client = nullptr; - if (CaptureDiagnostics) - Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); - Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(), - Client, - /*ShouldOwnClient=*/true); - } else if (CaptureDiagnostics) { + assert(Diags.get() && "no DiagnosticsEngine was provided"); + if (CaptureDiagnostics) Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); - } } -ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - const FileSystemOptions &FileSystemOpts, - bool OnlyLocalDecls, - ArrayRef<RemappedFile> RemappedFiles, - bool CaptureDiagnostics, - bool AllowPCHWithCompilerErrors, - bool UserFilesAreVolatile) { +std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( + const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, + ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics, + bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) { std::unique_ptr<ASTUnit> AST(new ASTUnit(true)); // Recover resources if we crash before exiting this method. @@ -679,7 +668,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > DiagCleanup(Diags.get()); - ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); + ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; @@ -705,7 +694,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, // Gather Info for preprocessor construction later on. - HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); + HeaderSearch &HeaderInfo = *AST->HeaderInfo; unsigned Counter; AST->PP = @@ -728,10 +717,9 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, /*DisableValidation=*/disableValid, AllowPCHWithCompilerErrors); - AST->Reader->setListener(new ASTInfoCollector(*AST->PP, Context, - AST->ASTFileLangOpts, - AST->TargetOpts, AST->Target, - Counter)); + AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>( + *AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target, + Counter)); switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile, SourceLocation(), ASTReader::ARR_None)) { @@ -768,7 +756,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, // Tell the diagnostic client that we have started a source file. AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP); - return AST.release(); + return AST; } namespace { @@ -891,12 +879,13 @@ class TopLevelDeclTrackerAction : public ASTFrontendAction { public: ASTUnit &Unit; - ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override { + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override { CI.getPreprocessor().addPPCallbacks( - new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); - return new TopLevelDeclTrackerConsumer(Unit, - Unit.getCurrentTopLevelHashValue()); + llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( + Unit.getCurrentTopLevelHashValue())); + return llvm::make_unique<TopLevelDeclTrackerConsumer>( + Unit, Unit.getCurrentTopLevelHashValue()); } public: @@ -916,8 +905,8 @@ public: explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit), HasEmittedPreamblePCH(false) {} - ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; } void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; } bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); } @@ -979,8 +968,9 @@ public: } -ASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { std::string Sysroot; std::string OutputFile; raw_ostream *OS = nullptr; @@ -991,10 +981,11 @@ ASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI, if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); - CI.getPreprocessor().addPPCallbacks(new MacroDefinitionTrackerPPCallbacks( - Unit.getCurrentTopLevelHashValue())); - return new PrecompilePreambleConsumer(Unit, this, CI.getPreprocessor(), - Sysroot, OS); + CI.getPreprocessor().addPPCallbacks( + llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( + Unit.getCurrentTopLevelHashValue())); + return llvm::make_unique<PrecompilePreambleConsumer>( + Unit, this, CI.getPreprocessor(), Sysroot, OS); } static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) { @@ -1031,15 +1022,12 @@ 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(llvm::MemoryBuffer *OverrideMainBuffer) { - delete SavedMainFileBuffer; - SavedMainFileBuffer = nullptr; +bool ASTUnit::Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) { + SavedMainFileBuffer.reset(); - if (!Invocation) { - delete OverrideMainBuffer; + if (!Invocation) return true; - } - + // Create the compiler instance to use for building the AST. std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); @@ -1060,10 +1048,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // Create the target instance. Clang->setTarget(TargetInfo::CreateTargetInfo( Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); - if (!Clang->hasTarget()) { - delete OverrideMainBuffer; + if (!Clang->hasTarget()) return true; - } // Inform the target of the language options. // @@ -1083,10 +1069,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { FileSystemOpts = Clang->getFileSystemOpts(); IntrusiveRefCntPtr<vfs::FileSystem> VFS = createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics()); - if (!VFS) { - delete OverrideMainBuffer; + if (!VFS) return true; - } FileMgr = new FileManager(FileSystemOpts, VFS); SourceMgr = new SourceManager(getDiagnostics(), *FileMgr, UserFilesAreVolatile); @@ -1115,7 +1099,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // make that override happen and introduce the preamble. PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts(); if (OverrideMainBuffer) { - PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); + PreprocessorOpts.addRemappedFile(OriginalSourceFile, + OverrideMainBuffer.get()); PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); PreprocessorOpts.PrecompiledPreambleBytes.second = PreambleEndsAtStartOfLine; @@ -1130,7 +1115,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { checkAndSanitizeDiags(StoredDiagnostics, getSourceManager()); // Keep track of the override buffer; - SavedMainFileBuffer = OverrideMainBuffer; + SavedMainFileBuffer = std::move(OverrideMainBuffer); } std::unique_ptr<TopLevelDeclTrackerAction> Act( @@ -1143,7 +1128,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) goto error; - if (OverrideMainBuffer) { + if (SavedMainFileBuffer) { std::string ModName = getPreambleFile(this); TranslateStoredDiagnostics(getFileManager(), getSourceManager(), PreambleDiagnostics, StoredDiagnostics); @@ -1162,10 +1147,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { error: // Remove the overridden buffer we used for the preamble. - if (OverrideMainBuffer) { - delete OverrideMainBuffer; - SavedMainFileBuffer = nullptr; - } + SavedMainFileBuffer = nullptr; // Keep the ownership of the data in the ASTUnit because the client may // want to see the diagnostics. @@ -1194,17 +1176,16 @@ static std::string GetPreamblePCHPath() { /// \brief Compute the preamble for the main file, providing the source buffer /// that corresponds to the main file along with a pair (bytes, start-of-line) /// that describes the preamble. -std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > -ASTUnit::ComputePreamble(CompilerInvocation &Invocation, - unsigned MaxLines, bool &CreatedBuffer) { +ASTUnit::ComputedPreamble +ASTUnit::ComputePreamble(CompilerInvocation &Invocation, unsigned MaxLines) { FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts(); - CreatedBuffer = false; // 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 = nullptr; + std::unique_ptr<llvm::MemoryBuffer> BufferOwner; std::string MainFilePath(FrontendOpts.Inputs[0].getFile()); llvm::sys::fs::UniqueID MainFileID; if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) { @@ -1215,15 +1196,9 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, if (!llvm::sys::fs::getUniqueID(MPath, MID)) { if (MainFileID == MID) { // We found a remapping. Try to load the resulting, remapped source. - if (CreatedBuffer) { - delete Buffer; - CreatedBuffer = false; - } - - Buffer = getBufferForFile(RF.second); - if (!Buffer) - return std::make_pair(nullptr, std::make_pair(0, true)); - CreatedBuffer = true; + BufferOwner = getBufferForFile(RF.second); + if (!BufferOwner) + return ComputedPreamble(nullptr, nullptr, 0, true); } } } @@ -1236,11 +1211,7 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, if (!llvm::sys::fs::getUniqueID(MPath, MID)) { if (MainFileID == MID) { // We found a remapping. - if (CreatedBuffer) { - delete Buffer; - CreatedBuffer = false; - } - + BufferOwner.reset(); Buffer = const_cast<llvm::MemoryBuffer *>(RB.second); } } @@ -1248,17 +1219,18 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, } // If the main source file was not remapped, load it now. - if (!Buffer) { - Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile()); - if (!Buffer) - return std::make_pair(nullptr, std::make_pair(0, true)); - - CreatedBuffer = true; + if (!Buffer && !BufferOwner) { + BufferOwner = getBufferForFile(FrontendOpts.Inputs[0].getFile()); + if (!BufferOwner) + return ComputedPreamble(nullptr, nullptr, 0, true); } - - return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, - *Invocation.getLangOpts(), - MaxLines)); + + if (!Buffer) + Buffer = BufferOwner.get(); + auto Pre = Lexer::ComputePreamble(Buffer->getBuffer(), + *Invocation.getLangOpts(), MaxLines); + return ComputedPreamble(Buffer, std::move(BufferOwner), Pre.first, + Pre.second); } ASTUnit::PreambleFileHash @@ -1300,42 +1272,44 @@ makeStandaloneRange(CharSourceRange Range, const SourceManager &SM, return std::make_pair(Offset, EndOffset); } -static void makeStandaloneFixIt(const SourceManager &SM, - const LangOptions &LangOpts, - const FixItHint &InFix, - ASTUnit::StandaloneFixIt &OutFix) { +static ASTUnit::StandaloneFixIt 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; + return OutFix; } -static void makeStandaloneDiagnostic(const LangOptions &LangOpts, - const StoredDiagnostic &InDiag, - ASTUnit::StandaloneDiagnostic &OutDiag) { +static ASTUnit::StandaloneDiagnostic +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; + return OutDiag; const SourceManager &SM = InDiag.getLocation().getManager(); SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation()); OutDiag.Filename = SM.getFilename(FileLoc); if (OutDiag.Filename.empty()) - return; + return OutDiag; 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); - } + for (StoredDiagnostic::fixit_iterator I = InDiag.fixit_begin(), + E = InDiag.fixit_end(); + I != E; ++I) + OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, *I)); + + return OutDiag; } /// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing @@ -1358,27 +1332,20 @@ static void makeStandaloneDiagnostic(const LangOptions &LangOpts, /// \returns If the precompiled preamble can be used, returns a newly-allocated /// buffer that should be used in place of the main file when doing so. /// Otherwise, returns a NULL pointer. -llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( - const CompilerInvocation &PreambleInvocationIn, - bool AllowRebuild, - unsigned MaxLines) { - +std::unique_ptr<llvm::MemoryBuffer> +ASTUnit::getMainBufferWithPrecompiledPreamble( + const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild, + unsigned MaxLines) { + IntrusiveRefCntPtr<CompilerInvocation> PreambleInvocation(new CompilerInvocation(PreambleInvocationIn)); FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts(); PreprocessorOptions &PreprocessorOpts = PreambleInvocation->getPreprocessorOpts(); - bool CreatedPreambleBuffer = false; - std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble - = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); - - // If ComputePreamble() Take ownership of the preamble buffer. - std::unique_ptr<llvm::MemoryBuffer> OwnedPreambleBuffer; - if (CreatedPreambleBuffer) - OwnedPreambleBuffer.reset(NewPreamble.first); + ComputedPreamble NewPreamble = ComputePreamble(*PreambleInvocation, MaxLines); - if (!NewPreamble.second.first) { + if (!NewPreamble.Size) { // We couldn't find a preamble in the main source. Clear out the current // preamble, if we have one. It's obviously no good any more. Preamble.clear(); @@ -1394,10 +1361,10 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // preamble now that we did before, and that there's enough space in // the main-file buffer within the precompiled preamble to fit the // new main file. - if (Preamble.size() == NewPreamble.second.first && - PreambleEndsAtStartOfLine == NewPreamble.second.second && - memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(), - NewPreamble.second.first) == 0) { + if (Preamble.size() == NewPreamble.Size && + PreambleEndsAtStartOfLine == NewPreamble.PreambleEndsAtStartOfLine && + memcmp(Preamble.getBufferStart(), NewPreamble.Buffer->getBufferStart(), + NewPreamble.Size) == 0) { // The preamble has not changed. We may be able to re-use the precompiled // preamble. @@ -1467,7 +1434,7 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( getDiagnostics().setNumWarnings(NumWarningsInPreamble); return llvm::MemoryBuffer::getMemBufferCopy( - NewPreamble.first->getBuffer(), FrontendOpts.Inputs[0].getFile()); + NewPreamble.Buffer->getBuffer(), FrontendOpts.Inputs[0].getFile()); } } @@ -1512,19 +1479,16 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // subsequent reparses. StringRef MainFilename = FrontendOpts.Inputs[0].getFile(); Preamble.assign(FileMgr->getFile(MainFilename), - NewPreamble.first->getBufferStart(), - NewPreamble.first->getBufferStart() - + NewPreamble.second.first); - PreambleEndsAtStartOfLine = NewPreamble.second.second; + NewPreamble.Buffer->getBufferStart(), + NewPreamble.Buffer->getBufferStart() + NewPreamble.Size); + PreambleEndsAtStartOfLine = NewPreamble.PreambleEndsAtStartOfLine; - delete PreambleBuffer; - PreambleBuffer - = llvm::MemoryBuffer::getMemBufferCopy( - NewPreamble.first->getBuffer().slice(0, Preamble.size()), MainFilename); + PreambleBuffer = llvm::MemoryBuffer::getMemBufferCopy( + NewPreamble.Buffer->getBuffer().slice(0, Preamble.size()), MainFilename); // Remap the main source file to the preamble buffer. StringRef MainFilePath = FrontendOpts.Inputs[0].getFile(); - PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer); + PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer.get()); // Tell the compiler invocation to generate a temporary precompiled header. FrontendOpts.ProgramAction = frontend::GeneratePCH; @@ -1607,13 +1571,11 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( // 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); - } + for (stored_diag_iterator I = stored_diag_afterDriver_begin(), + E = stored_diag_end(); + I != E; ++I) + PreambleDiagnostics.push_back( + makeStandaloneDiagnostic(Clang->getLangOpts(), *I)); Act->EndSourceFile(); @@ -1663,8 +1625,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( CompletionCacheTopLevelHashValue = 0; PreambleTopLevelHashValue = CurrentTopLevelHashValue; } - - return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.first->getBuffer(), + + return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.Buffer->getBuffer(), MainFilename); } @@ -1688,8 +1650,8 @@ void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) { // created. assert(CI.hasInvocation() && "missing invocation"); LangOpts = CI.getInvocation().LangOpts; - TheSema.reset(CI.takeSema()); - Consumer.reset(CI.takeASTConsumer()); + TheSema = CI.takeSema(); + Consumer = CI.takeASTConsumer(); if (CI.hasASTContext()) Ctx = &CI.getASTContext(); if (CI.hasPreprocessor()) @@ -1735,7 +1697,7 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI, bool UserFilesAreVolatile) { std::unique_ptr<ASTUnit> AST; AST.reset(new ASTUnit(false)); - ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); + ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; AST->Invocation = CI; AST->FileSystemOpts = CI->getFileSystemOpts(); @@ -1862,13 +1824,15 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( if (Persistent && !TrackerAct) { Clang->getPreprocessor().addPPCallbacks( - new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue())); - std::vector<ASTConsumer*> Consumers; + llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( + AST->getCurrentTopLevelHashValue())); + std::vector<std::unique_ptr<ASTConsumer>> Consumers; if (Clang->hasASTConsumer()) Consumers.push_back(Clang->takeASTConsumer()); - Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST, - AST->getCurrentTopLevelHashValue())); - Clang->setASTConsumer(new MultiplexConsumer(Consumers)); + Consumers.push_back(llvm::make_unique<TopLevelDeclTrackerConsumer>( + *AST, AST->getCurrentTopLevelHashValue())); + Clang->setASTConsumer( + llvm::make_unique<MultiplexConsumer>(std::move(Consumers))); } if (!Act->Execute()) { AST->transferASTDataFromCompilerInstance(*Clang); @@ -1898,11 +1862,10 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { Invocation->getFrontendOpts().DisableFree = false; ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); - llvm::MemoryBuffer *OverrideMainBuffer = nullptr; + std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (PrecompilePreamble) { PreambleRebuildCounter = 2; - OverrideMainBuffer - = getMainBufferWithPrecompiledPreamble(*Invocation); + OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); } SimpleTimer ParsingTimer(WantTiming); @@ -1910,9 +1873,9 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> - MemBufferCleanup(OverrideMainBuffer); - - return Parse(OverrideMainBuffer); + MemBufferCleanup(OverrideMainBuffer.get()); + + return Parse(std::move(OverrideMainBuffer)); } std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( @@ -1922,7 +1885,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation( bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) { // Create the AST unit. std::unique_ptr<ASTUnit> AST(new ASTUnit(false)); - ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics); + ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; @@ -1961,11 +1924,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine( 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()); - } + assert(Diags.get() && "no DiagnosticsEngine was provided"); SmallVector<StoredDiagnostic, 4> StoredDiagnostics; @@ -2000,9 +1959,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine( // Create the AST unit. std::unique_ptr<ASTUnit> AST; AST.reset(new ASTUnit(false)); - ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); + ConfigureDiags(Diags, *AST, CaptureDiagnostics); AST->Diagnostics = Diags; - Diags = nullptr; // Zero out now to ease cleanup during crash recovery. AST->FileSystemOpts = CI->getFileSystemOpts(); IntrusiveRefCntPtr<vfs::FileSystem> VFS = createVFSFromCompilerInvocation(*CI, *Diags); @@ -2021,7 +1979,9 @@ ASTUnit *ASTUnit::LoadFromCommandLine( AST->Invocation = CI; if (ForSerialization) AST->WriterData.reset(new ASTWriterData()); - CI = nullptr; // Zero out now to ease cleanup during crash recovery. + // Zero out now to ease cleanup during crash recovery. + CI = nullptr; + Diags = nullptr; // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> @@ -2062,7 +2022,7 @@ bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) { // If we have a preamble file lying around, or if we might try to // build a precompiled preamble, do so now. - llvm::MemoryBuffer *OverrideMainBuffer = nullptr; + std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0) OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); @@ -2073,8 +2033,8 @@ bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) { getDiagnostics().setNumWarnings(NumWarningsInPreamble); // Parse the sources - bool Result = Parse(OverrideMainBuffer); - + bool Result = Parse(std::move(OverrideMainBuffer)); + // If we're caching global code-completion results, and the top-level // declarations have changed, clear out the code-completion cache. if (!Result && ShouldCacheCodeCompletionResults && @@ -2366,6 +2326,10 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // Set the language options appropriately. LangOpts = *CCInvocation->getLangOpts(); + // Spell-checking and warnings are wasteful during code-completion. + LangOpts.SpellChecking = false; + CCInvocation->getDiagnosticOpts().IgnoreWarnings = true; + std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); // Recover resources if we crash before exiting this method. @@ -2427,7 +2391,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 = nullptr; + std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer; if (!getPreambleFile(this).empty()) { std::string CompleteFilePath(File); llvm::sys::fs::UniqueID CompleteFileID; @@ -2437,9 +2401,8 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, llvm::sys::fs::UniqueID MainID; if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) { if (CompleteFileID == MainID && Line > 1) - OverrideMainBuffer - = getMainBufferWithPrecompiledPreamble(*CCInvocation, false, - Line - 1); + OverrideMainBuffer = getMainBufferWithPrecompiledPreamble( + *CCInvocation, false, Line - 1); } } } @@ -2447,14 +2410,15 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, // If the main file has been overridden due to the use of a preamble, // make that override happen and introduce the preamble. if (OverrideMainBuffer) { - PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); + PreprocessorOpts.addRemappedFile(OriginalSourceFile, + OverrideMainBuffer.get()); PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); PreprocessorOpts.PrecompiledPreambleBytes.second = PreambleEndsAtStartOfLine; PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this); PreprocessorOpts.DisablePCHValidation = true; - - OwnedBuffers.push_back(OverrideMainBuffer); + + OwnedBuffers.push_back(OverrideMainBuffer.release()); } else { PreprocessorOpts.PrecompiledPreambleBytes.first = 0; PreprocessorOpts.PrecompiledPreambleBytes.second = false; @@ -2821,7 +2785,8 @@ struct PCHLocatorInfo { static bool PCHLocator(serialization::ModuleFile &M, void *UserData) { PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData); switch (M.Kind) { - case serialization::MK_Module: + case serialization::MK_ImplicitModule: + case serialization::MK_ExplicitModule: return true; // skip dependencies. case serialization::MK_PCH: Info.Mod = &M; diff --git a/contrib/llvm/tools/clang/lib/Frontend/CacheTokens.cpp b/contrib/llvm/tools/clang/lib/Frontend/CacheTokens.cpp index 14f7027..d909d52 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CacheTokens.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CacheTokens.cpp @@ -270,17 +270,17 @@ void PTHWriter::EmitToken(const Token& T) { StringRef s(T.getLiteralData(), T.getLength()); // Get the string entry. - llvm::StringMapEntry<OffsetOpt> *E = &CachedStrs.GetOrCreateValue(s); + auto &E = *CachedStrs.insert(std::make_pair(s, OffsetOpt())).first; // If this is a new string entry, bump the PTH offset. - if (!E->getValue().hasOffset()) { - E->getValue().setOffset(CurStrOffset); - StrEntries.push_back(E); + if (!E.second.hasOffset()) { + E.second.setOffset(CurStrOffset); + StrEntries.push_back(&E); CurStrOffset += s.size() + 1; } // Emit the relative offset into the PTH file for the spelling string. - Emit32(E->getValue().getOffset()); + Emit32(E.second.getOffset()); } // Emit the offset into the original source file of this token so that we @@ -572,8 +572,10 @@ void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) { PTHWriter PW(*OS, PP); // Install the 'stat' system call listener in the FileManager. - StatListener *StatCache = new StatListener(PW.getPM()); - PP.getFileManager().addStatCache(StatCache, /*AtBeginning=*/true); + auto StatCacheOwner = llvm::make_unique<StatListener>(PW.getPM()); + StatListener *StatCache = StatCacheOwner.get(); + PP.getFileManager().addStatCache(std::move(StatCacheOwner), + /*AtBeginning=*/true); // Lex through the entire file. This will populate SourceManager with // all of the header information. diff --git a/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp b/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp index e6e73ac..cb260b4 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -74,7 +74,7 @@ protected: static ASTReader * createASTReader(CompilerInstance &CI, StringRef pchFile, - SmallVectorImpl<llvm::MemoryBuffer *> &memBufs, + SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &MemBufs, SmallVectorImpl<std::string> &bufNames, ASTDeserializationListener *deserialListener = nullptr) { Preprocessor &PP = CI.getPreprocessor(); @@ -83,7 +83,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile, /*DisableValidation=*/true)); for (unsigned ti = 0; ti < bufNames.size(); ++ti) { StringRef sr(bufNames[ti]); - Reader->addInMemoryBuffer(sr, memBufs[ti]); + Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti])); } Reader->setDeserializationListener(deserialListener); switch (Reader->ReadAST(pchFile, serialization::MK_PCH, SourceLocation(), @@ -118,7 +118,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource()); InputKind IK = CI.getFrontendOpts().Inputs[0].getKind(); - SmallVector<llvm::MemoryBuffer *, 4> serialBufs; + SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> SerialBufs; SmallVector<std::string, 4> serialBufNames; for (unsigned i = 0, e = includes.size(); i != e; ++i) { @@ -158,12 +158,12 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( SmallVector<char, 256> serialAST; llvm::raw_svector_ostream OS(serialAST); - std::unique_ptr<ASTConsumer> consumer; - consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", nullptr, - /*isysroot=*/"", &OS)); + auto consumer = + llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr, + /*isysroot=*/"", &OS); Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); - Clang->setASTConsumer(consumer.release()); + Clang->setASTConsumer(std::move(consumer)); Clang->createSema(TU_Prefix, nullptr); if (firstInclude) { @@ -171,20 +171,21 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); } else { - assert(!serialBufs.empty()); - SmallVector<llvm::MemoryBuffer *, 4> bufs; + assert(!SerialBufs.empty()); + SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> Bufs; // TODO: Pass through the existing MemoryBuffer instances instead of // allocating new ones. - for (auto *SB : serialBufs) - bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer())); + for (auto &SB : SerialBufs) + Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer())); std::string pchName = includes[i-1]; llvm::raw_string_ostream os(pchName); os << ".pch" << i-1; serialBufNames.push_back(os.str()); IntrusiveRefCntPtr<ASTReader> Reader; - Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, - Clang->getASTConsumer().GetASTDeserializationListener()); + Reader = createASTReader( + *Clang, pchName, Bufs, serialBufNames, + Clang->getASTConsumer().GetASTDeserializationListener()); if (!Reader) return nullptr; Clang->setModuleManager(Reader); @@ -196,14 +197,14 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( ParseAST(Clang->getSema()); Clang->getDiagnosticClient().EndSourceFile(); - serialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str())); + SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str())); source->CIs.push_back(Clang.release()); } - assert(!serialBufs.empty()); + assert(!SerialBufs.empty()); std::string pchName = includes.back() + ".pch-final"; serialBufNames.push_back(pchName); - Reader = createASTReader(CI, pchName, serialBufs, serialBufNames); + Reader = createASTReader(CI, pchName, SerialBufs, serialBufNames); if (!Reader) return nullptr; diff --git a/contrib/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp b/contrib/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp new file mode 100644 index 0000000..75ee47f --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Frontend/CodeGenOptions.cpp @@ -0,0 +1,24 @@ +//===--- CodeGenOptions.cpp -----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/CodeGenOptions.h" +#include <string.h> + +namespace clang { + +CodeGenOptions::CodeGenOptions() { +#define CODEGENOPT(Name, Bits, Default) Name = Default; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default); +#include "clang/Frontend/CodeGenOptions.def" + + RelocationModel = "pic"; + memcpy(CoverageVersion, "402*", 4); +} + +} // end namespace clang diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp index 6af920d..93a34b7 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp @@ -101,14 +101,18 @@ void CompilerInstance::setSema(Sema *S) { TheSema.reset(S); } -void CompilerInstance::setASTConsumer(ASTConsumer *Value) { - Consumer.reset(Value); +void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { + Consumer = std::move(Value); } void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { CompletionConsumer.reset(Value); } - + +std::unique_ptr<Sema> CompilerInstance::takeSema() { + return std::move(TheSema); +} + IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { return ModuleManager; } @@ -130,52 +134,48 @@ void CompilerInstance::setModuleDepCollector( static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, const CodeGenOptions *CodeGenOpts, DiagnosticsEngine &Diags) { - std::string ErrorInfo; - bool OwnsStream = false; + std::error_code EC; + std::unique_ptr<raw_ostream> StreamOwner; raw_ostream *OS = &llvm::errs(); if (DiagOpts->DiagnosticLogFile != "-") { // Create the output stream. - llvm::raw_fd_ostream *FileOS(new llvm::raw_fd_ostream( - DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo, - llvm::sys::fs::F_Append | llvm::sys::fs::F_Text)); - if (!ErrorInfo.empty()) { + auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( + DiagOpts->DiagnosticLogFile, EC, + llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); + if (EC) { Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) - << DiagOpts->DiagnosticLogFile << ErrorInfo; + << DiagOpts->DiagnosticLogFile << EC.message(); } else { FileOS->SetUnbuffered(); FileOS->SetUseAtomicWrites(true); - OS = FileOS; - OwnsStream = true; + OS = FileOS.get(); + StreamOwner = std::move(FileOS); } } // Chain in the diagnostic client which will log the diagnostics. - LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts, - OwnsStream); + auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, + std::move(StreamOwner)); if (CodeGenOpts) Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); - Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); + assert(Diags.ownsClient()); + Diags.setClient( + new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); } static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, DiagnosticsEngine &Diags, StringRef OutputFile) { - std::string ErrorInfo; - std::unique_ptr<llvm::raw_fd_ostream> OS; - OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo, - llvm::sys::fs::F_None)); + auto SerializedConsumer = + clang::serialized_diags::create(OutputFile, DiagOpts); - if (!ErrorInfo.empty()) { - Diags.Report(diag::warn_fe_serialized_diag_failure) - << OutputFile << ErrorInfo; - return; + if (Diags.ownsClient()) { + Diags.setClient(new ChainedDiagnosticConsumer( + Diags.takeClient(), std::move(SerializedConsumer))); + } else { + Diags.setClient(new ChainedDiagnosticConsumer( + Diags.getClient(), std::move(SerializedConsumer))); } - - DiagnosticConsumer *SerializedConsumer = - clang::serialized_diags::create(OS.release(), DiagOpts); - - Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), - SerializedConsumer)); } void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, @@ -371,6 +371,14 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"", /*ShowDepth=*/true, /*MSStyle=*/true); } + + // Load all explictly-specified module map files. + for (const auto &Filename : getFrontendOpts().ModuleMapFiles) { + if (auto *File = getFileManager().getFile(Filename)) + PP->getHeaderSearchInfo().loadModuleMapFile(File, /*IsSystem*/false); + else + getDiagnostics().Report(diag::err_module_map_not_found) << Filename; + } } // ASTContext @@ -569,17 +577,14 @@ CompilerInstance::createOutputFile(StringRef OutputPath, StringRef Extension, bool UseTemporary, bool CreateMissingDirectories) { - std::string Error, OutputPathName, TempPathName; - llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary, - RemoveFileOnSignal, - InFile, Extension, - UseTemporary, - CreateMissingDirectories, - &OutputPathName, - &TempPathName); + std::string OutputPathName, TempPathName; + std::error_code EC; + llvm::raw_fd_ostream *OS = createOutputFile( + OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, + UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); if (!OS) { - getDiagnostics().Report(diag::err_fe_unable_to_open_output) - << OutputPath << Error; + getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath + << EC.message(); return nullptr; } @@ -591,17 +596,11 @@ CompilerInstance::createOutputFile(StringRef OutputPath, return OS; } -llvm::raw_fd_ostream * -CompilerInstance::createOutputFile(StringRef OutputPath, - std::string &Error, - bool Binary, - bool RemoveFileOnSignal, - StringRef InFile, - StringRef Extension, - bool UseTemporary, - bool CreateMissingDirectories, - std::string *ResultPathName, - std::string *TempPathName) { +llvm::raw_fd_ostream *CompilerInstance::createOutputFile( + StringRef OutputPath, std::error_code &Error, bool Binary, + bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, + bool UseTemporary, bool CreateMissingDirectories, + std::string *ResultPathName, std::string *TempPathName) { assert((!CreateMissingDirectories || UseTemporary) && "CreateMissingDirectories is only allowed when using temporary files"); @@ -670,9 +669,9 @@ CompilerInstance::createOutputFile(StringRef OutputPath, if (!OS) { OSFile = OutFile; OS.reset(new llvm::raw_fd_ostream( - OSFile.c_str(), Error, + OSFile, Error, (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); - if (!Error.empty()) + if (Error) return nullptr; } @@ -705,7 +704,8 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; if (Input.isBuffer()) { - SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind)); + SourceMgr.setMainFileID(SourceMgr.createFileID( + std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind)); assert(!SourceMgr.getMainFileID().isInvalid() && "Couldn't establish MainFileID!"); return true; @@ -727,14 +727,14 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, // pick up the correct size, and simply override their contents as we do for // STDIN. if (File->isNamedPipe()) { - std::string ErrorStr; - if (llvm::MemoryBuffer *MB = - FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) { + auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true); + if (MB) { // Create a new virtual file that will have the correct size. - File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); - SourceMgr.overrideFileContents(File, MB); + File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0); + SourceMgr.overrideFileContents(File, std::move(*MB)); } else { - Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr; + Diags.Report(diag::err_cannot_open_file) << InputFile + << MB.getError().message(); return false; } } @@ -754,7 +754,7 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, SB->getBufferSize(), 0); SourceMgr.setMainFileID( SourceMgr.createFileID(File, SourceLocation(), Kind)); - SourceMgr.overrideFileContents(File, SB.release()); + SourceMgr.overrideFileContents(File, std::move(SB)); } assert(!SourceMgr.getMainFileID().isInvalid() && @@ -802,8 +802,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { llvm::EnableStatistics(); for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { - // Reset the ID tables if we are reusing the SourceManager. - if (hasSourceManager()) + // Reset the ID tables if we are reusing the SourceManager and parsing + // regular files. + if (hasSourceManager() && !Act.isModelParsingAction()) getSourceManager().clearIDTables(); if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { @@ -951,17 +952,22 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, FrontendOpts.Inputs.push_back( FrontendInputFile("__inferred_module.map", IK)); - llvm::MemoryBuffer *ModuleMapBuffer = + std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); ModuleMapFile = Instance.getFileManager().getVirtualFile( "__inferred_module.map", InferredModuleMapContent.size(), 0); - SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer); + SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer)); } - // Construct a module-generating action. Passing through Module->ModuleMap is + // Construct a module-generating action. Passing through the module map is // safe because the FileManager is shared between the compiler instances. - GenerateModuleAction CreateModuleAction(Module->ModuleMap, Module->IsSystem); - + GenerateModuleAction CreateModuleAction( + ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem); + + ImportingInstance.getDiagnostics().Report(ImportLoc, + diag::remark_module_build) + << Module->Name << ModuleFileName; + // Execute the action to actually build the module in-place. Use a separate // thread so that we get a stack large enough. const unsigned ThreadStackSize = 8 << 20; @@ -969,6 +975,10 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); }, ThreadStackSize); + ImportingInstance.getDiagnostics().Report(ImportLoc, + diag::remark_module_build_done) + << Module->Name; + // Delete the temporary module map file. // FIXME: Even though we're executing under crash protection, it would still // be nice to do this with RemoveFileOnSignal when we can. However, that @@ -988,9 +998,10 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName) { + DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); + auto diagnoseBuildFailure = [&] { - ImportingInstance.getDiagnostics().Report(ModuleNameLoc, - diag::err_module_not_built) + Diags.Report(ModuleNameLoc, diag::err_module_not_built) << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); }; @@ -1004,6 +1015,8 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: + Diags.Report(ModuleNameLoc, diag::err_module_lock_failure) + << Module->Name; return false; case llvm::LockFileManager::LFS_Owned: @@ -1027,7 +1040,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, // Try to read the module file, now that we've compiled it. ASTReader::ASTReadResult ReadResult = ImportingInstance.getModuleManager()->ReadAST( - ModuleFileName, serialization::MK_Module, ImportLoc, + ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, ModuleLoadCapabilities); if (ReadResult == ASTReader::OutOfDate && @@ -1038,6 +1051,10 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, continue; } else if (ReadResult == ASTReader::Missing) { diagnoseBuildFailure(); + } else if (ReadResult != ASTReader::Success && + !Diags.hasErrorOccurred()) { + // The ASTReader didn't diagnose the error, so conservatively report it. + diagnoseBuildFailure(); } return ReadResult == ASTReader::Success; } @@ -1131,9 +1148,8 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, /// \brief Write a new timestamp file with the given path. static void writeTimestampFile(StringRef TimestampFile) { - std::string ErrorInfo; - llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo, - llvm::sys::fs::F_None); + std::error_code EC; + llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); } /// \brief Prune the module cache of modules that haven't been accessed in @@ -1251,6 +1267,65 @@ void CompilerInstance::createModuleManager() { } } +bool CompilerInstance::loadModuleFile(StringRef FileName) { + // Helper to recursively read the module names for all modules we're adding. + // We mark these as known and redirect any attempt to load that module to + // the files we were handed. + struct ReadModuleNames : ASTReaderListener { + CompilerInstance &CI; + std::vector<StringRef> ModuleFileStack; + bool Failed; + bool TopFileIsModule; + + ReadModuleNames(CompilerInstance &CI) + : CI(CI), Failed(false), TopFileIsModule(false) {} + + bool needsImportVisitation() const override { return true; } + + void visitImport(StringRef FileName) override { + ModuleFileStack.push_back(FileName); + if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(), + *this)) { + CI.getDiagnostics().Report(SourceLocation(), + diag::err_module_file_not_found) + << FileName; + // FIXME: Produce a note stack explaining how we got here. + Failed = true; + } + ModuleFileStack.pop_back(); + } + + void ReadModuleName(StringRef ModuleName) override { + if (ModuleFileStack.size() == 1) + TopFileIsModule = true; + + auto &ModuleFile = CI.ModuleFileOverrides[ModuleName]; + if (!ModuleFile.empty() && + CI.getFileManager().getFile(ModuleFile) != + CI.getFileManager().getFile(ModuleFileStack.back())) + CI.getDiagnostics().Report(SourceLocation(), + diag::err_conflicting_module_files) + << ModuleName << ModuleFile << ModuleFileStack.back(); + ModuleFile = ModuleFileStack.back(); + } + } RMN(*this); + + RMN.visitImport(FileName); + + if (RMN.Failed) + return false; + + // If we never found a module name for the top file, then it's not a module, + // it's a PCH or preamble or something. + if (!RMN.TopFileIsModule) { + getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module) + << FileName; + return false; + } + + return true; +} + ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, @@ -1265,7 +1340,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // when both the preprocessor and parser see the same import declaration. if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. - if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) + if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule && + ModuleName != getLangOpts().ImplementationOfModule) ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, ImportLoc, /*Complain=*/false); return LastModuleImportResult; @@ -1279,7 +1355,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, if (Known != KnownModules.end()) { // Retrieve the cached top-level module. Module = Known->second; - } else if (ModuleName == getLangOpts().CurrentModule) { + } else if (ModuleName == getLangOpts().CurrentModule || + ModuleName == getLangOpts().ImplementationOfModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; @@ -1294,8 +1371,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return ModuleLoadResult(); } + auto Override = ModuleFileOverrides.find(ModuleName); + bool Explicit = Override != ModuleFileOverrides.end(); + std::string ModuleFileName = - PP->getHeaderSearchInfo().getModuleFileName(Module); + Explicit ? Override->second + : PP->getHeaderSearchInfo().getModuleFileName(Module); // If we don't already have an ASTReader, create one now. if (!ModuleManager) @@ -1311,14 +1392,24 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Listener->attachToASTReader(*ModuleManager); // Try to load the module file. - unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; - switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, + unsigned ARRFlags = + Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; + switch (ModuleManager->ReadAST(ModuleFileName, + Explicit ? serialization::MK_ExplicitModule + : serialization::MK_ImplicitModule, ImportLoc, ARRFlags)) { case ASTReader::Success: break; case ASTReader::OutOfDate: case ASTReader::Missing: { + if (Explicit) { + // ReadAST has already complained for us. + ModuleLoader::HadFatalFailure = true; + KnownModules[Path[0].first] = nullptr; + return ModuleLoadResult(); + } + // The module file is missing or out-of-date. Build it. assert(Module && "missing module file"); // Check whether there is a cycle in the module graph. @@ -1342,9 +1433,6 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return ModuleLoadResult(); } - getDiagnostics().Report(ImportLoc, diag::remark_module_build) - << ModuleName << ModuleFileName; - // Check whether we have already attempted to build this module (but // failed). if (getPreprocessorOpts().FailedModules && @@ -1359,6 +1447,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Try to compile and then load the module. if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, ModuleFileName)) { + assert(getDiagnostics().hasErrorOccurred() && + "undiagnosed error in compileAndLoadModule"); if (getPreprocessorOpts().FailedModules) getPreprocessorOpts().FailedModules->addFailed(ModuleName); KnownModules[Path[0].first] = nullptr; @@ -1448,6 +1538,10 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Module = Sub; } } + + // Don't make the module visible if we are in the implementation. + if (ModuleName == getLangOpts().ImplementationOfModule) + return ModuleLoadResult(Module, false); // Make the named module visible, if it's not already part of the module // we are parsing. @@ -1468,7 +1562,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Check whether this module is available. clang::Module::Requirement Requirement; - clang::Module::HeaderDirective MissingHeader; + clang::Module::UnresolvedHeaderDirective MissingHeader; if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement, MissingHeader)) { if (MissingHeader.FileNameLoc.isValid()) { @@ -1497,9 +1591,16 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Module, ImportLoc); } + // Determine whether we're in the #include buffer for a module. The #includes + // in that buffer do not qualify as module imports; they're just an + // implementation detail of us building the module. + bool IsInModuleIncludes = !getLangOpts().CurrentModule.empty() && + getSourceManager().getFileID(ImportLoc) == + getSourceManager().getMainFileID(); + // If this module import was due to an inclusion directive, create an // implicit import declaration to capture it in the AST. - if (IsInclusionDirective && hasASTContext()) { + if (IsInclusionDirective && hasASTContext() && !IsInModuleIncludes) { TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, ImportLoc, Module, @@ -1602,3 +1703,4 @@ CompilerInstance::lookupMissingImports(StringRef Name, return false; } +void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp index 7b94132..54025b0 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp @@ -10,6 +10,7 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/Version.h" +#include "clang/Config/config.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Driver/Util.h" @@ -19,8 +20,8 @@ #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Serialization/ASTReader.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" @@ -215,6 +216,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help); + Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks); + Opts.visualizeExplodedGraphWithGraphViz = Args.hasArg(OPT_analyzer_viz_egraph_graphviz); Opts.visualizeExplodedGraphWithUbiGraph = @@ -322,21 +325,38 @@ GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args, return Pattern; } +static void parseSanitizerKinds(StringRef FlagName, + const std::vector<std::string> &Sanitizers, + DiagnosticsEngine &Diags, SanitizerSet &S) { + for (const auto &Sanitizer : Sanitizers) { + SanitizerKind K = llvm::StringSwitch<SanitizerKind>(Sanitizer) +#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID) +#include "clang/Basic/Sanitizers.def" + .Default(SanitizerKind::Unknown); + if (K == SanitizerKind::Unknown) + Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer; + else + S.set(K, true); + } +} + static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags, const TargetOptions &TargetOpts) { using namespace options; bool Success = true; - Opts.OptimizationLevel = getOptimizationLevel(Args, IK, Diags); + unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags); // TODO: This could be done in Driver unsigned MaxOptLevel = 3; - if (Opts.OptimizationLevel > MaxOptLevel) { - // If the optimization level is not supported, fall back on the default optimization + if (OptimizationLevel > MaxOptLevel) { + // If the optimization level is not supported, fall back on the default + // optimization Diags.Report(diag::warn_drv_optimization_value) << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel; - Opts.OptimizationLevel = MaxOptLevel; + OptimizationLevel = MaxOptLevel; } + Opts.OptimizationLevel = OptimizationLevel; // We must always run at least the always inlining pass. Opts.setInlining( @@ -399,6 +419,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ); Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate); Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ); + Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping); + Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping); Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device); @@ -413,16 +435,19 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable); Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || - Args.hasArg(OPT_cl_finite_math_only)|| + Args.hasArg(OPT_cl_finite_math_only) || Args.hasArg(OPT_cl_fast_relaxed_math)); Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) || - Args.hasArg(OPT_cl_finite_math_only)|| + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_finite_math_only) || Args.hasArg(OPT_cl_fast_relaxed_math)); + Opts.NoSignedZeros = Args.hasArg(OPT_cl_no_signed_zeros); Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); Opts.BackendOptions = Args.getAllArgValues(OPT_backend_option); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoGlobalMerge = Args.hasArg(OPT_mno_global_merge); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); + Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings); Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks); Opts.RelaxAll = Args.hasArg(OPT_mrelax_all); Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer); @@ -435,6 +460,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic"); + Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix"); + if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") + Diags.Report(diag::err_drv_invalid_value) + << Args.getLastArg(OPT_mthread_model)->getAsString(Args) + << Opts.ThreadModel; Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ); Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array); @@ -442,6 +472,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, OPT_fno_function_sections, false); Opts.DataSections = Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false); + Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions); Opts.VectorizeBB = Args.hasArg(OPT_vectorize_slp_aggressive); Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops); @@ -449,13 +480,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); - Opts.SanitizeRecover = !Args.hasArg(OPT_fno_sanitize_recover); Opts.DisableGCov = Args.hasArg(OPT_test_coverage); Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) { - Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file); + Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file); Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum); Opts.CoverageNoFunctionNamesInData = Args.hasArg(OPT_coverage_no_function_names_in_data); @@ -477,7 +507,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections); Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file); - Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist); + Opts.SanitizeCoverage = + getLastArgIntValue(Args, OPT_fsanitize_coverage, 0, Diags); Opts.SanitizeMemoryTrackOrigins = getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags); Opts.SanitizeUndefinedTrapOnError = @@ -566,11 +597,25 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, NeedLocTracking = true; } - // If the user requested one of the flags in the -Rpass family, make sure - // that the backend tracks source location information. + // If the user requested to use a sample profile for PGO, then the + // backend will need to track source location information so the profile + // can be incorporated into the IR. + if (!Opts.SampleProfileFile.empty()) + NeedLocTracking = true; + + // If the user requested a flag that requires source locations available in + // the backend, make sure that the backend tracks source location information. if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo) Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly); + Opts.RewriteMapFiles = Args.getAllArgValues(OPT_frewrite_map_file); + + // Parse -fsanitize-recover= arguments. + // FIXME: Report unrecoverable sanitizers incorrectly specified here. + parseSanitizerKinds("-fsanitize-recover=", + Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags, + Opts.SanitizeRecover); + return Success; } @@ -597,8 +642,9 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, bool Success = true; Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file); - Opts.DiagnosticSerializationFile = - Args.getLastArgValue(OPT_diagnostic_serialized_file); + if (Arg *A = + Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags)) + Opts.DiagnosticSerializationFile = A->getValue(); Opts.IgnoreWarnings = Args.hasArg(OPT_w); Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros); Opts.Pedantic = Args.hasArg(OPT_pedantic); @@ -686,6 +732,9 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.ConstexprBacktraceLimit = getLastArgIntValue( Args, OPT_fconstexpr_backtrace_limit, DiagnosticOptions::DefaultConstexprBacktraceLimit, Diags); + Opts.SpellCheckingLimit = getLastArgIntValue( + Args, OPT_fspell_checking_limit, + DiagnosticOptions::DefaultSpellCheckingLimit, Diags); Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop, DiagnosticOptions::DefaultTabStop, Diags); if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) { @@ -716,6 +765,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, case OPT_ast_list: Opts.ProgramAction = frontend::ASTDeclList; break; case OPT_ast_dump: + case OPT_ast_dump_lookups: Opts.ProgramAction = frontend::ASTDump; break; case OPT_ast_print: Opts.ProgramAction = frontend::ASTPrint; break; @@ -823,11 +873,14 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings); Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile); Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp); + Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump); Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter); Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups); Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index); Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex; - + Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file); + Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file); + Opts.CodeCompleteOpts.IncludeMacros = Args.hasArg(OPT_code_completion_macros); Opts.CodeCompleteOpts.IncludeCodePatterns @@ -866,6 +919,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals; if (Args.hasArg(OPT_objcmt_migrate_subscripting)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting; + if (Args.hasArg(OPT_objcmt_migrate_property_dot_syntax)) + Opts.ObjCMTAction |= FrontendOptions::ObjCMT_PropertyDotSyntax; if (Args.hasArg(OPT_objcmt_migrate_property)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property; if (Args.hasArg(OPT_objcmt_migrate_readonly_property)) @@ -950,14 +1005,19 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, std::string CompilerInvocation::GetResourcesPath(const char *Argv0, void *MainAddr) { - SmallString<128> P(llvm::sys::fs::getMainExecutable(Argv0, MainAddr)); - - if (!P.empty()) { - llvm::sys::path::remove_filename(P); // Remove /clang from foo/bin/clang - llvm::sys::path::remove_filename(P); // Remove /bin from foo/bin - - // Get foo/lib/clang/<version>/include - llvm::sys::path::append(P, "lib", "clang", CLANG_VERSION_STRING); + std::string ClangExecutable = + llvm::sys::fs::getMainExecutable(Argv0, MainAddr); + StringRef Dir = llvm::sys::path::parent_path(ClangExecutable); + + // Compute the path to the resource directory. + StringRef ClangResourceDir(CLANG_RESOURCE_DIR); + SmallString<128> P(Dir); + if (ClangResourceDir != "") { + llvm::sys::path::append(P, ClangResourceDir); + } else { + StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX); + llvm::sys::path::append(P, "..", Twine("lib") + ClangLibdirSuffix, "clang", + CLANG_VERSION_STRING); } return P.str(); @@ -978,6 +1038,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); // -fmodules implies -fmodule-maps Opts.ModuleMaps = Args.hasArg(OPT_fmodule_maps) || Args.hasArg(OPT_fmodules); + Opts.ModuleMapFileHomeIsCwd = Args.hasArg(OPT_fmodule_map_file_home_is_cwd); Opts.ModuleCachePruneInterval = getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60); Opts.ModuleCachePruneAfter = @@ -995,9 +1056,6 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { StringRef MacroDef = (*it)->getValue(); Opts.ModulesIgnoreMacros.insert(MacroDef.split('=').first); } - std::vector<std::string> ModuleMapFiles = - Args.getAllArgValues(OPT_fmodule_map_file); - Opts.ModuleMapFiles.insert(ModuleMapFiles.begin(), ModuleMapFiles.end()); // Add -I..., -F..., and -index-header-map options in order. bool IsIndexHeaderMap = false; @@ -1118,7 +1176,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, case IK_PreprocessedC: case IK_ObjC: case IK_PreprocessedObjC: - LangStd = LangStandard::lang_gnu99; + LangStd = LangStandard::lang_gnu11; break; case IK_CXX: case IK_PreprocessedCXX: @@ -1135,7 +1193,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.C11 = Std.isC11(); Opts.CPlusPlus = Std.isCPlusPlus(); Opts.CPlusPlus11 = Std.isCPlusPlus11(); - Opts.CPlusPlus1y = Std.isCPlusPlus1y(); + Opts.CPlusPlus14 = Std.isCPlusPlus14(); Opts.CPlusPlus1z = Std.isCPlusPlus1z(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); @@ -1148,10 +1206,12 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, if (LangStd == LangStandard::lang_opencl) Opts.OpenCLVersion = 100; else if (LangStd == LangStandard::lang_opencl11) - Opts.OpenCLVersion = 110; + Opts.OpenCLVersion = 110; else if (LangStd == LangStandard::lang_opencl12) Opts.OpenCLVersion = 120; - + else if (LangStd == LangStandard::lang_opencl20) + Opts.OpenCLVersion = 200; + // OpenCL has some additional defaults. if (Opts.OpenCL) { Opts.AltiVec = 0; @@ -1175,15 +1235,10 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.GNUKeywords = Opts.GNUMode; Opts.CXXOperatorNames = Opts.CPlusPlus; - // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs - // is specified, or -std is set to a conforming mode. - // Trigraphs are disabled by default in c++1z onwards. - Opts.Trigraphs = !Opts.GNUMode && !Opts.CPlusPlus1z; - Opts.DollarIdents = !Opts.AsmPreprocessor; - // C++1y onwards has sized global deallocation functions. - Opts.SizedDeallocation = Opts.CPlusPlus1y; + // C++14 onwards has sized global deallocation functions. + Opts.SizedDeallocation = Opts.CPlusPlus14; } /// Attempt to parse a visibility value out of the given argument. @@ -1299,6 +1354,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, .Case("CL", LangStandard::lang_opencl) .Case("CL1.1", LangStandard::lang_opencl11) .Case("CL1.2", LangStandard::lang_opencl12) + .Case("CL2.0", LangStandard::lang_opencl20) .Default(LangStandard::lang_unspecified); if (OpenCLLangStd == LangStandard::lang_unspecified) { @@ -1322,6 +1378,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fno_operator_names)) Opts.CXXOperatorNames = 0; + if (Args.hasArg(OPT_fcuda_is_device)) + Opts.CUDAIsDevice = 1; + if (Opts.ObjC1) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { StringRef value = arg->getValue(); @@ -1400,17 +1459,22 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, else if (Args.hasArg(OPT_fwrapv)) Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); - if (Args.hasArg(OPT_trigraphs)) - Opts.Trigraphs = 1; + Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility); + Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions); + Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt; + Opts.MSCompatibilityVersion = parseMSCVersion(Args, Diags); + + // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs + // is specified, or -std is set to a conforming mode. + // Trigraphs are disabled by default in c++1z onwards. + Opts.Trigraphs = !Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus1z; + Opts.Trigraphs = + Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs); Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers, OPT_fno_dollars_in_identifiers, Opts.DollarIdents); Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings); - Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility); - Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions); - Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt; - Opts.MSCompatibilityVersion = parseMSCVersion(Args, Diags); Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags); Opts.Borland = Args.hasArg(OPT_fborland_extensions); Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings); @@ -1438,12 +1502,13 @@ 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.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false); Opts.ShortEnums = Args.hasArg(OPT_fshort_enums); Opts.Freestanding = Args.hasArg(OPT_ffreestanding); - Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions); Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin); Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); @@ -1473,6 +1538,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fencode_extended_block_signature); Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags); + Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags); Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags); Opts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags); Opts.Static = Args.hasArg(OPT_static_define); @@ -1493,6 +1559,16 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal); Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack); Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name); + Opts.ImplementationOfModule = + Args.getLastArgValue(OPT_fmodule_implementation_of); + Opts.NativeHalfType = Opts.NativeHalfType; + Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns); + + if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() && + Opts.CurrentModule != Opts.ImplementationOfModule) { + Diags.Report(diag::err_conflicting_module_names) + << Opts.CurrentModule << Opts.ImplementationOfModule; + } if (Arg *A = Args.getLastArg(OPT_faddress_space_map_mangling_EQ)) { switch (llvm::StringSwitch<unsigned>(A->getValue()) @@ -1557,8 +1633,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // inlining enabled. Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline); - Opts.FastMath = Args.hasArg(OPT_ffast_math); - Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only); + Opts.FastMath = Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) || + Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); Opts.RetainCommentsFromSystemHeaders = Args.hasArg(OPT_fretain_comments_from_system_headers); @@ -1576,35 +1655,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } // Parse -fsanitize= arguments. - std::vector<std::string> Sanitizers = Args.getAllArgValues(OPT_fsanitize_EQ); - for (unsigned I = 0, N = Sanitizers.size(); I != N; ++I) { - // Since the Opts.Sanitize* values are bitfields, it's a little tricky to - // efficiently map string values to them. Perform the mapping indirectly: - // convert strings to enumerated values, then switch over the enum to set - // the right bitfield value. - enum Sanitizer { -#define SANITIZER(NAME, ID) \ - ID, -#include "clang/Basic/Sanitizers.def" - Unknown - }; - switch (llvm::StringSwitch<unsigned>(Sanitizers[I]) -#define SANITIZER(NAME, ID) \ - .Case(NAME, ID) -#include "clang/Basic/Sanitizers.def" - .Default(Unknown)) { -#define SANITIZER(NAME, ID) \ - case ID: \ - Opts.Sanitize.ID = true; \ - break; -#include "clang/Basic/Sanitizers.def" - - case Unknown: - Diags.Report(diag::err_drv_invalid_value) - << "-fsanitize=" << Sanitizers[I]; - break; - } - } + parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), + Diags, Opts.Sanitize); + // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here. + Opts.SanitizeAddressFieldPadding = + getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags); + Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist); } static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, @@ -2022,7 +2078,7 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI, } IntrusiveRefCntPtr<vfs::FileSystem> FS = - vfs::getVFSFromYAML(Buffer->release(), /*DiagHandler*/ nullptr); + vfs::getVFSFromYAML(std::move(Buffer.get()), /*DiagHandler*/ nullptr); if (!FS.get()) { Diags.Report(diag::err_invalid_vfs_overlay) << File; return IntrusiveRefCntPtr<vfs::FileSystem>(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp index f2f36e4..4a8a8a0 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -71,13 +71,13 @@ clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList, return nullptr; } - const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); - if (StringRef(Cmd->getCreator().getName()) != "clang") { + const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin()); + if (StringRef(Cmd.getCreator().getName()) != "clang") { Diags->Report(diag::err_fe_expected_clang_command); return nullptr; } - const ArgStringList &CCArgs = Cmd->getArguments(); + const ArgStringList &CCArgs = Cmd.getArguments(); std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation()); if (!CompilerInvocation::CreateFromArgs(*CI, const_cast<const char **>(CCArgs.data()), diff --git a/contrib/llvm/tools/clang/lib/Frontend/DependencyFile.cpp b/contrib/llvm/tools/clang/lib/Frontend/DependencyFile.cpp index 0b9c0d4..6ea8f51 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/DependencyFile.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/DependencyFile.cpp @@ -22,6 +22,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Serialization/ASTReader.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -108,23 +109,32 @@ struct DepCollectorASTListener : public ASTReaderListener { void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing) { - if (Seen.insert(Filename) && + if (Seen.insert(Filename).second && sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing)) Dependencies.push_back(Filename); } +static bool isSpecialFilename(StringRef Filename) { + return llvm::StringSwitch<bool>(Filename) + .Case("<built-in>", true) + .Case("<stdin>", true) + .Default(false); +} + bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing) { - return Filename != "<built-in>" && (needSystemDependencies() || !IsSystem); + return !isSpecialFilename(Filename) && + (needSystemDependencies() || !IsSystem); } DependencyCollector::~DependencyCollector() { } void DependencyCollector::attachToPreprocessor(Preprocessor &PP) { - PP.addPPCallbacks(new DepCollectorPPCallbacks(*this, PP.getSourceManager())); + PP.addPPCallbacks( + llvm::make_unique<DepCollectorPPCallbacks>(*this, PP.getSourceManager())); } void DependencyCollector::attachToASTReader(ASTReader &R) { - R.addListener(new DepCollectorASTListener(*this)); + R.addListener(llvm::make_unique<DepCollectorASTListener>(*this)); } namespace { @@ -203,21 +213,21 @@ DependencyFileGenerator *DependencyFileGenerator::CreateAndAttachToPreprocessor( PP.SetSuppressIncludeNotFoundError(true); DFGImpl *Callback = new DFGImpl(&PP, Opts); - PP.addPPCallbacks(Callback); // PP owns the Callback + PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callback)); return new DependencyFileGenerator(Callback); } void DependencyFileGenerator::AttachToASTReader(ASTReader &R) { DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl); assert(I && "missing implementation"); - R.addListener(new DFGASTReaderListener(*I)); + R.addListener(llvm::make_unique<DFGASTReaderListener>(*I)); } /// FileMatchesDepCriteria - Determine whether the given Filename should be /// considered as a dependency. bool DFGImpl::FileMatchesDepCriteria(const char *Filename, SrcMgr::CharacteristicKind FileType) { - if (strcmp("<built-in>", Filename) == 0) + if (isSpecialFilename(Filename)) return false; if (IncludeSystemHeaders) @@ -275,7 +285,7 @@ void DFGImpl::InclusionDirective(SourceLocation HashLoc, } void DFGImpl::AddFilename(StringRef Filename) { - if (FilesSet.insert(Filename)) + if (FilesSet.insert(Filename).second) Files.push_back(Filename); } @@ -297,11 +307,11 @@ void DFGImpl::OutputDependencyFile() { return; } - std::string Err; - llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text); - if (!Err.empty()) { - PP->getDiagnostics().Report(diag::err_fe_error_opening) - << OutputFile << Err; + std::error_code EC; + llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text); + if (EC) { + PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile + << EC.message(); return; } diff --git a/contrib/llvm/tools/clang/lib/Frontend/DependencyGraph.cpp b/contrib/llvm/tools/clang/lib/Frontend/DependencyGraph.cpp index 051b7f9..67a977e 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/DependencyGraph.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/DependencyGraph.cpp @@ -61,7 +61,8 @@ public: void clang::AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, StringRef SysRoot) { - PP.addPPCallbacks(new DependencyGraphCallback(&PP, OutputFile, SysRoot)); + PP.addPPCallbacks(llvm::make_unique<DependencyGraphCallback>(&PP, OutputFile, + SysRoot)); } void DependencyGraphCallback::InclusionDirective(SourceLocation HashLoc, @@ -96,11 +97,11 @@ DependencyGraphCallback::writeNodeReference(raw_ostream &OS, } void DependencyGraphCallback::OutputGraphFile() { - std::string Err; - llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text); - if (!Err.empty()) { - PP->getDiagnostics().Report(diag::err_fe_error_opening) - << OutputFile << Err; + std::error_code EC; + llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text); + if (EC) { + PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile + << EC.message(); return; } diff --git a/contrib/llvm/tools/clang/lib/Frontend/DiagnosticRenderer.cpp b/contrib/llvm/tools/clang/lib/Frontend/DiagnosticRenderer.cpp index cff32b8..c63e98d 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/DiagnosticRenderer.cpp @@ -193,7 +193,7 @@ void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { void DiagnosticRenderer::emitBasicNote(StringRef Message) { emitDiagnosticMessage( SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message, - ArrayRef<CharSourceRange>(), nullptr, DiagOrStoredDiag()); + None, nullptr, DiagOrStoredDiag()); } /// \brief Prints an include stack when appropriate for a particular @@ -509,6 +509,6 @@ DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, Message << "while building module '" << ModuleName << "' imported from " << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; else - Message << "while building module '" << ModuleName << ":"; + Message << "while building module '" << ModuleName << "':"; emitNote(Loc, Message.str(), &SM); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp index 7910179..c81c81a 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendAction.cpp @@ -129,14 +129,15 @@ FrontendAction::FrontendAction() : Instance(nullptr) {} FrontendAction::~FrontendAction() {} void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput, - ASTUnit *AST) { + std::unique_ptr<ASTUnit> AST) { this->CurrentInput = CurrentInput; - CurrentASTUnit.reset(AST); + CurrentASTUnit = std::move(AST); } -ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, - StringRef InFile) { - ASTConsumer* Consumer = CreateASTConsumer(CI, InFile); +std::unique_ptr<ASTConsumer> +FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, + StringRef InFile) { + std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile); if (!Consumer) return nullptr; @@ -145,7 +146,8 @@ ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, // Make sure the non-plugin consumer is first, so that plugins can't // modifiy the AST. - std::vector<ASTConsumer*> Consumers(1, Consumer); + std::vector<std::unique_ptr<ASTConsumer>> Consumers; + Consumers.push_back(std::move(Consumer)); for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); i != e; ++i) { @@ -155,16 +157,15 @@ ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { - if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { - std::unique_ptr<PluginASTAction> P(it->instantiate()); - FrontendAction* c = P.get(); - if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) - Consumers.push_back(c->CreateASTConsumer(CI, InFile)); - } + if (it->getName() != CI.getFrontendOpts().AddPluginActions[i]) + continue; + std::unique_ptr<PluginASTAction> P = it->instantiate(); + if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) + Consumers.push_back(P->CreateASTConsumer(CI, InFile)); } } - return new MultiplexConsumer(Consumers); + return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); } bool FrontendAction::BeginSourceFile(CompilerInstance &CI, @@ -189,13 +190,12 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); - ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags, - CI.getFileSystemOpts()); + std::unique_ptr<ASTUnit> AST = + ASTUnit::LoadFromASTFile(InputFile, Diags, CI.getFileSystemOpts()); + if (!AST) goto failure; - setCurrentInput(Input, AST); - // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); HasBegunSourceFile = true; @@ -207,6 +207,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, CI.setPreprocessor(&AST->getPreprocessor()); CI.setASTContext(&AST->getASTContext()); + setCurrentInput(Input, std::move(AST)); + // Initialize the action. if (!BeginSourceFileAction(CI, InputFile)) goto failure; @@ -285,8 +287,10 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, } } - // Set up the preprocessor. - CI.createPreprocessor(getTranslationUnitKind()); + // Set up the preprocessor if needed. When parsing model files the + // preprocessor of the original source is reused. + if (!isModelParsingAction()) + CI.createPreprocessor(getTranslationUnitKind()); // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), @@ -305,15 +309,19 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // Create the AST context and consumer unless this is a preprocessor only // action. if (!usesPreprocessorOnly()) { - CI.createASTContext(); + // Parsing a model file should reuse the existing ASTContext. + if (!isModelParsingAction()) + CI.createASTContext(); - std::unique_ptr<ASTConsumer> Consumer( - CreateWrappedASTConsumer(CI, InputFile)); + std::unique_ptr<ASTConsumer> Consumer = + CreateWrappedASTConsumer(CI, InputFile); if (!Consumer) goto failure; - CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); - + // FIXME: should not overwrite ASTMutationListener when parsing model files? + if (!isModelParsingAction()) + CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener()); + if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader; @@ -349,7 +357,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, goto failure; } - CI.setASTConsumer(Consumer.release()); + CI.setASTConsumer(std::move(Consumer)); if (!CI.hasASTConsumer()) goto failure; } @@ -375,6 +383,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, "doesn't support modules"); } + // If we were asked to load any module files, do so now. + for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) + if (!CI.loadModuleFile(ModuleFile)) + goto failure; + // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && @@ -432,6 +445,10 @@ void FrontendAction::EndSourceFile() { // Inform the diagnostic client we are done with this source file. CI.getDiagnosticClient().EndSourceFile(); + // Inform the preprocessor we are done. + if (CI.hasPreprocessor()) + CI.getPreprocessor().EndSourceFile(); + // Finalize the action. EndSourceFileAction(); @@ -444,7 +461,7 @@ void FrontendAction::EndSourceFile() { CI.resetAndLeakSema(); CI.resetAndLeakASTContext(); } - BuryPointer(CI.takeASTConsumer()); + BuryPointer(CI.takeASTConsumer().get()); } else { if (!isCurrentFileAST()) { CI.setSema(nullptr); @@ -453,10 +470,6 @@ void FrontendAction::EndSourceFile() { CI.setASTConsumer(nullptr); } - // Inform the preprocessor we are done. - if (CI.hasPreprocessor()) - CI.getPreprocessor().EndSourceFile(); - if (CI.getFrontendOpts().ShowStats) { llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n"; CI.getPreprocessor().PrintStats(); @@ -516,14 +529,15 @@ void ASTFrontendAction::ExecuteAction() { void PluginASTAction::anchor() { } -ASTConsumer * +std::unique_ptr<ASTConsumer> PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!"); } -ASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { return WrappedAction->CreateASTConsumer(CI, InFile); } bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) { diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp index 6dcaf38..701ef02 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp @@ -33,9 +33,9 @@ using namespace clang; // Custom Actions //===----------------------------------------------------------------------===// -ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return new ASTConsumer(); +std::unique_ptr<ASTConsumer> +InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return llvm::make_unique<ASTConsumer>(); } void InitOnlyAction::ExecuteAction() { @@ -45,36 +45,38 @@ void InitOnlyAction::ExecuteAction() { // AST Consumer Actions //===----------------------------------------------------------------------===// -ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter); return nullptr; } -ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter, + CI.getFrontendOpts().ASTDumpDecls, CI.getFrontendOpts().ASTDumpLookups); } -ASTConsumer *ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { return CreateASTDeclNodeLister(); } -ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { return CreateASTViewer(); } -ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { return CreateDeclContextPrinter(); } -ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; std::string OutputFile; raw_ostream *OS = nullptr; @@ -83,8 +85,8 @@ ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); - return new PCHGenerator(CI.getPreprocessor(), OutputFile, nullptr, Sysroot, - OS); + return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile, + nullptr, Sysroot, OS); } bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, @@ -111,16 +113,17 @@ bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, return false; } -ASTConsumer *GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { std::string Sysroot; std::string OutputFile; raw_ostream *OS = nullptr; if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS)) return nullptr; - return new PCHGenerator(CI.getPreprocessor(), OutputFile, Module, - Sysroot, OS); + return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile, + Module, Sysroot, OS); } static SmallVectorImpl<char> & @@ -139,17 +142,9 @@ static std::error_code addHeaderInclude(StringRef HeaderName, Includes += "#import \""; else Includes += "#include \""; - // Use an absolute path for the include; there's no reason to think that - // a relative path will work (. might not be on our include path) or that - // it will find the same file. - if (llvm::sys::path::is_absolute(HeaderName)) { - Includes += HeaderName; - } else { - SmallString<256> Header = HeaderName; - if (std::error_code Err = llvm::sys::fs::make_absolute(Header)) - return Err; - Includes += Header; - } + + Includes += HeaderName; + Includes += "\"\n"; if (IsExternC && LangOpts.CPlusPlus) Includes += "}\n"; @@ -160,7 +155,16 @@ static std::error_code addHeaderInclude(const FileEntry *Header, SmallVectorImpl<char> &Includes, const LangOptions &LangOpts, bool IsExternC) { - return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC); + // Use an absolute path if we don't have a filename as written in the module + // map file; this ensures that we will identify the right file independent of + // header search paths. + if (llvm::sys::path::is_absolute(Header->getName())) + return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC); + + SmallString<256> AbsName(Header->getName()); + if (std::error_code Err = llvm::sys::fs::make_absolute(AbsName)) + return Err; + return addHeaderInclude(AbsName, Includes, LangOpts, IsExternC); } /// \brief Collect the set of header includes needed to construct the given @@ -179,16 +183,20 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, return std::error_code(); // Add includes for each of these headers. - for (unsigned I = 0, N = Module->NormalHeaders.size(); I != N; ++I) { - const FileEntry *Header = Module->NormalHeaders[I]; - Module->addTopHeader(Header); - if (std::error_code Err = - addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC)) + for (Module::Header &H : Module->Headers[Module::HK_Normal]) { + Module->addTopHeader(H.Entry); + // Use the path as specified in the module map file. We'll look for this + // file relative to the module build directory (the directory containing + // the module map file) so this will find the same file that we found + // while parsing the module map. + if (std::error_code Err = addHeaderInclude(H.NameAsWritten, Includes, + LangOpts, Module->IsExternC)) return Err; } // Note that Module->PrivateHeaders will not be a TopHeader. if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) { + // FIXME: Track the name as written here. Module->addTopHeader(UmbrellaHeader); if (Module->Parent) { // Include the umbrella header for submodules. @@ -210,25 +218,30 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, .Cases(".h", ".H", ".hh", ".hpp", true) .Default(false)) continue; - + + const FileEntry *Header = FileMgr.getFile(Dir->path()); + // FIXME: This shouldn't happen unless there is a file system race. Is + // that worth diagnosing? + if (!Header) + continue; + // If this header is marked 'unavailable' in this module, don't include // it. - if (const FileEntry *Header = FileMgr.getFile(Dir->path())) { - if (ModMap.isHeaderUnavailableInModule(Header, Module)) - continue; - Module->addTopHeader(Header); - } - + if (ModMap.isHeaderUnavailableInModule(Header, Module)) + continue; + // Include this header as part of the umbrella directory. - if (std::error_code Err = addHeaderInclude(Dir->path(), Includes, - LangOpts, Module->IsExternC)) + // FIXME: Track the name as written through to here. + Module->addTopHeader(Header); + if (std::error_code Err = + addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC)) return Err; } if (EC) return EC; } - + // Recurse into submodules. for (clang::Module::submodule_iterator Sub = Module->submodule_begin(), SubEnd = Module->submodule_end(); @@ -285,7 +298,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, // Check whether we can build this module at all. clang::Module::Requirement Requirement; - clang::Module::HeaderDirective MissingHeader; + clang::Module::UnresolvedHeaderDirective MissingHeader; if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement, MissingHeader)) { if (MissingHeader.FileNameLoc.isValid()) { @@ -301,10 +314,12 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, return false; } - if (!ModuleMapForUniquing) + if (ModuleMapForUniquing && ModuleMapForUniquing != ModuleMap) { + Module->IsInferred = true; + HS.getModuleMap().setInferredModuleAllowedBy(Module, ModuleMapForUniquing); + } else { ModuleMapForUniquing = ModuleMap; - Module->ModuleMap = ModuleMapForUniquing; - assert(Module->ModuleMap && "missing module map file"); + } FileManager &FileMgr = CI.getFileManager(); @@ -312,6 +327,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, SmallString<256> HeaderContents; std::error_code Err = std::error_code(); if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) + // FIXME: Track the file name as written. Err = addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(), Module->IsExternC); if (!Err) @@ -326,11 +342,15 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, return false; } - llvm::MemoryBuffer *InputBuffer = + // Inform the preprocessor that includes from within the input buffer should + // be resolved relative to the build directory of the module map file. + CI.getPreprocessor().setMainFileDir(Module->Directory); + + std::unique_ptr<llvm::MemoryBuffer> InputBuffer = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents, Module::getModuleInputBufferName()); // Ownership of InputBuffer will be transferred to the SourceManager. - setCurrentInput(FrontendInputFile(InputBuffer, getCurrentFileKind(), + setCurrentInput(FrontendInputFile(InputBuffer.release(), getCurrentFileKind(), Module->IsSystem)); return true; } @@ -363,19 +383,20 @@ bool GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI, return false; } -ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return new ASTConsumer(); +std::unique_ptr<ASTConsumer> +SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return llvm::make_unique<ASTConsumer>(); } -ASTConsumer *DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return new ASTConsumer(); +std::unique_ptr<ASTConsumer> +DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + return llvm::make_unique<ASTConsumer>(); } -ASTConsumer *VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return new ASTConsumer(); +std::unique_ptr<ASTConsumer> +VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return llvm::make_unique<ASTConsumer>(); } void VerifyPCHAction::ExecuteAction() { @@ -425,8 +446,8 @@ namespace { Out.indent(2) << "Module map file: " << ModuleMapPath << "\n"; } - bool ReadLanguageOptions(const LangOptions &LangOpts, - bool Complain) override { + bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, + bool AllowCompatibleDifferences) override { Out.indent(2) << "Language options:\n"; #define LANGOPT(Name, Bits, Default, Description) \ DUMP_BOOLEAN(LangOpts.Name, Description); @@ -528,9 +549,9 @@ void DumpModuleInfoAction::ExecuteAction() { std::unique_ptr<llvm::raw_fd_ostream> OutFile; StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile; if (!OutputFileName.empty() && OutputFileName != "-") { - std::string ErrorInfo; - OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str().c_str(), - ErrorInfo, llvm::sys::fs::F_Text)); + std::error_code EC; + OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC, + llvm::sys::fs::F_Text)); } llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs(); @@ -675,13 +696,12 @@ void PrintPreambleAction::ExecuteAction() { // We can't do anything with these. return; } - + CompilerInstance &CI = getCompilerInstance(); - llvm::MemoryBuffer *Buffer - = CI.getFileManager().getBufferForFile(getCurrentFile()); + auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile()); if (Buffer) { - unsigned Preamble = Lexer::ComputePreamble(Buffer, CI.getLangOpts()).first; - llvm::outs().write(Buffer->getBufferStart(), Preamble); - delete Buffer; + unsigned Preamble = + Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).first; + llvm::outs().write((*Buffer)->getBufferStart(), Preamble); } } diff --git a/contrib/llvm/tools/clang/lib/Frontend/HeaderIncludeGen.cpp b/contrib/llvm/tools/clang/lib/Frontend/HeaderIncludeGen.cpp index a2f5896..2701194 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/HeaderIncludeGen.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/HeaderIncludeGen.cpp @@ -54,13 +54,12 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders, // Open the output file, if used. if (!OutputPath.empty()) { - std::string Error; + std::error_code EC; llvm::raw_fd_ostream *OS = new llvm::raw_fd_ostream( - OutputPath.str().c_str(), Error, - llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); - if (!Error.empty()) { - PP.getDiagnostics().Report( - clang::diag::warn_fe_cc_print_header_failure) << Error; + OutputPath.str(), EC, llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); + if (EC) { + PP.getDiagnostics().Report(clang::diag::warn_fe_cc_print_header_failure) + << EC.message(); delete OS; } else { OS->SetUnbuffered(); @@ -70,9 +69,12 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders, } } - PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders, - OutputFile, OwnsOutputFile, - ShowDepth, MSStyle)); + PP.addPPCallbacks(llvm::make_unique<HeaderIncludesCallback>(&PP, + ShowAllHeaders, + OutputFile, + OwnsOutputFile, + ShowDepth, + MSStyle)); } void HeaderIncludesCallback::FileChanged(SourceLocation Loc, diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp index 6a47d04..a518a0a 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitHeaderSearch.cpp @@ -14,7 +14,6 @@ #include "clang/Frontend/Utils.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/Version.h" #include "clang/Config/config.h" // C_INCLUDE_DIRS #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" @@ -337,9 +336,6 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, break; } break; - case llvm::Triple::FreeBSD: - AddPath("/usr/include/clang/" CLANG_VERSION_STRING, System, false); - break; default: break; } @@ -384,7 +380,6 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp break; case llvm::Triple::aarch64: - case llvm::Triple::arm64: AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1", "arm64-apple-darwin10", "", "", triple); break; @@ -395,7 +390,7 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp switch (os) { case llvm::Triple::Linux: llvm_unreachable("Include management is handled in the driver."); - + break; case llvm::Triple::Win32: switch (triple.getEnvironment()) { default: llvm_unreachable("Include management is handled in the driver."); @@ -449,11 +444,6 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp case llvm::Triple::Solaris: AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/", "i386-pc-solaris2.11", "", "", triple); - // Solaris - Fall though.. - case llvm::Triple::AuroraUX: - // AuroraUX - AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4", - "i386-pc-solaris2.11", "", "", triple); break; default: break; @@ -477,7 +467,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, case llvm::Triple::Win32: if (triple.getEnvironment() == llvm::Triple::MSVC || triple.getEnvironment() == llvm::Triple::Itanium || - triple.getObjectFormat() == llvm::Triple::MachO) + triple.isOSBinFormatMachO()) return; break; } @@ -539,16 +529,16 @@ static unsigned RemoveDuplicates(std::vector<DirectoryLookup> &SearchList, if (CurEntry.isNormalDir()) { // If this isn't the first time we've seen this dir, remove it. - if (SeenDirs.insert(CurEntry.getDir())) + if (SeenDirs.insert(CurEntry.getDir()).second) continue; } else if (CurEntry.isFramework()) { // If this isn't the first time we've seen this framework dir, remove it. - if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir())) + if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()).second) continue; } else { assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?"); // If this isn't the first time we've seen this headermap, remove it. - if (SeenHeaderMaps.insert(CurEntry.getHeaderMap())) + if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()).second) continue; } diff --git a/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp b/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp index 7a9d09a..f4241a9 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/InitPreprocessor.cpp @@ -65,17 +65,14 @@ static void DefineBuiltinMacro(MacroBuilder &Builder, StringRef Macro, /// AddImplicitInclude - Add an implicit \#include of the specified file to the /// predefines buffer. -static void AddImplicitInclude(MacroBuilder &Builder, StringRef File, - FileManager &FileMgr) { - Builder.append(Twine("#include \"") + - HeaderSearch::NormalizeDashIncludePath(File, FileMgr) + "\""); +/// As these includes are generated by -include arguments the header search +/// logic is going to search relatively to the current working directory. +static void AddImplicitInclude(MacroBuilder &Builder, StringRef File) { + Builder.append(Twine("#include \"") + File + "\""); } -static void AddImplicitIncludeMacros(MacroBuilder &Builder, - StringRef File, - FileManager &FileMgr) { - Builder.append(Twine("#__include_macros \"") + - HeaderSearch::NormalizeDashIncludePath(File, FileMgr) + "\""); +static void AddImplicitIncludeMacros(MacroBuilder &Builder, StringRef File) { + Builder.append(Twine("#__include_macros \"") + File + "\""); // Marker token to stop the __include_macros fetch loop. Builder.append("##"); // ##? } @@ -94,7 +91,7 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP, return; } - AddImplicitInclude(Builder, OriginalFile, PP.getFileManager()); + AddImplicitInclude(Builder, OriginalFile); } /// \brief Add an implicit \#include using the original file used to generate @@ -107,7 +104,7 @@ static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP, if (OriginalFile.empty()) return; - AddImplicitInclude(Builder, OriginalFile, PP.getFileManager()); + AddImplicitInclude(Builder, OriginalFile); } /// PickFP - This is used to pick a value based on the FP semantics of the @@ -378,7 +375,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, // C++1y [cpp.predefined]p1: // The name __cplusplus is defined to the value 201402L when compiling a // C++ translation unit. - else if (LangOpts.CPlusPlus1y) + else if (LangOpts.CPlusPlus14) Builder.defineMacro("__cplusplus", "201402L"); // C++11 [cpp.predefined]p1: // The name __cplusplus is defined to the value 201103L when compiling a @@ -412,6 +409,12 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, /// ISO/IEC JTC1/SC22/WG21 (C++) SD-6: "SG10 Feature Test Recommendations". static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, MacroBuilder &Builder) { + // C++98 features. + if (LangOpts.RTTI) + Builder.defineMacro("__cpp_rtti", "199711"); + if (LangOpts.CXXExceptions) + Builder.defineMacro("__cpp_exceptions", "199711"); + // C++11 features. if (LangOpts.CPlusPlus11) { Builder.defineMacro("__cpp_unicode_characters", "200704"); @@ -420,17 +423,25 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_user_defined_literals", "200809"); Builder.defineMacro("__cpp_lambdas", "200907"); Builder.defineMacro("__cpp_constexpr", - LangOpts.CPlusPlus1y ? "201304" : "200704"); + LangOpts.CPlusPlus14 ? "201304" : "200704"); + Builder.defineMacro("__cpp_range_based_for", "200907"); Builder.defineMacro("__cpp_static_assert", "200410"); Builder.defineMacro("__cpp_decltype", "200707"); Builder.defineMacro("__cpp_attributes", "200809"); Builder.defineMacro("__cpp_rvalue_references", "200610"); Builder.defineMacro("__cpp_variadic_templates", "200704"); + Builder.defineMacro("__cpp_initializer_lists", "200806"); + Builder.defineMacro("__cpp_delegating_constructors", "200604"); + Builder.defineMacro("__cpp_nsdmi", "200809"); + Builder.defineMacro("__cpp_inheriting_constructors", "200802"); + Builder.defineMacro("__cpp_ref_qualifiers", "200710"); + Builder.defineMacro("__cpp_alias_templates", "200704"); } // C++14 features. - if (LangOpts.CPlusPlus1y) { + if (LangOpts.CPlusPlus14) { Builder.defineMacro("__cpp_binary_literals", "201304"); + Builder.defineMacro("__cpp_digit_separators", "201309"); Builder.defineMacro("__cpp_init_captures", "201304"); Builder.defineMacro("__cpp_generic_lambdas", "201304"); Builder.defineMacro("__cpp_decltype_auto", "201304"); @@ -438,6 +449,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_aggregate_nsdmi", "201304"); Builder.defineMacro("__cpp_variable_templates", "201304"); } + if (LangOpts.SizedDeallocation) + Builder.defineMacro("__cpp_sized_deallocation", "201309"); } static void InitializePredefinedMacros(const TargetInfo &TI, @@ -530,6 +543,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("IBOutletCollection(ClassName)", "__attribute__((iboutletcollection(ClassName)))"); Builder.defineMacro("IBAction", "void)__attribute__((ibaction)"); + Builder.defineMacro("IBInspectable", ""); + Builder.defineMacro("IB_DESIGNABLE", ""); } if (LangOpts.CPlusPlus) @@ -551,7 +566,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__BLOCKS__"); } - if (!LangOpts.MSVCCompat && LangOpts.CXXExceptions) + if (!LangOpts.MSVCCompat && LangOpts.Exceptions) Builder.defineMacro("__EXCEPTIONS"); if (!LangOpts.MSVCCompat && LangOpts.RTTI) Builder.defineMacro("__GXX_RTTI"); @@ -626,12 +641,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder); DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder); - if (!LangOpts.MSVCCompat) { - DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder); - DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder); - DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder); - DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder); - } + DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder); + DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder); + DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder); + DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder); DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder); DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder); @@ -649,7 +662,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI, TI.getTypeWidth(TI.getWCharType()), TI, Builder); DefineTypeSizeof("__SIZEOF_WINT_T__", TI.getTypeWidth(TI.getWIntType()), TI, Builder); - if (TI.hasInt128Type()) + // This is a temporary workaround while MIPS64 has not yet fully supported + // 128-bit integers. But declaration of int128 type is necessary even though + // __SIZEOF_INT128__ is undefined because c++ standard header files like + // limits throw error message if __int128 is not available. + if (TI.hasInt128Type() && !(TI.getTriple().getArch() == llvm::Triple::mips64el + || TI.getTriple().getArch() == llvm::Triple::mips64)) DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder); DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder); @@ -679,12 +697,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder); DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder); - if (!LangOpts.MSVCCompat) { - DefineTypeWidth("__UINTMAX_WIDTH__", TI.getUIntMaxType(), TI, Builder); - DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder); - DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder); - DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder); - } + DefineTypeWidth("__UINTMAX_WIDTH__", TI.getUIntMaxType(), TI, Builder); + DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder); + DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder); + DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder); DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F"); DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), ""); @@ -718,54 +734,52 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (TI.getLongLongWidth() > TI.getLongWidth()) DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder); - if (!LangOpts.MSVCCompat) { - DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder); - - if (TI.getShortWidth() > TI.getCharWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder); - } + DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder); - if (TI.getIntWidth() > TI.getShortWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder); - } + if (TI.getShortWidth() > TI.getCharWidth()) { + DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder); + } - if (TI.getLongWidth() > TI.getIntWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder); - } + if (TI.getIntWidth() > TI.getShortWidth()) { + DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder); + } - if (TI.getLongLongWidth() > TI.getLongWidth()) { - DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder); - DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder); - } + if (TI.getLongWidth() > TI.getIntWidth()) { + DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder); + } - DefineLeastWidthIntType(8, true, TI, Builder); - DefineLeastWidthIntType(8, false, TI, Builder); - DefineLeastWidthIntType(16, true, TI, Builder); - DefineLeastWidthIntType(16, false, TI, Builder); - DefineLeastWidthIntType(32, true, TI, Builder); - DefineLeastWidthIntType(32, false, TI, Builder); - DefineLeastWidthIntType(64, true, TI, Builder); - DefineLeastWidthIntType(64, false, TI, Builder); - - DefineFastIntType(8, true, TI, Builder); - DefineFastIntType(8, false, TI, Builder); - DefineFastIntType(16, true, TI, Builder); - DefineFastIntType(16, false, TI, Builder); - DefineFastIntType(32, true, TI, Builder); - DefineFastIntType(32, false, TI, Builder); - DefineFastIntType(64, true, TI, Builder); - DefineFastIntType(64, false, TI, Builder); + if (TI.getLongLongWidth() > TI.getLongWidth()) { + DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder); + DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder); } + DefineLeastWidthIntType(8, true, TI, Builder); + DefineLeastWidthIntType(8, false, TI, Builder); + DefineLeastWidthIntType(16, true, TI, Builder); + DefineLeastWidthIntType(16, false, TI, Builder); + DefineLeastWidthIntType(32, true, TI, Builder); + DefineLeastWidthIntType(32, false, TI, Builder); + DefineLeastWidthIntType(64, true, TI, Builder); + DefineLeastWidthIntType(64, false, TI, Builder); + + DefineFastIntType(8, true, TI, Builder); + DefineFastIntType(8, false, TI, Builder); + DefineFastIntType(16, true, TI, Builder); + DefineFastIntType(16, false, TI, Builder); + DefineFastIntType(32, true, TI, Builder); + DefineFastIntType(32, false, TI, Builder); + DefineFastIntType(64, true, TI, Builder); + DefineFastIntType(64, false, TI, Builder); + if (const char *Prefix = TI.getUserLabelPrefix()) Builder.defineMacro("__USER_LABEL_PREFIX__", Prefix); @@ -861,6 +875,13 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("_OPENMP", "201307"); } + // CUDA device path compilaton + if (LangOpts.CUDAIsDevice) { + // The CUDA_ARCH value is set for the GPU target specified in the NVPTX + // backend's target defines. + Builder.defineMacro("__CUDA_ARCH__"); + } + // Get other target #defines. TI.getTargetDefines(LangOpts, Builder); } @@ -925,8 +946,7 @@ void clang::InitializePreprocessor(Preprocessor &PP, // If -imacros are specified, include them now. These are processed before // any -include directives. for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i) - AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i], - PP.getFileManager()); + AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i]); // Process -include-pch/-include-pth directives. if (!InitOpts.ImplicitPCHInclude.empty()) @@ -937,7 +957,7 @@ void clang::InitializePreprocessor(Preprocessor &PP, // Process -include directives. for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) { const std::string &Path = InitOpts.Includes[i]; - AddImplicitInclude(Builder, Path, PP.getFileManager()); + AddImplicitInclude(Builder, Path); } // Exit the command line and go back to <built-in> (2 is LC_LEAVE). diff --git a/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp b/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp index 19539e0..c6a18e0 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp @@ -18,17 +18,11 @@ using namespace clang; using namespace markup; -LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os, - DiagnosticOptions *diags, - bool _OwnsOutputStream) - : OS(os), LangOpts(nullptr), DiagOpts(diags), - OwnsOutputStream(_OwnsOutputStream) { -} - -LogDiagnosticPrinter::~LogDiagnosticPrinter() { - if (OwnsOutputStream) - delete &OS; -} +LogDiagnosticPrinter::LogDiagnosticPrinter( + raw_ostream &os, DiagnosticOptions *diags, + std::unique_ptr<raw_ostream> StreamOwner) + : OS(os), StreamOwner(std::move(StreamOwner)), LangOpts(nullptr), + DiagOpts(diags) {} static StringRef getLevelName(DiagnosticsEngine::Level Level) { switch (Level) { @@ -69,6 +63,14 @@ LogDiagnosticPrinter::EmitDiagEntry(llvm::raw_ostream &OS, << " "; EmitString(OS, DE.Message) << '\n'; } + OS << " <key>ID</key>\n" + << " "; + EmitInteger(OS, DE.DiagnosticID) << '\n'; + if (!DE.WarningOption.empty()) { + OS << " <key>WarningOption</key>\n" + << " "; + EmitString(OS, DE.WarningOption) << '\n'; + } OS << " </dict>\n"; } @@ -128,6 +130,8 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level, DE.DiagnosticID = Info.getID(); DE.DiagnosticLevel = Level; + DE.WarningOption = DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID); + // Format the message. SmallString<100> MessageStr; Info.FormatDiagnostic(MessageStr); diff --git a/contrib/llvm/tools/clang/lib/Frontend/ModuleDependencyCollector.cpp b/contrib/llvm/tools/clang/lib/Frontend/ModuleDependencyCollector.cpp index d30f921..62865e9 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/ModuleDependencyCollector.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/ModuleDependencyCollector.cpp @@ -13,8 +13,8 @@ #include "clang/Frontend/Utils.h" #include "clang/Serialization/ASTReader.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -38,7 +38,7 @@ public: } void ModuleDependencyCollector::attachToASTReader(ASTReader &R) { - R.addListener(new ModuleDependencyListener(*this)); + R.addListener(llvm::make_unique<ModuleDependencyListener>(*this)); } void ModuleDependencyCollector::writeFileMap() { @@ -48,49 +48,26 @@ void ModuleDependencyCollector::writeFileMap() { SmallString<256> Dest = getDest(); llvm::sys::path::append(Dest, "vfs.yaml"); - std::string ErrorInfo; - llvm::raw_fd_ostream OS(Dest.c_str(), ErrorInfo, llvm::sys::fs::F_Text); - if (!ErrorInfo.empty()) { + std::error_code EC; + llvm::raw_fd_ostream OS(Dest, EC, llvm::sys::fs::F_Text); + if (EC) { setHasErrors(); return; } VFSWriter.write(OS); } -/// Remove traversal (ie, . or ..) from the given absolute path. -static void removePathTraversal(SmallVectorImpl<char> &Path) { - using namespace llvm::sys; - SmallVector<StringRef, 16> ComponentStack; - StringRef P(Path.data(), Path.size()); - - // Skip the root path, then look for traversal in the components. - StringRef Rel = path::relative_path(P); - for (StringRef C : llvm::make_range(path::begin(Rel), path::end(Rel))) { - if (C == ".") - continue; - if (C == "..") { - assert(ComponentStack.size() && "Path traverses out of parent"); - ComponentStack.pop_back(); - } else - ComponentStack.push_back(C); - } - - // The stack is now the path without any directory traversal. - SmallString<256> Buffer = path::root_path(P); - for (StringRef C : ComponentStack) - path::append(Buffer, C); - - // Put the result in Path. - Path.swap(Buffer); -} - std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) { using namespace llvm::sys; // We need an absolute path to append to the root. SmallString<256> AbsoluteSrc = Src; fs::make_absolute(AbsoluteSrc); - removePathTraversal(AbsoluteSrc); + // Canonicalize to a native path to avoid mixed separator styles. + path::native(AbsoluteSrc); + // TODO: We probably need to handle .. as well as . in order to have valid + // input to the YAMLVFSWriter. + FileManager::removeDotPaths(AbsoluteSrc); // Build the destination path. SmallString<256> Dest = Collector.getDest(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp b/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp index 0e933a3..0198828 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/MultiplexConsumer.cpp @@ -107,6 +107,7 @@ public: const ObjCPropertyDecl *OrigProp, const ObjCCategoryDecl *ClassExt) override; void DeclarationMarkedUsed(const Decl *D) override; + void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; private: std::vector<ASTMutationListener*> Listeners; @@ -180,121 +181,121 @@ void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclarationMarkedUsed(D); } +void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( + const Decl *D) { + for (size_t i = 0, e = Listeners.size(); i != e; ++i) + Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); +} } // end namespace clang -MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer *> C) - : Consumers(C.begin(), C.end()), MutationListener(), - DeserializationListener() { +MultiplexConsumer::MultiplexConsumer( + std::vector<std::unique_ptr<ASTConsumer>> C) + : Consumers(std::move(C)), MutationListener(), DeserializationListener() { // Collect the mutation listeners and deserialization listeners of all // children, and create a multiplex listener each if so. std::vector<ASTMutationListener*> mutationListeners; std::vector<ASTDeserializationListener*> serializationListeners; - for (size_t i = 0, e = Consumers.size(); i != e; ++i) { - ASTMutationListener* mutationListener = - Consumers[i]->GetASTMutationListener(); - if (mutationListener) + for (auto &Consumer : Consumers) { + if (auto *mutationListener = Consumer->GetASTMutationListener()) mutationListeners.push_back(mutationListener); - ASTDeserializationListener* serializationListener = - Consumers[i]->GetASTDeserializationListener(); - if (serializationListener) + if (auto *serializationListener = Consumer->GetASTDeserializationListener()) serializationListeners.push_back(serializationListener); } - if (mutationListeners.size()) { - MutationListener.reset(new MultiplexASTMutationListener(mutationListeners)); + if (!mutationListeners.empty()) { + MutationListener = + llvm::make_unique<MultiplexASTMutationListener>(mutationListeners); } - if (serializationListeners.size()) { - DeserializationListener.reset( - new MultiplexASTDeserializationListener(serializationListeners)); + if (!serializationListeners.empty()) { + DeserializationListener = + llvm::make_unique<MultiplexASTDeserializationListener>( + serializationListeners); } } -MultiplexConsumer::~MultiplexConsumer() { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - delete Consumers[i]; -} +MultiplexConsumer::~MultiplexConsumer() {} void MultiplexConsumer::Initialize(ASTContext &Context) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->Initialize(Context); + for (auto &Consumer : Consumers) + Consumer->Initialize(Context); } bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { bool Continue = true; - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Continue = Continue && Consumers[i]->HandleTopLevelDecl(D); + for (auto &Consumer : Consumers) + Continue = Continue && Consumer->HandleTopLevelDecl(D); return Continue; } void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleInlineMethodDefinition(D); + for (auto &Consumer : Consumers) + Consumer->HandleInlineMethodDefinition(D); } -void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleCXXStaticMemberVarInstantiation(VD); +void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { + for (auto &Consumer : Consumers) + Consumer->HandleCXXStaticMemberVarInstantiation(VD); } void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleInterestingDecl(D); + for (auto &Consumer : Consumers) + Consumer->HandleInterestingDecl(D); } void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleTranslationUnit(Ctx); + for (auto &Consumer : Consumers) + Consumer->HandleTranslationUnit(Ctx); } void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleTagDeclDefinition(D); + for (auto &Consumer : Consumers) + Consumer->HandleTagDeclDefinition(D); } void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleTagDeclRequiredDefinition(D); + for (auto &Consumer : Consumers) + Consumer->HandleTagDeclRequiredDefinition(D); } void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){ - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleCXXImplicitFunctionInstantiation(D); + for (auto &Consumer : Consumers) + Consumer->HandleCXXImplicitFunctionInstantiation(D); } void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleTopLevelDeclInObjCContainer(D); + for (auto &Consumer : Consumers) + Consumer->HandleTopLevelDeclInObjCContainer(D); } void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleImplicitImportDecl(D); + for (auto &Consumer : Consumers) + Consumer->HandleImplicitImportDecl(D); } void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleLinkerOptionPragma(Opts); + for (auto &Consumer : Consumers) + Consumer->HandleLinkerOptionPragma(Opts); } void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleDetectMismatch(Name, Value); + for (auto &Consumer : Consumers) + Consumer->HandleDetectMismatch(Name, Value); } void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleDependentLibrary(Lib); + for (auto &Consumer : Consumers) + Consumer->HandleDependentLibrary(Lib); } void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->CompleteTentativeDefinition(D); + for (auto &Consumer : Consumers) + Consumer->CompleteTentativeDefinition(D); } void MultiplexConsumer::HandleVTable( CXXRecordDecl *RD, bool DefinitionRequired) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->HandleVTable(RD, DefinitionRequired); + for (auto &Consumer : Consumers) + Consumer->HandleVTable(RD, DefinitionRequired); } ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { @@ -306,18 +307,18 @@ ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { } void MultiplexConsumer::PrintStats() { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - Consumers[i]->PrintStats(); + for (auto &Consumer : Consumers) + Consumer->PrintStats(); } void MultiplexConsumer::InitializeSema(Sema &S) { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) + for (auto &Consumer : Consumers) + if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) SC->InitializeSema(S); } void MultiplexConsumer::ForgetSema() { - for (size_t i = 0, e = Consumers.size(); i != e; ++i) - if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) + for (auto &Consumer : Consumers) + if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get())) SC->ForgetSema(); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 4a6f8db..7c1d9a5 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -332,7 +332,10 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc, MoveToLine(HashLoc); OS << "@import " << Imported->getFullModuleName() << ";" << " /* clang -E: implicit import for \"" << File->getName() << "\" */"; + // Since we want a newline after the @import, but not a #<line>, start a new + // line immediately. EmittedTokensOnThisLine = true; + startNewLineIfNeeded(); } } @@ -724,7 +727,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, PP.AddPragmaHandler("clang", new UnknownPragmaHandler("#pragma clang", Callbacks)); - PP.addPPCallbacks(Callbacks); + PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks)); // After we have configured the preprocessor, enter the main file. PP.EnterMainSourceFile(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp index 8b7af71..a3e14f9 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FixItRewriter.cpp @@ -36,14 +36,13 @@ FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr, FixItOpts(FixItOpts), NumFailures(0), PrevDiagSilenced(false) { - OwnsClient = Diags.ownsClient(); - Client = Diags.takeClient(); - Diags.setClient(this); + Owner = Diags.takeClient(); + Client = Diags.getClient(); + Diags.setClient(this, false); } FixItRewriter::~FixItRewriter() { - Diags.takeClient(); - Diags.setClient(Client, OwnsClient); + Diags.setClient(Client, Owner.release() != nullptr); } bool FixItRewriter::WriteFixedFile(FileID ID, raw_ostream &OS) { @@ -86,17 +85,16 @@ bool FixItRewriter::WriteFixedFiles( const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first); int fd; std::string Filename = FixItOpts->RewriteFilename(Entry->getName(), fd); - std::string Err; + std::error_code EC; std::unique_ptr<llvm::raw_fd_ostream> OS; if (fd != -1) { OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); } else { - OS.reset(new llvm::raw_fd_ostream(Filename.c_str(), Err, - llvm::sys::fs::F_None)); + OS.reset(new llvm::raw_fd_ostream(Filename, EC, llvm::sys::fs::F_None)); } - if (!Err.empty()) { - Diags.Report(clang::diag::err_fe_unable_to_open_output) - << Filename << Err; + if (EC) { + Diags.Report(clang::diag::err_fe_unable_to_open_output) << Filename + << EC.message(); continue; } RewriteBuffer &RewriteBuf = I->second; @@ -189,12 +187,10 @@ void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) { // When producing this diagnostic, we temporarily bypass ourselves, // clear out any current diagnostic, and let the downstream client // format the diagnostic. - Diags.takeClient(); - Diags.setClient(Client); + Diags.setClient(Client, false); Diags.Clear(); Diags.Report(Loc, DiagID); - Diags.takeClient(); - Diags.setClient(this); + Diags.setClient(this, false); } FixItOptions::~FixItOptions() {} diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp index 59fef73..1b5eb28 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -30,8 +30,8 @@ using namespace clang; // AST Consumer Actions //===----------------------------------------------------------------------===// -ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) return CreateHTMLPrinter(OS, CI.getPreprocessor()); return nullptr; @@ -40,9 +40,9 @@ ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, FixItAction::FixItAction() {} FixItAction::~FixItAction() {} -ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return new ASTConsumer(); +std::unique_ptr<ASTConsumer> +FixItAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return llvm::make_unique<ASTConsumer>(); } namespace { @@ -148,8 +148,8 @@ bool FixItRecompile::BeginInvocation(CompilerInstance &CI) { #ifdef CLANG_ENABLE_OBJC_REWRITER -ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) { if (CI.getLangOpts().ObjCRuntime.isNonFragile()) return CreateModernObjCRewriter(InFile, OS, diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/HTMLPrint.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/HTMLPrint.cpp index 64da05f..22ccfe6 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/HTMLPrint.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/HTMLPrint.cpp @@ -47,11 +47,12 @@ namespace { }; } -ASTConsumer* clang::CreateHTMLPrinter(raw_ostream *OS, - Preprocessor &PP, - bool SyntaxHighlight, - bool HighlightMacros) { - return new HTMLPrinter(OS, PP, SyntaxHighlight, HighlightMacros); +std::unique_ptr<ASTConsumer> clang::CreateHTMLPrinter(raw_ostream *OS, + Preprocessor &PP, + bool SyntaxHighlight, + bool HighlightMacros) { + return llvm::make_unique<HTMLPrinter>(OS, PP, SyntaxHighlight, + HighlightMacros); } void HTMLPrinter::Initialize(ASTContext &context) { diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp index aa7017b..1400557 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -40,6 +40,7 @@ class InclusionRewriter : public PPCallbacks { Preprocessor &PP; ///< Used to find inclusion directives. SourceManager &SM; ///< Used to read and manage source files. raw_ostream &OS; ///< The destination stream for rewritten contents. + StringRef MainEOL; ///< The line ending marker to use. const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines. bool ShowLineMarkers; ///< Show #line markers. bool UseLineDirective; ///< Use of line directives or line markers. @@ -54,6 +55,7 @@ public: void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) { PredefinesBuffer = Buf; } + void detectMainFileEOL(); private: void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, @@ -67,8 +69,8 @@ private: const Module *Imported) override; void WriteLineInfo(const char *Filename, int Line, SrcMgr::CharacteristicKind FileType, - StringRef EOL, StringRef Extra = StringRef()); - void WriteImplicitModuleImport(const Module *Mod, StringRef EOL); + StringRef Extra = StringRef()); + void WriteImplicitModuleImport(const Module *Mod); void OutputContentUpTo(const MemoryBuffer &FromFile, unsigned &WriteFrom, unsigned WriteTo, StringRef EOL, int &lines, @@ -88,9 +90,9 @@ private: /// Initializes an InclusionRewriter with a \p PP source and \p OS destination. InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers) - : PP(PP), SM(PP.getSourceManager()), OS(OS), PredefinesBuffer(nullptr), - ShowLineMarkers(ShowLineMarkers), - LastInsertedFileChange(FileChanges.end()) { + : PP(PP), SM(PP.getSourceManager()), OS(OS), MainEOL("\n"), + PredefinesBuffer(nullptr), ShowLineMarkers(ShowLineMarkers), + LastInsertedFileChange(FileChanges.end()) { // If we're in microsoft mode, use normal #line instead of line markers. UseLineDirective = PP.getLangOpts().MicrosoftExt; } @@ -101,7 +103,7 @@ InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS, /// any \p Extra context specifiers in GNU line directives. void InclusionRewriter::WriteLineInfo(const char *Filename, int Line, SrcMgr::CharacteristicKind FileType, - StringRef EOL, StringRef Extra) { + StringRef Extra) { if (!ShowLineMarkers) return; if (UseLineDirective) { @@ -125,13 +127,12 @@ void InclusionRewriter::WriteLineInfo(const char *Filename, int Line, // should be treated as being wrapped in an implicit extern "C" block." OS << " 3 4"; } - OS << EOL; + OS << MainEOL; } -void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod, - StringRef EOL) { +void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod) { OS << "@import " << Mod->getFullModuleName() << ";" - << " /* clang -frewrite-includes: implicit import */" << EOL; + << " /* clang -frewrite-includes: implicit import */" << MainEOL; } /// FileChanged - Whenever the preprocessor enters or exits a #include file @@ -197,23 +198,33 @@ InclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const { /// Detect the likely line ending style of \p FromFile by examining the first /// newline found within it. static StringRef DetectEOL(const MemoryBuffer &FromFile) { - // detect what line endings the file uses, so that added content does not mix - // the style + // Detect what line endings the file uses, so that added content does not mix + // the style. We need to check for "\r\n" first because "\n\r" will match + // "\r\n\r\n". const char *Pos = strchr(FromFile.getBufferStart(), '\n'); if (!Pos) return "\n"; - if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r') - return "\n\r"; if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r') return "\r\n"; + if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r') + return "\n\r"; return "\n"; } +void InclusionRewriter::detectMainFileEOL() { + bool Invalid; + const MemoryBuffer &FromFile = *SM.getBuffer(SM.getMainFileID(), &Invalid); + assert(!Invalid); + if (Invalid) + return; // Should never happen, but whatever. + MainEOL = DetectEOL(FromFile); +} + /// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at /// \p WriteTo - 1. void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile, unsigned &WriteFrom, unsigned WriteTo, - StringRef EOL, int &Line, + StringRef LocalEOL, int &Line, bool EnsureNewline) { if (WriteTo <= WriteFrom) return; @@ -222,14 +233,37 @@ void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile, WriteFrom = WriteTo; return; } - OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom); - // count lines manually, it's faster than getPresumedLoc() - Line += std::count(FromFile.getBufferStart() + WriteFrom, - FromFile.getBufferStart() + WriteTo, '\n'); - if (EnsureNewline) { - char LastChar = FromFile.getBufferStart()[WriteTo - 1]; - if (LastChar != '\n' && LastChar != '\r') - OS << EOL; + + // If we would output half of a line ending, advance one character to output + // the whole line ending. All buffers are null terminated, so looking ahead + // one byte is safe. + if (LocalEOL.size() == 2 && + LocalEOL[0] == (FromFile.getBufferStart() + WriteTo)[-1] && + LocalEOL[1] == (FromFile.getBufferStart() + WriteTo)[0]) + WriteTo++; + + StringRef TextToWrite(FromFile.getBufferStart() + WriteFrom, + WriteTo - WriteFrom); + + if (MainEOL == LocalEOL) { + OS << TextToWrite; + // count lines manually, it's faster than getPresumedLoc() + Line += TextToWrite.count(LocalEOL); + if (EnsureNewline && !TextToWrite.endswith(LocalEOL)) + OS << MainEOL; + } else { + // Output the file one line at a time, rewriting the line endings as we go. + StringRef Rest = TextToWrite; + while (!Rest.empty()) { + StringRef LineText; + std::tie(LineText, Rest) = Rest.split(LocalEOL); + OS << LineText; + Line++; + if (!Rest.empty()) + OS << MainEOL; + } + if (TextToWrite.endswith(LocalEOL) || EnsureNewline) + OS << MainEOL; } WriteFrom = WriteTo; } @@ -242,10 +276,11 @@ void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile, void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex, const Token &StartToken, const MemoryBuffer &FromFile, - StringRef EOL, + StringRef LocalEOL, unsigned &NextToWrite, int &Line) { OutputContentUpTo(FromFile, NextToWrite, - SM.getFileOffset(StartToken.getLocation()), EOL, Line, false); + SM.getFileOffset(StartToken.getLocation()), LocalEOL, Line, + false); Token DirectiveToken; do { DirectiveLex.LexFromRawLexer(DirectiveToken); @@ -254,11 +289,12 @@ void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex, // OutputContentUpTo() would not output anything anyway. return; } - OS << "#if 0 /* expanded by -frewrite-includes */" << EOL; + OS << "#if 0 /* expanded by -frewrite-includes */" << MainEOL; OutputContentUpTo(FromFile, NextToWrite, - SM.getFileOffset(DirectiveToken.getLocation()) + DirectiveToken.getLength(), - EOL, Line, true); - OS << "#endif /* expanded by -frewrite-includes */" << EOL; + SM.getFileOffset(DirectiveToken.getLocation()) + + DirectiveToken.getLength(), + LocalEOL, Line, true); + OS << "#endif /* expanded by -frewrite-includes */" << MainEOL; } /// Find the next identifier in the pragma directive specified by \p RawToken. @@ -333,10 +369,13 @@ bool InclusionRewriter::HandleHasInclude( // FIXME: Subframeworks aren't handled here. Do we care? bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename); const DirectoryLookup *CurDir; + const FileEntry *FileEnt = PP.getSourceManager().getFileEntryForID(FileId); + SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 1> + Includers; + Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir())); const FileEntry *File = PP.getHeaderSearchInfo().LookupFile( - Filename, SourceLocation(), isAngled, nullptr, CurDir, - PP.getSourceManager().getFileEntryForID(FileId), nullptr, nullptr, - nullptr, false); + Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr, + nullptr, nullptr, false); FileExists = File != nullptr; return true; @@ -355,13 +394,13 @@ bool InclusionRewriter::Process(FileID FileId, Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts()); RawLex.SetCommentRetentionState(false); - StringRef EOL = DetectEOL(FromFile); + StringRef LocalEOL = DetectEOL(FromFile); // Per the GNU docs: "1" indicates entering a new file. if (FileId == SM.getMainFileID() || FileId == PP.getPredefinesFileID()) - WriteLineInfo(FileName, 1, FileType, EOL, ""); + WriteLineInfo(FileName, 1, FileType, ""); else - WriteLineInfo(FileName, 1, FileType, EOL, " 1"); + WriteLineInfo(FileName, 1, FileType, " 1"); if (SM.getFileIDSize(FileId) == 0) return false; @@ -389,15 +428,15 @@ bool InclusionRewriter::Process(FileID FileId, case tok::pp_include: case tok::pp_include_next: case tok::pp_import: { - CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite, + CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL, NextToWrite, Line); if (FileId != PP.getPredefinesFileID()) - WriteLineInfo(FileName, Line - 1, FileType, EOL, ""); + WriteLineInfo(FileName, Line - 1, FileType, ""); StringRef LineInfoExtra; if (const FileChange *Change = FindFileChangeLocation( HashToken.getLocation())) { if (Change->Mod) { - WriteImplicitModuleImport(Change->Mod, EOL); + WriteImplicitModuleImport(Change->Mod); // else now include and recursively process the file } else if (Process(Change->Id, Change->FileType)) { @@ -410,7 +449,7 @@ bool InclusionRewriter::Process(FileID FileId, } // fix up lineinfo (since commented out directive changed line // numbers) for inclusions that were skipped due to header guards - WriteLineInfo(FileName, Line, FileType, EOL, LineInfoExtra); + WriteLineInfo(FileName, Line, FileType, LineInfoExtra); break; } case tok::pp_pragma: { @@ -418,17 +457,17 @@ bool InclusionRewriter::Process(FileID FileId, if (Identifier == "clang" || Identifier == "GCC") { if (NextIdentifierName(RawLex, RawToken) == "system_header") { // keep the directive in, commented out - CommentOutDirective(RawLex, HashToken, FromFile, EOL, + CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL, NextToWrite, Line); // update our own type FileType = SM.getFileCharacteristic(RawToken.getLocation()); - WriteLineInfo(FileName, Line, FileType, EOL); + WriteLineInfo(FileName, Line, FileType); } } else if (Identifier == "once") { // keep the directive in, commented out - CommentOutDirective(RawLex, HashToken, FromFile, EOL, + CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL, NextToWrite, Line); - WriteLineInfo(FileName, Line, FileType, EOL); + WriteLineInfo(FileName, Line, FileType); } break; } @@ -468,12 +507,12 @@ bool InclusionRewriter::Process(FileID FileId, // Replace the macro with (0) or (1), followed by the commented // out macro for reference. OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc), - EOL, Line, false); + LocalEOL, Line, false); OS << '(' << (int) HasFile << ")/*"; OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(RawToken.getLocation()) + - RawToken.getLength(), - EOL, Line, false); + RawToken.getLength(), + LocalEOL, Line, false); OS << "*/"; } } while (RawToken.isNot(tok::eod)); @@ -481,8 +520,8 @@ bool InclusionRewriter::Process(FileID FileId, OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(RawToken.getLocation()) + RawToken.getLength(), - EOL, Line, /*EnsureNewLine*/ true); - WriteLineInfo(FileName, Line, FileType, EOL); + LocalEOL, Line, /*EnsureNewline=*/ true); + WriteLineInfo(FileName, Line, FileType); } break; } @@ -497,11 +536,11 @@ bool InclusionRewriter::Process(FileID FileId, do { RawLex.LexFromRawLexer(RawToken); } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof)); - OutputContentUpTo( - FromFile, NextToWrite, - SM.getFileOffset(RawToken.getLocation()) + RawToken.getLength(), - EOL, Line, /*EnsureNewLine*/ true); - WriteLineInfo(FileName, Line, FileType, EOL); + OutputContentUpTo(FromFile, NextToWrite, + SM.getFileOffset(RawToken.getLocation()) + + RawToken.getLength(), + LocalEOL, Line, /*EnsureNewline=*/ true); + WriteLineInfo(FileName, Line, FileType); RawLex.SetKeepWhitespaceMode(false); } default: @@ -513,8 +552,8 @@ bool InclusionRewriter::Process(FileID FileId, RawLex.LexFromRawLexer(RawToken); } OutputContentUpTo(FromFile, NextToWrite, - SM.getFileOffset(SM.getLocForEndOfFile(FileId)), EOL, Line, - /*EnsureNewline*/true); + SM.getFileOffset(SM.getLocForEndOfFile(FileId)), LocalEOL, + Line, /*EnsureNewline=*/true); return true; } @@ -524,7 +563,9 @@ void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, SourceManager &SM = PP.getSourceManager(); InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS, Opts.ShowLineMarkers); - PP.addPPCallbacks(Rewrite); + Rewrite->detectMainFileEOL(); + + PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Rewrite)); PP.IgnorePragmas(); // First let the preprocessor process the entire file and call callbacks. diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 3e18a8b..47f8189 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -249,27 +249,16 @@ namespace { void HandleTranslationUnit(ASTContext &C) override; void ReplaceStmt(Stmt *Old, Stmt *New) { - Stmt *ReplacingStmt = ReplacedNodes[Old]; - - if (ReplacingStmt) - return; // We can't rewrite the same node twice. - - if (DisableReplaceStmt) - return; - - // If replacement succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceStmt(Old, New)) { - ReplacedNodes[Old] = New; - return; - } - if (SilenceRewriteMacroWarning) - return; - Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) - << Old->getSourceRange(); + ReplaceStmtWithRange(Old, New, Old->getSourceRange()); } void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); + + Stmt *ReplacingStmt = ReplacedNodes[Old]; + if (ReplacingStmt) + return; // We can't rewrite the same node twice. + if (DisableReplaceStmt) return; @@ -508,7 +497,7 @@ namespace { void GetBlockDeclRefExprs(Stmt *S); void GetInnerBlockDeclRefExprs(Stmt *S, SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, - llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts); + llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts); // We avoid calling Type::isBlockPointerType(), since it operates on the // canonical type. We only care if the top-level type is a closure pointer. @@ -675,14 +664,11 @@ RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS, "for @try/@finally (code may not execute properly)"); } -ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile, - raw_ostream* OS, - DiagnosticsEngine &Diags, - const LangOptions &LOpts, - bool SilenceRewriteMacroWarning, - bool LineInfo) { - return new RewriteModernObjC(InFile, OS, Diags, LOpts, - SilenceRewriteMacroWarning, LineInfo); +std::unique_ptr<ASTConsumer> clang::CreateModernObjCRewriter( + const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, + const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo) { + return llvm::make_unique<RewriteModernObjC>( + InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning, LineInfo); } void RewriteModernObjC::InitializeCommon(ASTContext &context) { @@ -4055,7 +4041,7 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); ReplaceText(LocStart, endBuf-startBuf, Result); // Mark this struct as having been generated. - if (!ObjCSynthesizedStructs.insert(CDecl)) + if (!ObjCSynthesizedStructs.insert(CDecl).second) llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct"); } @@ -4070,9 +4056,7 @@ void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, return; llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput; - for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(), - e = Ivars.end(); i != e; i++) { - ObjCIvarDecl *IvarDecl = (*i); + for (ObjCIvarDecl *IvarDecl : Ivars) { const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface(); unsigned GroupNo = 0; if (IvarDecl->isBitField()) { @@ -4256,14 +4240,12 @@ std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, S += "(" + StructRef; S += "*dst, " + StructRef; S += "*src) {"; - for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), - E = ImportedBlockDecls.end(); I != E; ++I) { - ValueDecl *VD = (*I); + for (ValueDecl *VD : ImportedBlockDecls) { S += "_Block_object_assign((void*)&dst->"; - S += (*I)->getNameAsString(); + S += VD->getNameAsString(); S += ", (void*)src->"; - S += (*I)->getNameAsString(); - if (BlockByRefDeclsPtrSet.count((*I))) + S += VD->getNameAsString(); + if (BlockByRefDeclsPtrSet.count(VD)) S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; else if (VD->getType()->isBlockPointerType()) S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; @@ -4277,12 +4259,10 @@ std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, S += "_block_dispose_" + utostr(i); S += "(" + StructRef; S += "*src) {"; - for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), - E = ImportedBlockDecls.end(); I != E; ++I) { - ValueDecl *VD = (*I); + for (ValueDecl *VD : ImportedBlockDecls) { S += "_Block_object_dispose((void*)src->"; - S += (*I)->getNameAsString(); - if (BlockByRefDeclsPtrSet.count((*I))) + S += VD->getNameAsString(); + if (BlockByRefDeclsPtrSet.count(VD)) S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; else if (VD->getType()->isBlockPointerType()) S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; @@ -4583,22 +4563,18 @@ void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) { GetBlockDeclRefExprs(*CI); } // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { - if (DRE->refersToEnclosingLocal()) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) + if (DRE->refersToEnclosingVariableOrCapture() || + HasLocalVariableExternalStorage(DRE->getDecl())) // FIXME: Handle enums. - if (!isa<FunctionDecl>(DRE->getDecl())) - BlockDeclRefs.push_back(DRE); - if (HasLocalVariableExternalStorage(DRE->getDecl())) - BlockDeclRefs.push_back(DRE); - } - } - + BlockDeclRefs.push_back(DRE); + return; } void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, - llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { + llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) { for (Stmt::child_range CI = S->children(); CI; ++CI) if (*CI) { if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { @@ -4615,11 +4591,11 @@ void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, } // Handle specific things. if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { - if (DRE->refersToEnclosingLocal()) { - if (!isa<FunctionDecl>(DRE->getDecl()) && - !InnerContexts.count(DRE->getDecl()->getDeclContext())) + if (DRE->refersToEnclosingVariableOrCapture() || + HasLocalVariableExternalStorage(DRE->getDecl())) { + if (!InnerContexts.count(DRE->getDecl()->getDeclContext())) InnerBlockDeclRefs.push_back(DRE); - if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) + if (VarDecl *Var = cast<VarDecl>(DRE->getDecl())) if (Var->isFunctionOrMethodVarDecl()) ImportedLocalExternalDecls.insert(Var); } @@ -4796,7 +4772,8 @@ Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR // for each DeclRefExp where BYREFVAR is name of the variable. ValueDecl *VD = DeclRefExp->getDecl(); - bool isArrow = DeclRefExp->refersToEnclosingLocal(); + bool isArrow = DeclRefExp->refersToEnclosingVariableOrCapture() || + HasLocalVariableExternalStorage(DeclRefExp->getDecl()); FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), @@ -5546,6 +5523,10 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, VK_RValue, OK_Ordinary, SourceLocation()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); + // Put Paren around the call. + NewRep = new (Context) ParenExpr(SourceLocation(), SourceLocation(), + NewRep); + BlockDeclRefs.clear(); BlockByRefDecls.clear(); BlockByRefDeclsPtrSet.clear(); @@ -5978,10 +5959,9 @@ void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) { // Here's a great place to add any extra declarations that may be needed. // Write out meta data for each @protocol(<expr>). - for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), - E = ProtocolExprDecls.end(); I != E; ++I) { - RewriteObjCProtocolMetaData(*I, Preamble); - Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble); + for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { + RewriteObjCProtocolMetaData(ProtDecl, Preamble); + Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble); } InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); @@ -7122,7 +7102,7 @@ void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, Result += ";\n"; // Mark this protocol as having been generated. - if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) + if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) llvm_unreachable("protocol already synthesized"); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 7a72177..5196810 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -198,27 +198,16 @@ namespace { void HandleTranslationUnit(ASTContext &C) override; void ReplaceStmt(Stmt *Old, Stmt *New) { - Stmt *ReplacingStmt = ReplacedNodes[Old]; - - if (ReplacingStmt) - return; // We can't rewrite the same node twice. - - if (DisableReplaceStmt) - return; - - // If replacement succeeded or warning disabled return with no warning. - if (!Rewrite.ReplaceStmt(Old, New)) { - ReplacedNodes[Old] = New; - return; - } - if (SilenceRewriteMacroWarning) - return; - Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) - << Old->getSourceRange(); + ReplaceStmtWithRange(Old, New, Old->getSourceRange()); } void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); + + Stmt *ReplacingStmt = ReplacedNodes[Old]; + if (ReplacingStmt) + return; // We can't rewrite the same node twice. + if (DisableReplaceStmt) return; @@ -332,7 +321,7 @@ namespace { void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, std::string &Result); - virtual void Initialize(ASTContext &context) override = 0; + void Initialize(ASTContext &context) override = 0; // Metadata Rewriting. virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0; @@ -413,7 +402,7 @@ namespace { void GetBlockDeclRefExprs(Stmt *S); void GetInnerBlockDeclRefExprs(Stmt *S, SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, - llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts); + llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts); // We avoid calling Type::isBlockPointerType(), since it operates on the // canonical type. We only care if the top-level type is a closure pointer. @@ -524,7 +513,7 @@ namespace { silenceMacroWarn) {} ~RewriteObjCFragileABI() {} - virtual void Initialize(ASTContext &context) override; + void Initialize(ASTContext &context) override; // Rewriting metadata template<typename MethodIterator> @@ -600,12 +589,12 @@ RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, "for @try/@finally (code may not execute properly)"); } -ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile, - raw_ostream* OS, - DiagnosticsEngine &Diags, - const LangOptions &LOpts, - bool SilenceRewriteMacroWarning) { - return new RewriteObjCFragileABI(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning); +std::unique_ptr<ASTConsumer> +clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, + DiagnosticsEngine &Diags, const LangOptions &LOpts, + bool SilenceRewriteMacroWarning) { + return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts, + SilenceRewriteMacroWarning); } void RewriteObjC::InitializeCommon(ASTContext &context) { @@ -3238,7 +3227,7 @@ void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, ReplaceText(LocStart, endBuf-startBuf, Result); } // Mark this struct as having been generated. - if (!ObjCSynthesizedStructs.insert(CDecl)) + if (!ObjCSynthesizedStructs.insert(CDecl).second) llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct"); } @@ -3382,14 +3371,12 @@ std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, S += "(" + StructRef; S += "*dst, " + StructRef; S += "*src) {"; - for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), - E = ImportedBlockDecls.end(); I != E; ++I) { - ValueDecl *VD = (*I); + for (ValueDecl *VD : ImportedBlockDecls) { S += "_Block_object_assign((void*)&dst->"; - S += (*I)->getNameAsString(); + S += VD->getNameAsString(); S += ", (void*)src->"; - S += (*I)->getNameAsString(); - if (BlockByRefDeclsPtrSet.count((*I))) + S += VD->getNameAsString(); + if (BlockByRefDeclsPtrSet.count(VD)) S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; else if (VD->getType()->isBlockPointerType()) S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; @@ -3403,12 +3390,10 @@ std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, S += "_block_dispose_" + utostr(i); S += "(" + StructRef; S += "*src) {"; - for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), - E = ImportedBlockDecls.end(); I != E; ++I) { - ValueDecl *VD = (*I); + for (ValueDecl *VD : ImportedBlockDecls) { S += "_Block_object_dispose((void*)src->"; - S += (*I)->getNameAsString(); - if (BlockByRefDeclsPtrSet.count((*I))) + S += VD->getNameAsString(); + if (BlockByRefDeclsPtrSet.count(VD)) S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; else if (VD->getType()->isBlockPointerType()) S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; @@ -3686,22 +3671,18 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { GetBlockDeclRefExprs(*CI); } // Handle specific things. - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { - if (DRE->refersToEnclosingLocal()) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) + if (DRE->refersToEnclosingVariableOrCapture() || + HasLocalVariableExternalStorage(DRE->getDecl())) // FIXME: Handle enums. - if (!isa<FunctionDecl>(DRE->getDecl())) - BlockDeclRefs.push_back(DRE); - if (HasLocalVariableExternalStorage(DRE->getDecl())) - BlockDeclRefs.push_back(DRE); - } - } - + BlockDeclRefs.push_back(DRE); + return; } void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, - llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { + llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) { for (Stmt::child_range CI = S->children(); CI; ++CI) if (*CI) { if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { @@ -3718,11 +3699,11 @@ void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, } // Handle specific things. if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { - if (DRE->refersToEnclosingLocal()) { - if (!isa<FunctionDecl>(DRE->getDecl()) && - !InnerContexts.count(DRE->getDecl()->getDeclContext())) + if (DRE->refersToEnclosingVariableOrCapture() || + HasLocalVariableExternalStorage(DRE->getDecl())) { + if (!InnerContexts.count(DRE->getDecl()->getDeclContext())) InnerBlockDeclRefs.push_back(DRE); - if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) + if (VarDecl *Var = cast<VarDecl>(DRE->getDecl())) if (Var->isFunctionOrMethodVarDecl()) ImportedLocalExternalDecls.insert(Var); } @@ -3880,7 +3861,8 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR // for each DeclRefExp where BYREFVAR is name of the variable. ValueDecl *VD = DeclRefExp->getDecl(); - bool isArrow = DeclRefExp->refersToEnclosingLocal(); + bool isArrow = DeclRefExp->refersToEnclosingVariableOrCapture() || + HasLocalVariableExternalStorage(DeclRefExp->getDecl()); FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), @@ -4967,9 +4949,8 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) { // Here's a great place to add any extra declarations that may be needed. // Write out meta data for each @protocol(<expr>). - for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), - E = ProtocolExprDecls.end(); I != E; ++I) - RewriteObjCProtocolMetaData(*I, "", "", Preamble); + for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) + RewriteObjCProtocolMetaData(ProtDecl, "", "", Preamble); InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); if (ClassImplementation.size() || CategoryImplementation.size()) @@ -5276,7 +5257,7 @@ void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( Result += "};\n"; // Mark this protocol as having been generated. - if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) + if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) llvm_unreachable("protocol already synthesized"); } @@ -5657,12 +5638,11 @@ void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) { if (ProtocolExprDecls.size()) { Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; - for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), - E = ProtocolExprDecls.end(); I != E; ++I) { + for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; - Result += (*I)->getNameAsString(); + Result += ProtDecl->getNameAsString(); Result += " = &_OBJC_PROTOCOL_"; - Result += (*I)->getNameAsString(); + Result += ProtDecl->getNameAsString(); Result += ";\n"; } Result += "#pragma data_seg(pop)\n\n"; diff --git a/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index 29c58a8..f701f72 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -14,6 +14,10 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" #include "clang/Frontend/DiagnosticRenderer.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/SerializedDiagnosticReader.h" +#include "clang/Frontend/SerializedDiagnostics.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" @@ -86,20 +90,70 @@ protected: void endDiagnostic(DiagOrStoredDiag D, DiagnosticsEngine::Level Level) override; }; - + +typedef llvm::DenseMap<unsigned, unsigned> AbbrevLookup; + +class SDiagsMerger : SerializedDiagnosticReader { + SDiagsWriter &Writer; + AbbrevLookup FileLookup; + AbbrevLookup CategoryLookup; + AbbrevLookup DiagFlagLookup; + +public: + SDiagsMerger(SDiagsWriter &Writer) + : SerializedDiagnosticReader(), Writer(Writer) {} + + std::error_code mergeRecordsFromFile(const char *File) { + return readDiagnostics(File); + } + +protected: + std::error_code visitStartOfDiagnostic() override; + std::error_code visitEndOfDiagnostic() override; + std::error_code visitCategoryRecord(unsigned ID, StringRef Name) override; + std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) override; + std::error_code visitDiagnosticRecord( + unsigned Severity, const serialized_diags::Location &Location, + unsigned Category, unsigned Flag, StringRef Message) override; + std::error_code visitFilenameRecord(unsigned ID, unsigned Size, + unsigned Timestamp, + StringRef Name) override; + std::error_code visitFixitRecord(const serialized_diags::Location &Start, + const serialized_diags::Location &End, + StringRef CodeToInsert) override; + std::error_code + visitSourceRangeRecord(const serialized_diags::Location &Start, + const serialized_diags::Location &End) override; + +private: + std::error_code adjustSourceLocFilename(RecordData &Record, + unsigned int offset); + + void adjustAbbrevID(RecordData &Record, AbbrevLookup &Lookup, + unsigned NewAbbrev); + + void writeRecordWithAbbrev(unsigned ID, RecordData &Record); + + void writeRecordWithBlob(unsigned ID, RecordData &Record, StringRef Blob); +}; + class SDiagsWriter : public DiagnosticConsumer { friend class SDiagsRenderer; + friend class SDiagsMerger; struct SharedState; explicit SDiagsWriter(IntrusiveRefCntPtr<SharedState> State) - : LangOpts(nullptr), OriginalInstance(false), State(State) {} + : LangOpts(nullptr), OriginalInstance(false), MergeChildRecords(false), + State(State) {} public: - SDiagsWriter(raw_ostream *os, DiagnosticOptions *diags) - : LangOpts(nullptr), OriginalInstance(true), - State(new SharedState(os, diags)) - { + SDiagsWriter(StringRef File, DiagnosticOptions *Diags, bool MergeChildRecords) + : LangOpts(nullptr), OriginalInstance(true), + MergeChildRecords(MergeChildRecords), + State(new SharedState(File, Diags)) { + if (MergeChildRecords) + RemoveOldDiagnostics(); EmitPreamble(); } @@ -115,6 +169,14 @@ public: void finish() override; private: + /// \brief Build a DiagnosticsEngine to emit diagnostics about the diagnostics + DiagnosticsEngine *getMetaDiags(); + + /// \brief Remove old copies of the serialized diagnostics. This is necessary + /// so that we can detect when subprocesses write diagnostics that we should + /// merge into our own. + void RemoveOldDiagnostics(); + /// \brief Emit the preamble for the serialized diagnostics. void EmitPreamble(); @@ -152,7 +214,9 @@ private: /// \brief Emit the string information for diagnostic flags. unsigned getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel, unsigned DiagID = 0); - + + unsigned getEmitDiagnosticFlag(StringRef DiagName); + /// \brief Emit (lazily) the file string and retrieved the file identifier. unsigned getEmitFile(const char *Filename); @@ -173,9 +237,6 @@ private: void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record, const SourceManager &SM); - /// \brief The version of the diagnostics file. - enum { Version = 2 }; - /// \brief Language options, which can differ from one clone of this client /// to another. const LangOptions *LangOpts; @@ -184,11 +245,16 @@ private: /// clones), responsible for writing the file at the end. bool OriginalInstance; + /// \brief Whether this instance should aggregate diagnostics that are + /// generated from child processes. + bool MergeChildRecords; + /// \brief State that is shared among the various clones of this diagnostic /// consumer. struct SharedState : RefCountedBase<SharedState> { - SharedState(raw_ostream *os, DiagnosticOptions *diags) - : DiagOpts(diags), Stream(Buffer), OS(os), EmittedAnyDiagBlocks(false) { } + SharedState(StringRef File, DiagnosticOptions *Diags) + : DiagOpts(Diags), Stream(Buffer), OutputFile(File.str()), + EmittedAnyDiagBlocks(false) {} /// \brief Diagnostic options. IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; @@ -200,7 +266,7 @@ private: llvm::BitstreamWriter Stream; /// \brief The name of the diagnostics file. - std::unique_ptr<raw_ostream> OS; + std::string OutputFile; /// \brief The set of constructed record abbreviations. AbbreviationMap Abbrevs; @@ -227,6 +293,9 @@ private: /// this becomes \c true, we never close a DIAG block until we know that we're /// starting another one or we're done. bool EmittedAnyDiagBlocks; + + /// \brief Engine for emitting diagnostics about the diagnostics. + std::unique_ptr<DiagnosticsEngine> MetaDiagnostics; }; /// \brief State shared among the various clones of this diagnostic consumer. @@ -236,9 +305,11 @@ private: namespace clang { namespace serialized_diags { -DiagnosticConsumer *create(raw_ostream *OS, DiagnosticOptions *diags) { - return new SDiagsWriter(OS, diags); +std::unique_ptr<DiagnosticConsumer> +create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords) { + return llvm::make_unique<SDiagsWriter>(OutputFile, Diags, MergeChildRecords); } + } // end namespace serialized_diags } // end namespace clang @@ -465,17 +536,15 @@ void SDiagsWriter::EmitMetaBlock() { Stream.EnterSubblock(BLOCK_META, 3); Record.clear(); Record.push_back(RECORD_VERSION); - Record.push_back(Version); + Record.push_back(VersionNumber); Stream.EmitRecordWithAbbrev(Abbrevs.get(RECORD_VERSION), Record); Stream.ExitBlock(); } unsigned SDiagsWriter::getEmitCategory(unsigned int category) { - if (State->Categories.count(category)) + if (!State->Categories.insert(category).second) return category; - - State->Categories.insert(category); - + // We use a local version of 'Record' so that we can be generating // another record when we lazily generate one for the category entry. RecordData Record; @@ -495,6 +564,10 @@ unsigned SDiagsWriter::getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel, return 0; // No flag for notes. StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(DiagID); + return getEmitDiagnosticFlag(FlagName); +} + +unsigned SDiagsWriter::getEmitDiagnosticFlag(StringRef FlagName) { if (FlagName.empty()) return 0; @@ -689,6 +762,40 @@ void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message, Writer.ExitDiagBlock(); } +DiagnosticsEngine *SDiagsWriter::getMetaDiags() { + // FIXME: It's slightly absurd to create a new diagnostics engine here, but + // the other options that are available today are worse: + // + // 1. Teach DiagnosticsConsumers to emit diagnostics to the engine they are a + // part of. The DiagnosticsEngine would need to know not to send + // diagnostics back to the consumer that failed. This would require us to + // rework ChainedDiagnosticsConsumer and teach the engine about multiple + // consumers, which is difficult today because most APIs interface with + // consumers rather than the engine itself. + // + // 2. Pass a DiagnosticsEngine to SDiagsWriter on creation - this would need + // to be distinct from the engine the writer was being added to and would + // normally not be used. + if (!State->MetaDiagnostics) { + IntrusiveRefCntPtr<DiagnosticIDs> IDs(new DiagnosticIDs()); + auto Client = + new TextDiagnosticPrinter(llvm::errs(), State->DiagOpts.get()); + State->MetaDiagnostics = llvm::make_unique<DiagnosticsEngine>( + IDs, State->DiagOpts.get(), Client); + } + return State->MetaDiagnostics.get(); +} + +void SDiagsWriter::RemoveOldDiagnostics() { + if (!llvm::sys::fs::remove(State->OutputFile)) + return; + + getMetaDiags()->Report(diag::warn_fe_serialized_diag_merge_failure); + // Disable merging child records, as whatever is in this file may be + // misleading. + MergeChildRecords = false; +} + void SDiagsWriter::finish() { // The original instance is responsible for writing the file. if (!OriginalInstance) @@ -698,9 +805,113 @@ void SDiagsWriter::finish() { if (State->EmittedAnyDiagBlocks) ExitDiagBlock(); + if (MergeChildRecords) { + if (!State->EmittedAnyDiagBlocks) + // We have no diagnostics of our own, so we can just leave the child + // process' output alone + return; + + if (llvm::sys::fs::exists(State->OutputFile)) + if (SDiagsMerger(*this).mergeRecordsFromFile(State->OutputFile.c_str())) + getMetaDiags()->Report(diag::warn_fe_serialized_diag_merge_failure); + } + + std::error_code EC; + auto OS = llvm::make_unique<llvm::raw_fd_ostream>(State->OutputFile.c_str(), + EC, llvm::sys::fs::F_None); + if (EC) { + getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) + << State->OutputFile << EC.message(); + return; + } + // Write the generated bitstream to "Out". - State->OS->write((char *)&State->Buffer.front(), State->Buffer.size()); - State->OS->flush(); + OS->write((char *)&State->Buffer.front(), State->Buffer.size()); + OS->flush(); +} + +std::error_code SDiagsMerger::visitStartOfDiagnostic() { + Writer.EnterDiagBlock(); + return std::error_code(); +} + +std::error_code SDiagsMerger::visitEndOfDiagnostic() { + Writer.ExitDiagBlock(); + return std::error_code(); +} + +std::error_code +SDiagsMerger::visitSourceRangeRecord(const serialized_diags::Location &Start, + const serialized_diags::Location &End) { + RecordData Record; + Record.push_back(RECORD_SOURCE_RANGE); + Record.push_back(FileLookup[Start.FileID]); + Record.push_back(Start.Line); + Record.push_back(Start.Col); + Record.push_back(Start.Offset); + Record.push_back(FileLookup[End.FileID]); + Record.push_back(End.Line); + Record.push_back(End.Col); + Record.push_back(End.Offset); + + Writer.State->Stream.EmitRecordWithAbbrev( + Writer.State->Abbrevs.get(RECORD_SOURCE_RANGE), Record); + return std::error_code(); +} + +std::error_code SDiagsMerger::visitDiagnosticRecord( + unsigned Severity, const serialized_diags::Location &Location, + unsigned Category, unsigned Flag, StringRef Message) { + RecordData MergedRecord; + MergedRecord.push_back(RECORD_DIAG); + MergedRecord.push_back(Severity); + MergedRecord.push_back(FileLookup[Location.FileID]); + MergedRecord.push_back(Location.Line); + MergedRecord.push_back(Location.Col); + MergedRecord.push_back(Location.Offset); + MergedRecord.push_back(CategoryLookup[Category]); + MergedRecord.push_back(Flag ? DiagFlagLookup[Flag] : 0); + MergedRecord.push_back(Message.size()); + + Writer.State->Stream.EmitRecordWithBlob( + Writer.State->Abbrevs.get(RECORD_DIAG), MergedRecord, Message); + return std::error_code(); +} + +std::error_code +SDiagsMerger::visitFixitRecord(const serialized_diags::Location &Start, + const serialized_diags::Location &End, + StringRef Text) { + RecordData Record; + Record.push_back(RECORD_FIXIT); + Record.push_back(FileLookup[Start.FileID]); + Record.push_back(Start.Line); + Record.push_back(Start.Col); + Record.push_back(Start.Offset); + Record.push_back(FileLookup[End.FileID]); + Record.push_back(End.Line); + Record.push_back(End.Col); + Record.push_back(End.Offset); + Record.push_back(Text.size()); + + Writer.State->Stream.EmitRecordWithBlob( + Writer.State->Abbrevs.get(RECORD_FIXIT), Record, Text); + return std::error_code(); +} + +std::error_code SDiagsMerger::visitFilenameRecord(unsigned ID, unsigned Size, + unsigned Timestamp, + StringRef Name) { + FileLookup[ID] = Writer.getEmitFile(Name.str().c_str()); + return std::error_code(); +} + +std::error_code SDiagsMerger::visitCategoryRecord(unsigned ID, StringRef Name) { + CategoryLookup[ID] = Writer.getEmitCategory(ID); + return std::error_code(); +} - State->OS.reset(); +std::error_code SDiagsMerger::visitDiagFlagRecord(unsigned ID, StringRef Name) { + DiagFlagLookup[ID] = Writer.getEmitDiagnosticFlag(Name); + return std::error_code(); } diff --git a/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticReader.cpp b/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticReader.cpp new file mode 100644 index 0000000..0ebbd22 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Frontend/SerializedDiagnosticReader.cpp @@ -0,0 +1,295 @@ +//===--- SerializedDiagnosticReader.cpp - Reads diagnostics ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/SerializedDiagnosticReader.h" +#include "clang/Basic/FileManager.h" +#include "clang/Frontend/SerializedDiagnostics.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace clang; +using namespace clang::serialized_diags; + +std::error_code SerializedDiagnosticReader::readDiagnostics(StringRef File) { + // Open the diagnostics file. + FileSystemOptions FO; + FileManager FileMgr(FO); + + auto Buffer = FileMgr.getBufferForFile(File); + if (!Buffer) + return SDError::CouldNotLoad; + + llvm::BitstreamReader StreamFile; + StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), + (const unsigned char *)(*Buffer)->getBufferEnd()); + + llvm::BitstreamCursor Stream(StreamFile); + + // Sniff for the signature. + if (Stream.Read(8) != 'D' || + Stream.Read(8) != 'I' || + Stream.Read(8) != 'A' || + Stream.Read(8) != 'G') + return SDError::InvalidSignature; + + // Read the top level blocks. + while (!Stream.AtEndOfStream()) { + if (Stream.ReadCode() != llvm::bitc::ENTER_SUBBLOCK) + return SDError::InvalidDiagnostics; + + std::error_code EC; + switch (Stream.ReadSubBlockID()) { + case llvm::bitc::BLOCKINFO_BLOCK_ID: + if (Stream.ReadBlockInfoBlock()) + return SDError::MalformedBlockInfoBlock; + continue; + case BLOCK_META: + if ((EC = readMetaBlock(Stream))) + return EC; + continue; + case BLOCK_DIAG: + if ((EC = readDiagnosticBlock(Stream))) + return EC; + continue; + default: + if (!Stream.SkipBlock()) + return SDError::MalformedTopLevelBlock; + continue; + } + } + return std::error_code(); +} + +enum class SerializedDiagnosticReader::Cursor { + Record = 1, + BlockEnd, + BlockBegin +}; + +llvm::ErrorOr<SerializedDiagnosticReader::Cursor> +SerializedDiagnosticReader::skipUntilRecordOrBlock( + llvm::BitstreamCursor &Stream, unsigned &BlockOrRecordID) { + BlockOrRecordID = 0; + + while (!Stream.AtEndOfStream()) { + unsigned Code = Stream.ReadCode(); + + switch ((llvm::bitc::FixedAbbrevIDs)Code) { + case llvm::bitc::ENTER_SUBBLOCK: + BlockOrRecordID = Stream.ReadSubBlockID(); + return Cursor::BlockBegin; + + case llvm::bitc::END_BLOCK: + if (Stream.ReadBlockEnd()) + return SDError::InvalidDiagnostics; + return Cursor::BlockEnd; + + case llvm::bitc::DEFINE_ABBREV: + Stream.ReadAbbrevRecord(); + continue; + + case llvm::bitc::UNABBREV_RECORD: + return SDError::UnsupportedConstruct; + + default: + // We found a record. + BlockOrRecordID = Code; + return Cursor::Record; + } + } + + return SDError::InvalidDiagnostics; +} + +std::error_code +SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META)) + return SDError::MalformedMetadataBlock; + + bool VersionChecked = false; + + while (true) { + unsigned BlockOrCode = 0; + llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode); + if (!Res) + Res.getError(); + + switch (Res.get()) { + case Cursor::Record: + break; + case Cursor::BlockBegin: + if (Stream.SkipBlock()) + return SDError::MalformedMetadataBlock; + case Cursor::BlockEnd: + if (!VersionChecked) + return SDError::MissingVersion; + return std::error_code(); + } + + SmallVector<uint64_t, 1> Record; + unsigned RecordID = Stream.readRecord(BlockOrCode, Record); + + if (RecordID == RECORD_VERSION) { + if (Record.size() < 1) + return SDError::MissingVersion; + if (Record[0] > VersionNumber) + return SDError::VersionMismatch; + VersionChecked = true; + } + } +} + +std::error_code +SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG)) + return SDError::MalformedDiagnosticBlock; + + std::error_code EC; + if ((EC = visitStartOfDiagnostic())) + return EC; + + SmallVector<uint64_t, 16> Record; + while (true) { + unsigned BlockOrCode = 0; + llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode); + if (!Res) + Res.getError(); + + switch (Res.get()) { + case Cursor::BlockBegin: + // The only blocks we care about are subdiagnostics. + if (BlockOrCode == serialized_diags::BLOCK_DIAG) { + if ((EC = readDiagnosticBlock(Stream))) + return EC; + } else if (!Stream.SkipBlock()) + return SDError::MalformedSubBlock; + continue; + case Cursor::BlockEnd: + if ((EC = visitEndOfDiagnostic())) + return EC; + return std::error_code(); + case Cursor::Record: + break; + } + + // Read the record. + Record.clear(); + StringRef Blob; + unsigned RecID = Stream.readRecord(BlockOrCode, Record, &Blob); + + if (RecID < serialized_diags::RECORD_FIRST || + RecID > serialized_diags::RECORD_LAST) + continue; + + switch ((RecordIDs)RecID) { + case RECORD_CATEGORY: + // A category has ID and name size. + if (Record.size() != 2) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitCategoryRecord(Record[0], Blob))) + return EC; + continue; + case RECORD_DIAG: + // A diagnostic has severity, location (4), category, flag, and message + // size. + if (Record.size() != 8) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitDiagnosticRecord( + Record[0], Location(Record[1], Record[2], Record[3], Record[4]), + Record[5], Record[6], Blob))) + return EC; + continue; + case RECORD_DIAG_FLAG: + // A diagnostic flag has ID and name size. + if (Record.size() != 2) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitDiagFlagRecord(Record[0], Blob))) + return EC; + continue; + case RECORD_FILENAME: + // A filename has ID, size, timestamp, and name size. The size and + // timestamp are legacy fields that are always zero these days. + if (Record.size() != 4) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitFilenameRecord(Record[0], Record[1], Record[2], Blob))) + return EC; + continue; + case RECORD_FIXIT: + // A fixit has two locations (4 each) and message size. + if (Record.size() != 9) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitFixitRecord( + Location(Record[0], Record[1], Record[2], Record[3]), + Location(Record[4], Record[5], Record[6], Record[7]), Blob))) + return EC; + continue; + case RECORD_SOURCE_RANGE: + // A source range is two locations (4 each). + if (Record.size() != 8) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitSourceRangeRecord( + Location(Record[0], Record[1], Record[2], Record[3]), + Location(Record[4], Record[5], Record[6], Record[7])))) + return EC; + continue; + case RECORD_VERSION: + // A version is just a number. + if (Record.size() != 1) + return SDError::MalformedDiagnosticRecord; + if ((EC = visitVersionRecord(Record[0]))) + return EC; + continue; + } + } +} + +namespace { +class SDErrorCategoryType final : public std::error_category { + const char *name() const LLVM_NOEXCEPT override { + return "clang.serialized_diags"; + } + std::string message(int IE) const override { + SDError E = static_cast<SDError>(IE); + switch (E) { + case SDError::CouldNotLoad: + return "Failed to open diagnostics file"; + case SDError::InvalidSignature: + return "Invalid diagnostics signature"; + case SDError::InvalidDiagnostics: + return "Parse error reading diagnostics"; + case SDError::MalformedTopLevelBlock: + return "Malformed block at top-level of diagnostics"; + case SDError::MalformedSubBlock: + return "Malformed sub-block in a diagnostic"; + case SDError::MalformedBlockInfoBlock: + return "Malformed BlockInfo block"; + case SDError::MalformedMetadataBlock: + return "Malformed Metadata block"; + case SDError::MalformedDiagnosticBlock: + return "Malformed Diagnostic block"; + case SDError::MalformedDiagnosticRecord: + return "Malformed Diagnostic record"; + case SDError::MissingVersion: + return "No version provided in diagnostics"; + case SDError::VersionMismatch: + return "Unsupported diagnostics version"; + case SDError::UnsupportedConstruct: + return "Bitcode constructs that are not supported in diagnostics appear"; + case SDError::HandlerFailed: + return "Generic error occurred while handling a record"; + } + llvm_unreachable("Unknown error type!"); + } +}; +} + +static llvm::ManagedStatic<SDErrorCategoryType> ErrorCategory; +const std::error_category &clang::serialized_diags::SDErrorCategory() { + return *ErrorCategory; +} diff --git a/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp b/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp index 6e6f3dd..bbc9914 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/TextDiagnostic.cpp @@ -176,7 +176,7 @@ static void expandTabs(std::string &SourceLine, unsigned TabStop) { /// of the printable representation of the line to the columns those printable /// characters will appear at (numbering the first column as 0). /// -/// If a byte 'i' corresponds to muliple columns (e.g. the byte contains a tab +/// If a byte 'i' corresponds to multiple columns (e.g. the byte contains a tab /// character) then the array will map that byte to the first column the /// tab appears at and the next value in the map will have been incremented /// more than once. @@ -293,14 +293,14 @@ struct SourceColumnMap { /// \brief Map from a byte index to the next byte which starts a column. int startOfNextColumn(int N) const { - assert(0 <= N && N < static_cast<int>(m_columnToByte.size() - 1)); + assert(0 <= N && N < static_cast<int>(m_byteToColumn.size() - 1)); while (byteToColumn(++N) == -1) {} return N; } /// \brief Map from a byte index to the previous byte which starts a column. int startOfPreviousColumn(int N) const { - assert(0 < N && N < static_cast<int>(m_columnToByte.size())); + assert(0 < N && N < static_cast<int>(m_byteToColumn.size())); while (byteToColumn(--N) == -1) {} return N; } @@ -323,9 +323,10 @@ static void selectInterestingSourceRegion(std::string &SourceLine, std::string &FixItInsertionLine, unsigned Columns, const SourceColumnMap &map) { - unsigned MaxColumns = std::max<unsigned>(map.columns(), - std::max(CaretLine.size(), - FixItInsertionLine.size())); + unsigned CaretColumns = CaretLine.size(); + unsigned FixItColumns = llvm::sys::locale::columnWidth(FixItInsertionLine); + unsigned MaxColumns = std::max(static_cast<unsigned>(map.columns()), + std::max(CaretColumns, FixItColumns)); // if the number of columns is less than the desired number we're done if (MaxColumns <= Columns) return; @@ -487,7 +488,7 @@ static void selectInterestingSourceRegion(std::string &SourceLine, // We checked up front that the line needed truncation assert(FrontColumnsRemoved+ColumnsKept+BackColumnsRemoved > Columns); - // The line needs some trunctiona, and we'd prefer to keep the front + // The line needs some truncation, and we'd prefer to keep the front // if possible, so remove the back if (BackColumnsRemoved > strlen(back_ellipse)) SourceLine.replace(SourceEnd, std::string::npos, back_ellipse); @@ -1110,12 +1111,13 @@ void TextDiagnostic::emitSnippetAndCaret( // Copy the line of code into an std::string for ease of manipulation. std::string SourceLine(LineStart, LineEnd); - // Create a line for the caret that is filled with spaces that is the same - // length as the line of source code. - std::string CaretLine(LineEnd-LineStart, ' '); - + // Build the byte to column map. const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop); + // Create a line for the caret that is filled with spaces that is the same + // number of columns as the line of source code. + std::string CaretLine(sourceColMap.columns(), ' '); + // Highlight all of the characters covered by Ranges with ~ characters. for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(), E = Ranges.end(); diff --git a/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp b/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp index b50950e..3ff6b18 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -27,14 +27,13 @@ typedef VerifyDiagnosticConsumer::Directive Directive; typedef VerifyDiagnosticConsumer::DirectiveList DirectiveList; typedef VerifyDiagnosticConsumer::ExpectedData ExpectedData; -VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &_Diags) - : Diags(_Diags), - PrimaryClient(Diags.getClient()), OwnsPrimaryClient(Diags.ownsClient()), +VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_) + : Diags(Diags_), + PrimaryClient(Diags.getClient()), PrimaryClientOwner(Diags.takeClient()), Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(nullptr), LangOpts(nullptr), SrcManager(nullptr), ActiveSourceFiles(0), Status(HasNoDirectives) { - Diags.takeClient(); if (Diags.hasSourceManager()) setSourceManager(Diags.getSourceManager()); } @@ -43,10 +42,8 @@ VerifyDiagnosticConsumer::~VerifyDiagnosticConsumer() { assert(!ActiveSourceFiles && "Incomplete parsing of source files!"); assert(!CurrentPreprocessor && "CurrentPreprocessor should be invalid!"); SrcManager = nullptr; - CheckDiagnostics(); - Diags.takeClient(); - if (OwnsPrimaryClient) - delete PrimaryClient; + CheckDiagnostics(); + Diags.takeClient().release(); } #ifndef NDEBUG @@ -84,8 +81,8 @@ void VerifyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts, const_cast<Preprocessor*>(PP)->addCommentHandler(this); #ifndef NDEBUG // Debug build tracks parsed files. - VerifyFileTracker *V = new VerifyFileTracker(*this, *SrcManager); - const_cast<Preprocessor*>(PP)->addPPCallbacks(V); + const_cast<Preprocessor*>(PP)->addPPCallbacks( + llvm::make_unique<VerifyFileTracker>(*this, *SrcManager)); #endif } } @@ -402,8 +399,9 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, // Lookup file via Preprocessor, like a #include. const DirectoryLookup *CurDir; - const FileEntry *FE = PP->LookupFile(Pos, Filename, false, nullptr, - CurDir, nullptr, nullptr, nullptr); + const FileEntry *FE = + PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir, + nullptr, nullptr, nullptr); if (!FE) { Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin), diag::err_verify_missing_file) << Filename << KindStr; @@ -502,13 +500,12 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM, } // Construct new directive. - std::unique_ptr<Directive> D( - Directive::create(RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text, - Min, Max)); + std::unique_ptr<Directive> D = Directive::create( + RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text, Min, Max); std::string Error; if (D->isValid(Error)) { - DL->push_back(D.release()); + DL->push_back(std::move(D)); FoundDirective = true; } else { Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin), @@ -644,15 +641,16 @@ static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceM /// \brief Takes a list of diagnostics that were expected to have been generated /// but were not and produces a diagnostic to the user from this. -static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager &SourceMgr, - DirectiveList &DL, const char *Kind) { +static unsigned PrintExpected(DiagnosticsEngine &Diags, + SourceManager &SourceMgr, + std::vector<Directive *> &DL, const char *Kind) { if (DL.empty()) return 0; SmallString<256> Fmt; llvm::raw_svector_ostream OS(Fmt); - for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) { - Directive &D = **I; + for (auto *DirPtr : DL) { + Directive &D = *DirPtr; OS << "\n File " << SourceMgr.getFilename(D.DiagnosticLoc); if (D.MatchAnyLine) OS << " Line *"; @@ -694,11 +692,11 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, DirectiveList &Left, const_diag_iterator d2_begin, const_diag_iterator d2_end) { - DirectiveList LeftOnly; + std::vector<Directive *> LeftOnly; DiagList Right(d2_begin, d2_end); - for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E; ++I) { - Directive& D = **I; + for (auto &Owner : Left) { + Directive &D = *Owner; unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.DiagnosticLoc); for (unsigned i = 0; i < D.Max; ++i) { @@ -720,7 +718,7 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr, if (II == IE) { // Not found. if (i >= D.Min) break; - LeftOnly.push_back(*I); + LeftOnly.push_back(&D); } else { // Found. The same cannot be found twice. Right.erase(II); @@ -801,8 +799,8 @@ void VerifyDiagnosticConsumer::UpdateParsedFileStatus(SourceManager &SM, void VerifyDiagnosticConsumer::CheckDiagnostics() { // Ensure any diagnostics go to the primary client. - bool OwnsCurClient = Diags.ownsClient(); - DiagnosticConsumer *CurClient = Diags.takeClient(); + DiagnosticConsumer *CurClient = Diags.getClient(); + std::unique_ptr<DiagnosticConsumer> Owner = Diags.takeClient(); Diags.setClient(PrimaryClient, false); #ifndef NDEBUG @@ -864,20 +862,21 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() { Buffer->note_end(), "note")); } - Diags.takeClient(); - Diags.setClient(CurClient, OwnsCurClient); + Diags.setClient(CurClient, Owner.release() != nullptr); // Reset the buffer, we have processed all the diagnostics in it. Buffer.reset(new TextDiagnosticBuffer()); ED.Reset(); } -Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc, - SourceLocation DiagnosticLoc, bool MatchAnyLine, - StringRef Text, unsigned Min, unsigned Max) { +std::unique_ptr<Directive> Directive::create(bool RegexKind, + SourceLocation DirectiveLoc, + SourceLocation DiagnosticLoc, + bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max) { if (!RegexKind) - return new StandardDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine, - Text, Min, Max); + return llvm::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc, + MatchAnyLine, Text, Min, Max); // Parse the directive into a regular expression. std::string RegexStr; @@ -902,6 +901,6 @@ Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc, } } - return new RegexDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, - Min, Max, RegexStr); + return llvm::make_unique<RegexDirective>( + DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max, RegexStr); } |