[analyzer][CTU] Add an abstraction layer between libCrossTU and libAnalysis.

Fixes shared libs build after D67422.

Differential Revision: https://reviews.llvm.org/D92432
This commit is contained in:
Artem Dergachev 2020-12-01 13:48:05 -08:00
parent ea6641085d
commit 00ffea77ad
9 changed files with 81 additions and 27 deletions

View File

@ -0,0 +1,41 @@
//===- CrossTUAnalysisHelper.h - Abstraction layer for CTU ------*- 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_ANALYSIS_CROSS_TU_HELPER_H
#define LLVM_CLANG_ANALYSIS_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<std::pair<SourceLocation /*FromLoc*/, ASTUnit *>>
getImportedFromSourceLocation(SourceLocation ToLoc) const = 0;
virtual ~CrossTUAnalysisHelper() {}
};
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_CROSS_TU_HELPER_H

View File

@ -24,9 +24,7 @@ namespace clang {
class AnalyzerOptions;
class Preprocessor;
namespace cross_tu {
class CrossTranslationUnitContext;
}
class CrossTUAnalysisHelper;
namespace ento {
@ -36,8 +34,7 @@ typedef std::vector<PathDiagnosticConsumer *> PathDiagnosticConsumers;
#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

View File

@ -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 @@ bool containsConst(const VarDecl *VD, const ASTContext &ACtx);
/// 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 @@ public:
/// If any error happens (ToLoc is a non-imported source location) empty is
/// returned.
llvm::Optional<std::pair<SourceLocation /*FromLoc*/, ASTUnit *>>
getImportedFromSourceLocation(const clang::SourceLocation &ToLoc) const;
getImportedFromSourceLocation(SourceLocation ToLoc) const override;
private:
using ImportedFileIDMap =

View File

@ -50,6 +50,10 @@
using namespace clang;
using namespace ento;
namespace clang {
class CrossTUAnalysisHelper;
}
//===----------------------------------------------------------------------===//
// Boilerplate.
//===----------------------------------------------------------------------===//
@ -133,7 +137,7 @@ private:
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::createHTMLDiagnosticConsumer(
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.

View File

@ -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);

View File

@ -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 @@ namespace {
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 @@ namespace {
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 @@ namespace {
class PlistPrinter {
const FIDMap& FM;
const Preprocessor &PP;
const cross_tu::CrossTranslationUnitContext &CTU;
const CrossTUAnalysisHelper &CTU;
llvm::SmallVector<const PathDiagnosticMacroPiece *, 0> 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 void printCoverage(const PathDiagnostic *D,
static ExpansionInfo
getExpandedMacro(SourceLocation MacroLoc, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU);
const CrossTUAnalysisHelper &CTU);
//===----------------------------------------------------------------------===//
// Methods of PlistPrinter.
@ -521,7 +521,7 @@ static void printCoverage(const PathDiagnostic *D,
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 @@ PlistPathDiagnosticConsumer::PlistPathDiagnosticConsumer(
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::createPlistDiagnosticConsumer(
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 const MacroInfo *getMacroInfoForLocation(const Preprocessor &PP,
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)) {

View File

@ -25,6 +25,10 @@ using namespace llvm;
using namespace clang;
using namespace ento;
namespace clang {
class CrossTUAnalysisHelper;
}
namespace {
class SarifPathDiagnosticConsumer : public PathDiagnosticConsumer {
std::string OutputFile;
@ -48,7 +52,7 @@ public:
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())

View File

@ -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 clang;
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 @@ public:
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::createTextPathDiagnosticConsumer(
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));

View File

@ -765,7 +765,7 @@ CrossTranslationUnitContext::getOrCreateASTImporter(ASTUnit *Unit) {
llvm::Optional<std::pair<SourceLocation, ASTUnit *>>
CrossTranslationUnitContext::getImportedFromSourceLocation(
const clang::SourceLocation &ToLoc) const {
SourceLocation ToLoc) const {
const SourceManager &SM = Context.getSourceManager();
auto DecToLoc = SM.getDecomposedLoc(ToLoc);