Index: clang/include/clang/Analysis/CrossTUAnalysisHelper.h =================================================================== --- /dev/null +++ clang/include/clang/Analysis/CrossTUAnalysisHelper.h @@ -0,0 +1,41 @@ +//===- CrossTUHelper.h - Abstraction layer for CTU analysis -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_STATICANALYZER_CORE_CROSS_TU_HELPER_H +#define LLVM_CLANG_STATICANALYZER_CORE_CROSS_TU_HELPER_H + +#include "llvm/ADT/Optional.h" +#include "clang/Basic/SourceManager.h" + +namespace clang { + +class ASTUnit; + +/// This class is an abstract interface acting as a bridge between +/// an analysis that requires lookups across translation units (a user +/// of that interface) and the facility that implements such lookups +/// (an implementation of that interface). This is useful to break direct +/// link-time dependencies between the (possibly shared) libraries in which +/// the user and the implementation live. +class CrossTUAnalysisHelper { +public: + /// Determine the original source location in the original TU for an + /// imported source location. + /// \p ToLoc Source location in the imported-to AST. + /// \return Source location in the imported-from AST and the corresponding + /// ASTUnit object (the AST was loaded from a file using an internal ASTUnit + /// object that is returned here). + /// If any error happens (ToLoc is a non-imported source location) empty is + /// returned. + virtual llvm::Optional> + getImportedFromSourceLocation(SourceLocation ToLoc) const = 0; + + virtual ~CrossTUAnalysisHelper() {} +}; +} // namespace clang + +#endif Index: clang/include/clang/Analysis/PathDiagnosticConsumers.h =================================================================== --- clang/include/clang/Analysis/PathDiagnosticConsumers.h +++ clang/include/clang/Analysis/PathDiagnosticConsumers.h @@ -24,9 +24,7 @@ class AnalyzerOptions; class Preprocessor; -namespace cross_tu { -class CrossTranslationUnitContext; -} +class CrossTUAnalysisHelper; namespace ento { @@ -36,8 +34,7 @@ #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ void CREATEFN(PathDiagnosticConsumerOptions Diagopts, \ PathDiagnosticConsumers &C, const std::string &Prefix, \ - const Preprocessor &PP, \ - const cross_tu::CrossTranslationUnitContext &CTU); + const Preprocessor &PP, const CrossTUAnalysisHelper &CTU); #include "clang/Analysis/PathDiagnosticConsumers.def" } // end 'ento' namespace Index: clang/include/clang/CrossTU/CrossTranslationUnit.h =================================================================== --- clang/include/clang/CrossTU/CrossTranslationUnit.h +++ clang/include/clang/CrossTU/CrossTranslationUnit.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H #define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H +#include "clang/Analysis/CrossTUAnalysisHelper.h" #include "clang/AST/ASTImporterSharedState.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" @@ -120,10 +121,10 @@ /// the locations of the AST files for each definition. /// /// Note that this class also implements caching. -class CrossTranslationUnitContext { +class CrossTranslationUnitContext : public CrossTUAnalysisHelper { public: CrossTranslationUnitContext(CompilerInstance &CI); - ~CrossTranslationUnitContext(); + ~CrossTranslationUnitContext() override; /// This function loads a function or variable definition from an /// external AST file and merges it into the original AST. @@ -191,7 +192,7 @@ /// If any error happens (ToLoc is a non-imported source location) empty is /// returned. llvm::Optional> - getImportedFromSourceLocation(const clang::SourceLocation &ToLoc) const; + getImportedFromSourceLocation(SourceLocation ToLoc) const override; private: using ImportedFileIDMap = Index: clang/lib/Analysis/HTMLPathDiagnosticConsumer.cpp =================================================================== --- clang/lib/Analysis/HTMLPathDiagnosticConsumer.cpp +++ clang/lib/Analysis/HTMLPathDiagnosticConsumer.cpp @@ -50,6 +50,10 @@ using namespace clang; using namespace ento; +namespace clang { +class CrossTUAnalysisHelper; +} + //===----------------------------------------------------------------------===// // Boilerplate. //===----------------------------------------------------------------------===// @@ -133,7 +137,7 @@ void ento::createHTMLDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputDir, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { // FIXME: HTML is currently our default output type, but if the output // directory isn't specified, it acts like if it was in the minimal text @@ -153,7 +157,7 @@ void ento::createHTMLSingleFileDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputDir, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, CTU); // TODO: Emit an error here. Index: clang/lib/Analysis/PlistHTMLPathDiagnosticConsumer.cpp =================================================================== --- clang/lib/Analysis/PlistHTMLPathDiagnosticConsumer.cpp +++ clang/lib/Analysis/PlistHTMLPathDiagnosticConsumer.cpp @@ -19,10 +19,14 @@ using namespace clang; using namespace ento; +namespace clang { +class CrossTUAnalysisHelper; +} + void ento::createPlistHTMLDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &Prefix, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { createHTMLDiagnosticConsumer( DiagOpts, C, std::string(llvm::sys::path::parent_path(Prefix)), PP, CTU); createPlistMultiFileDiagnosticConsumer(DiagOpts, C, Prefix, PP, CTU); Index: clang/lib/Analysis/PlistPathDiagnosticConsumer.cpp =================================================================== --- clang/lib/Analysis/PlistPathDiagnosticConsumer.cpp +++ clang/lib/Analysis/PlistPathDiagnosticConsumer.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Analysis/CrossTUAnalysisHelper.h" #include "clang/Analysis/IssueHash.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/PathDiagnosticConsumers.h" @@ -17,7 +18,6 @@ #include "clang/Basic/PlistSupport.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" -#include "clang/CrossTU/CrossTranslationUnit.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/TokenConcatenation.h" @@ -42,7 +42,7 @@ PathDiagnosticConsumerOptions DiagOpts; const std::string OutputFile; const Preprocessor &PP; - const cross_tu::CrossTranslationUnitContext &CTU; + const CrossTUAnalysisHelper &CTU; const bool SupportsCrossFileDiagnostics; void printBugPath(llvm::raw_ostream &o, const FIDMap &FM, @@ -51,7 +51,7 @@ public: PlistPathDiagnosticConsumer(PathDiagnosticConsumerOptions DiagOpts, const std::string &OutputFile, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU, + const CrossTUAnalysisHelper &CTU, bool supportsMultipleFiles); ~PlistPathDiagnosticConsumer() override {} @@ -79,13 +79,13 @@ class PlistPrinter { const FIDMap& FM; const Preprocessor &PP; - const cross_tu::CrossTranslationUnitContext &CTU; + const CrossTUAnalysisHelper &CTU; llvm::SmallVector MacroPieces; public: PlistPrinter(const FIDMap& FM, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) + const CrossTUAnalysisHelper &CTU) : FM(FM), PP(PP), CTU(CTU) { } @@ -175,7 +175,7 @@ static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU); + const CrossTUAnalysisHelper &CTU); //===----------------------------------------------------------------------===// // Methods of PlistPrinter. @@ -521,7 +521,7 @@ PlistPathDiagnosticConsumer::PlistPathDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, const std::string &output, - const Preprocessor &PP, const cross_tu::CrossTranslationUnitContext &CTU, + const Preprocessor &PP, const CrossTUAnalysisHelper &CTU, bool supportsMultipleFiles) : DiagOpts(std::move(DiagOpts)), OutputFile(output), PP(PP), CTU(CTU), SupportsCrossFileDiagnostics(supportsMultipleFiles) { @@ -532,7 +532,7 @@ void ento::createPlistDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputFile, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { // TODO: Emit an error here. if (OutputFile.empty()) @@ -547,7 +547,7 @@ void ento::createPlistMultiFileDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputFile, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { // TODO: Emit an error here. if (OutputFile.empty()) @@ -985,7 +985,7 @@ static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { const Preprocessor *PPToUse = &PP; if (auto LocAndUnit = CTU.getImportedFromSourceLocation(MacroLoc)) { Index: clang/lib/Analysis/SarifPathDiagnosticConsumer.cpp =================================================================== --- clang/lib/Analysis/SarifPathDiagnosticConsumer.cpp +++ clang/lib/Analysis/SarifPathDiagnosticConsumer.cpp @@ -25,6 +25,10 @@ using namespace clang; using namespace ento; +namespace clang { +class CrossTUAnalysisHelper; +} + namespace { class SarifPathDiagnosticConsumer : public PathDiagnosticConsumer { std::string OutputFile; @@ -48,7 +52,7 @@ void ento::createSarifDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &Output, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { // TODO: Emit an error here. if (Output.empty()) Index: clang/lib/Analysis/TextPathDiagnosticConsumer.cpp =================================================================== --- clang/lib/Analysis/TextPathDiagnosticConsumer.cpp +++ clang/lib/Analysis/TextPathDiagnosticConsumer.cpp @@ -14,7 +14,6 @@ #include "clang/Analysis/PathDiagnosticConsumers.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" -#include "clang/CrossTU/CrossTranslationUnit.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Lex/Preprocessor.h" #include "clang/Rewrite/Core/Rewriter.h" @@ -28,8 +27,12 @@ using namespace ento; using namespace tooling; +namespace clang { +class CrossTUAnalysisHelper; +} + namespace { -/// Emitsd minimal diagnostics (report message + notes) for the 'none' output +/// Emits minimal diagnostics (report message + notes) for the 'none' output /// type to the standard error, or to to compliment many others. Emits detailed /// diagnostics in textual format for the 'text' output type. class TextPathDiagnosticConsumer : public PathDiagnosticConsumer { @@ -138,7 +141,7 @@ void ento::createTextPathDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &Prefix, const clang::Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { C.emplace_back(new TextPathDiagnosticConsumer( std::move(DiagOpts), PP.getDiagnostics(), PP.getLangOpts(), /*ShouldDisplayPathNotes=*/true)); @@ -147,7 +150,7 @@ void ento::createTextMinimalPathDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &Prefix, const clang::Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const CrossTUAnalysisHelper &CTU) { C.emplace_back(new TextPathDiagnosticConsumer( std::move(DiagOpts), PP.getDiagnostics(), PP.getLangOpts(), /*ShouldDisplayPathNotes=*/false)); Index: clang/lib/CrossTU/CrossTranslationUnit.cpp =================================================================== --- clang/lib/CrossTU/CrossTranslationUnit.cpp +++ clang/lib/CrossTU/CrossTranslationUnit.cpp @@ -765,7 +765,7 @@ llvm::Optional> CrossTranslationUnitContext::getImportedFromSourceLocation( - const clang::SourceLocation &ToLoc) const { + SourceLocation ToLoc) const { const SourceManager &SM = Context.getSourceManager(); auto DecToLoc = SM.getDecomposedLoc(ToLoc);