llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Balázs Benics (steakhal) <details> <summary>Changes</summary> This reverts commit 9a1c63230b8ad3f19cb624f0d283f7df10957ab7. 1st attempt: #<!-- -->184421 2nd attempt: #<!-- -->185414 Third time the charm! --- Patch is 51.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/185616.diff 29 Files Affected: - (added) clang/include/clang/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.h (+33) - (added) clang/include/clang/Analysis/Scalable/SSAFBuiltinForceLinker.h (+28) - (added) clang/include/clang/Analysis/Scalable/SSAFForceLinker.h (+25) - (modified) clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h (+12-2) - (modified) clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h (+9) - (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+23) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+3) - (modified) clang/include/clang/Frontend/FrontendOptions.h (+7) - (modified) clang/include/clang/Options/Options.td (+20) - (modified) clang/lib/Analysis/Scalable/CMakeLists.txt (+3-1) - (added) clang/lib/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.cpp (+181) - (modified) clang/lib/Analysis/Scalable/Serialization/JSONFormat/JSONFormatImpl.cpp (+2-3) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+3) - (modified) clang/lib/FrontendTool/CMakeLists.txt (+1) - (modified) clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (+6) - (added) clang/test/Analysis/SSAF/command-line-interface.cpp (+22) - (added) clang/test/Analysis/SSAF/downgradable-errors.cpp (+15) - (added) clang/test/Analysis/SSAF/help.cpp (+7) - (modified) clang/tools/ssaf-linker/SSAFLinker.cpp (+1-3) - (modified) clang/unittests/Analysis/Scalable/CMakeLists.txt (+1) - (added) clang/unittests/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendActionTest.cpp (+362) - (modified) clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp (+2) - (modified) clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp (+2) - (modified) clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor1.cpp (+4-2) - (modified) clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor2.cpp (+4-2) - (modified) clang/unittests/Analysis/Scalable/Registries/SummaryExtractorRegistryTest.cpp (+1) - (added) clang/unittests/Analysis/Scalable/SSAFBuiltinTestForceLinker.h (+51) - (added) clang/unittests/Analysis/Scalable/SSAFTestForceLinker.h (+23) - (modified) clang/unittests/Analysis/Scalable/TestFixture.cpp (+1) ``````````diff diff --git a/clang/include/clang/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.h b/clang/include/clang/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.h new file mode 100644 index 0000000000000..a91955d2a2139 --- /dev/null +++ b/clang/include/clang/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.h @@ -0,0 +1,33 @@ +//===- TUSummaryExtractorFrontendAction.h -----------------------*- 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_SCALABLE_FRONTEND_TUSUMMARYEXTRACTORFRONTENDACTION_H +#define LLVM_CLANG_ANALYSIS_SCALABLE_FRONTEND_TUSUMMARYEXTRACTORFRONTENDACTION_H + +#include "clang/Frontend/FrontendAction.h" +#include <memory> + +namespace clang::ssaf { + +/// Wraps the existing \c FrontendAction and injects the extractor +/// \c ASTConsumers into the pipeline after the ASTConsumers of the wrapped +/// action. +class TUSummaryExtractorFrontendAction final : public WrapperFrontendAction { +public: + explicit TUSummaryExtractorFrontendAction( + std::unique_ptr<FrontendAction> WrappedAction); + ~TUSummaryExtractorFrontendAction(); + +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +} // namespace clang::ssaf + +#endif // LLVM_CLANG_ANALYSIS_SCALABLE_FRONTEND_TUSUMMARYEXTRACTORFRONTENDACTION_H diff --git a/clang/include/clang/Analysis/Scalable/SSAFBuiltinForceLinker.h b/clang/include/clang/Analysis/Scalable/SSAFBuiltinForceLinker.h new file mode 100644 index 0000000000000..f13f131e89bc6 --- /dev/null +++ b/clang/include/clang/Analysis/Scalable/SSAFBuiltinForceLinker.h @@ -0,0 +1,28 @@ +//===- SSAFBuiltinForceLinker.h ---------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file pulls in all built-in SSAF extractor and format registrations +/// by referencing their anchor symbols, preventing the static linker from +/// discarding the containing object files. +/// +/// Include this header (with IWYU pragma: keep) in any translation unit that +/// must guarantee these registrations are active — typically the entry point +/// of a binary that uses clangAnalysisScalable. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_SSAFBUILTINFORCELINKER_H +#define LLVM_CLANG_ANALYSIS_SCALABLE_SSAFBUILTINFORCELINKER_H + +// This anchor is used to force the linker to link the JSONFormat registration. +extern volatile int SSAFJSONFormatAnchorSource; +[[maybe_unused]] static int SSAFJSONFormatAnchorDestination = + SSAFJSONFormatAnchorSource; + +#endif // LLVM_CLANG_ANALYSIS_SCALABLE_SSAFBUILTINFORCELINKER_H diff --git a/clang/include/clang/Analysis/Scalable/SSAFForceLinker.h b/clang/include/clang/Analysis/Scalable/SSAFForceLinker.h new file mode 100644 index 0000000000000..a59c5f144a6f5 --- /dev/null +++ b/clang/include/clang/Analysis/Scalable/SSAFForceLinker.h @@ -0,0 +1,25 @@ +//===- SSAFForceLinker.h ----------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file pulls in all built-in SSAF extractor and format registrations +/// by referencing their anchor symbols, preventing the static linker from +/// discarding the containing object files. +/// +/// Include this header (with IWYU pragma: keep) in any translation unit that +/// must guarantee these registrations are active — typically the entry point +/// of a binary that uses clangAnalysisScalable. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_SSAFFORCELINKER_H +#define LLVM_CLANG_ANALYSIS_SCALABLE_SSAFFORCELINKER_H + +#include "SSAFBuiltinForceLinker.h" // IWYU pragma: keep + +#endif // LLVM_CLANG_ANALYSIS_SCALABLE_SSAFFORCELINKER_H diff --git a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h index ef060dd27c522..7edd7b5b561d9 100644 --- a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h +++ b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h @@ -24,10 +24,11 @@ // // Insert this code to the cpp file: // -// LLVM_INSTANTIATE_REGISTRY(llvm::Registry<MyFormat::FormatInfo>) -// +// // NOLINTNEXTLINE(misc-use-internal-linkage) +// volatile int SSAFMyFormatAnchorSource = 0; // static SerializationFormatRegistry::Add<MyFormat> // RegisterFormat("MyFormat", "My awesome serialization format"); +// LLVM_INSTANTIATE_REGISTRY(llvm::Registry<MyFormat::FormatInfo>) // // Then implement the formatter for the specific analysis and register the // format info for it: @@ -49,6 +50,15 @@ // "The MyFormat format info implementation for MyAnalysis" // ); // +// Finally, insert a use of the new anchor symbol into the force-linker header: +// clang/include/clang/Analysis/Scalable/SSAFBuiltinForceLinker.h: +// +// This anchor is used to force the linker to link the MyFormat registration. +// +// extern volatile int SSAFMyFormatAnchorSource; +// [[maybe_unused]] static int SSAFMyFormatAnchorDestination = +// SSAFMyFormatAnchorSource; +// //===----------------------------------------------------------------------===// #ifndef CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_REGISTRY_H diff --git a/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h b/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h index 29f5925ed6af6..d9147871a5101 100644 --- a/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h +++ b/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h @@ -9,9 +9,18 @@ // Registry for TUSummaryExtractors, and some helper functions. // To register some custom extractor, insert this code: // +// // NOLINTNEXTLINE(misc-use-internal-linkage) +// volatile int SSAFMyExtractorAnchorSource = 0; // static TUSummaryExtractorRegistry::Add<MyExtractor> // X("MyExtractor", "My awesome extractor"); // +// Finally, insert a use of the new anchor symbol into the force-linker header: +// clang/include/clang/Analysis/Scalable/SSAFBuiltinForceLinker.h: +// +// extern volatile int SSAFMyExtractorAnchorSource; +// [[maybe_unused]] static int SSAFMyExtractorAnchorDestination = +// SSAFMyExtractorAnchorSource; +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_EXTRACTORREGISTRY_H diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 5c62bb70ebd0f..00db1e7ee5afa 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -379,6 +379,29 @@ def warn_profile_data_misexpect : Warning< BackendInfo, InGroup<MisExpect>; } // end of instrumentation issue category +def warn_ssaf_extract_tu_summary_file_unknown_output_format : + Warning<"unknown output summary file format '%0' " + "specified by '--ssaf-tu-summary-file=%1'">, + InGroup<ScalableStaticAnalysisFramework>, DefaultError; + +def warn_ssaf_extract_tu_summary_file_unknown_format : + Warning<"failed to parse the value of '--ssaf-tu-summary-file=%0' " + "the value must follow the '<path>.<format>' pattern">, + InGroup<ScalableStaticAnalysisFramework>, DefaultError; + +def warn_ssaf_must_enable_summary_extractors : + Warning<"must enable some summary extractors using the " + "'--ssaf-extract-summaries=' option">, + InGroup<ScalableStaticAnalysisFramework>, DefaultError; + +def warn_ssaf_extract_summary_unknown_extractor_name : + Warning<"no summary extractor%s0 %plural{1:was|:were}0 registered with name: %1">, + InGroup<ScalableStaticAnalysisFramework>, DefaultError; + +def warn_ssaf_write_tu_summary_failed : + Warning<"failed to write TU summary to '%0': %1">, + InGroup<ScalableStaticAnalysisFramework>, DefaultError; + def err_extract_api_ignores_file_not_found : Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 22af8eec76f34..bc553bbb76717 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1907,6 +1907,9 @@ def BitIntExtension : DiagGroup<"bit-int-extension">; // Warnings about misuse of ExtractAPI options. def ExtractAPIMisuse : DiagGroup<"extractapi-misuse">; +// Warnings related to the "Scalable Static Analysis Framework" - SSAF. +def ScalableStaticAnalysisFramework : DiagGroup<"scalable-static-analysis-framework">; + // Warnings about using the non-standard extension having an explicit specialization // with a storage class specifier. def ExplicitSpecializationStorageClass : DiagGroup<"explicit-specialization-storage-class">; diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 9e05181ac916c..0d8eb6a1b7379 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -543,6 +543,13 @@ class FrontendOptions { /// minimization hints. std::string DumpMinimizationHintsPath; + /// List of SSAF extractors to enable. + std::vector<std::string> SSAFExtractSummaries; + + /// The TU summary output file with the file extension representing the file + /// format. + std::string SSAFTUSummaryFile; + public: FrontendOptions() : DisableFree(false), RelocatablePCH(false), ShowHelp(false), diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 4bbdd9c8c0e58..cf3fba37a1e0b 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -274,6 +274,10 @@ def StaticAnalyzer_Group : OptionGroup<"<Static analyzer group>">, DocName<"Static analyzer options">, DocBrief<[{ Flags controlling the behavior of the Clang Static Analyzer.}]>; +def SSAF_Group : OptionGroup<"<ssaf options>">, + DocName<"SSAF options">, DocBrief<[{ +Flags controlling the behavior of the Scalable Static Analysis Framework (SSAF).}]>; + // gfortran options that we recognize in the driver and pass along when // invoking GCC to compile Fortran code. def gfortran_Group : OptionGroup<"<gfortran group>">, @@ -941,6 +945,22 @@ def W_Joined : Joined<["-"], "W">, Group<W_Group>, def Xanalyzer : Separate<["-"], "Xanalyzer">, HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">, Group<StaticAnalyzer_Group>; +def _ssaf_extract_summaries : + CommaJoined<["--"], "ssaf-extract-summaries=">, + MetaVarName<"<summary-names>">, + Group<SSAF_Group>, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Comma-separated list of summary names to extract">, + MarshallingInfoStringVector<FrontendOpts<"SSAFExtractSummaries">>; +def _ssaf_tu_summary_file : + Joined<["--"], "ssaf-tu-summary-file=">, + MetaVarName<"<path>.<format>">, + Group<SSAF_Group>, + Visibility<[ClangOption, CC1Option]>, + HelpText< + "The output file for the extracted summaries. " + "The extension selects which file format to use.">, + MarshallingInfoString<FrontendOpts<"SSAFTUSummaryFile">>; def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[NoXarchOption]>, diff --git a/clang/lib/Analysis/Scalable/CMakeLists.txt b/clang/lib/Analysis/Scalable/CMakeLists.txt index 4593fbcd515b5..8e7e888ca3ae0 100644 --- a/clang/lib/Analysis/Scalable/CMakeLists.txt +++ b/clang/lib/Analysis/Scalable/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangAnalysisScalable ASTEntityMapping.cpp EntityLinker/EntityLinker.cpp + Frontend/TUSummaryExtractorFrontendAction.cpp Model/BuildNamespace.cpp Model/EntityId.cpp Model/EntityIdTable.cpp @@ -26,8 +27,9 @@ add_clang_library(clangAnalysisScalable clangAST clangASTMatchers clangBasic - clangLex clangFrontend + clangLex + clangSema clangUnifiedSymbolResolution DEPENDS diff --git a/clang/lib/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.cpp b/clang/lib/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.cpp new file mode 100644 index 0000000000000..9d2784cb3b2e3 --- /dev/null +++ b/clang/lib/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.cpp @@ -0,0 +1,181 @@ +//===- TUSummaryExtractorFrontendAction.cpp -------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/Scalable/Frontend/TUSummaryExtractorFrontendAction.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h" +#include "clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h" +#include "clang/Analysis/Scalable/TUSummary/TUSummary.h" +#include "clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h" +#include "clang/Analysis/Scalable/TUSummary/TUSummaryExtractor.h" +#include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Frontend/MultiplexConsumer.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Path.h" +#include <memory> +#include <string> +#include <vector> + +using namespace clang; +using namespace ssaf; + +static std::optional<std::pair<llvm::StringRef, llvm::StringRef>> +parseOutputFileFormatAndPathOrReportError(DiagnosticsEngine &Diags, + StringRef SSAFTUSummaryFile) { + + StringRef Ext = llvm::sys::path::extension(SSAFTUSummaryFile); + StringRef FilePath = SSAFTUSummaryFile.drop_back(Ext.size()); + + if (!Ext.consume_front(".") || FilePath.empty()) { + Diags.Report(diag::warn_ssaf_extract_tu_summary_file_unknown_format) + << SSAFTUSummaryFile; + return std::nullopt; + } + + if (!isFormatRegistered(Ext)) { + Diags.Report(diag::warn_ssaf_extract_tu_summary_file_unknown_output_format) + << Ext << SSAFTUSummaryFile; + return std::nullopt; + } + + return std::pair{Ext, FilePath}; +} + +/// Return \c true if reported unrecognized extractors. +static bool +reportUnrecognizedExtractorNames(DiagnosticsEngine &Diags, + ArrayRef<std::string> SSAFExtractSummaries) { + if (SSAFExtractSummaries.empty()) { + Diags.Report(diag::warn_ssaf_must_enable_summary_extractors); + return true; + } + + std::vector<StringRef> UnrecognizedExtractorNames; + for (StringRef Name : SSAFExtractSummaries) + if (!isTUSummaryExtractorRegistered(Name)) + UnrecognizedExtractorNames.push_back(Name); + + if (!UnrecognizedExtractorNames.empty()) { + Diags.Report(diag::warn_ssaf_extract_summary_unknown_extractor_name) + << UnrecognizedExtractorNames.size() + << llvm::join(UnrecognizedExtractorNames, ", "); + return true; + } + + return false; +} + +static std::vector<std::unique_ptr<ASTConsumer>> +makeTUSummaryExtractors(TUSummaryBuilder &Builder, + ArrayRef<std::string> SSAFExtractSummaries) { + std::vector<std::unique_ptr<ASTConsumer>> Extractors; + Extractors.reserve(SSAFExtractSummaries.size()); + for (StringRef Name : SSAFExtractSummaries) { + assert(isTUSummaryExtractorRegistered(Name)); + Extractors.push_back(makeTUSummaryExtractor(Name, Builder)); + } + return Extractors; +} + +namespace { + +/// Drives all extractor \c ASTConsumers and serializes the completed +/// \c TUSummary. +/// +/// Derives from \c MultiplexConsumer so every \c ASTConsumer virtual method is +/// automatically forwarded to each extractor. +class TUSummaryRunner final : public MultiplexConsumer { +public: + static std::unique_ptr<TUSummaryRunner> create(CompilerInstance &CI, + StringRef InFile); + +private: + TUSummaryRunner(StringRef InFile, std::unique_ptr<SerializationFormat> Format, + const FrontendOptions &Opts); + + void HandleTranslationUnit(ASTContext &Ctx) override; + + TUSummary Summary; + TUSummaryBuilder Builder = TUSummaryBuilder(Summary); + std::unique_ptr<SerializationFormat> Format; + const FrontendOptions &Opts; +}; +} // namespace + +std::unique_ptr<TUSummaryRunner> TUSummaryRunner::create(CompilerInstance &CI, + StringRef InFile) { + const FrontendOptions &Opts = CI.getFrontendOpts(); + DiagnosticsEngine &Diags = CI.getDiagnostics(); + + auto MaybePair = + parseOutputFileFormatAndPathOrReportError(Diags, Opts.SSAFTUSummaryFile); + if (!MaybePair.has_value()) + return nullptr; + auto [FormatName, OutputPath] = MaybePair.value(); + + if (reportUnrecognizedExtractorNames(Diags, Opts.SSAFExtractSummaries)) + return nullptr; + + return std::unique_ptr<TUSummaryRunner>{ + new TUSummaryRunner{InFile, makeFormat(FormatName), Opts}}; +} + +TUSummaryRunner::TUSummaryRunner(StringRef InFile, + std::unique_ptr<SerializationFormat> Format, + const FrontendOptions &Opts) + : MultiplexConsumer(std::vector<std::unique_ptr<ASTConsumer>>{}), + Summary(BuildNamespace(BuildNamespaceKind::CompilationUnit, InFile)), + Format(std::move(Format)), Opts(Opts) { + assert(this->Format); + + // Now the Summary and the builders are constructed, we can also construct the + // extractors. + auto Extractors = makeTUSummaryExtractors(Builder, Opts.SSAFExtractSummaries); + assert(!Extractors.empty()); + + // We must initialize the Consumers here because our extractors need a + // Builder that holds a reference to the TUSummary, which would be only + // initialized after the MultiplexConsumer ctor. This is the only way we can + // avoid the use of the TUSummary before it starts its lifetime. + MultiplexConsumer::Consumers = std::move(Extractors); +} + +void TUSummaryRunner::HandleTranslationUnit(ASTContext &Ctx) { + // First, invoke the Summary Extractors. + MultiplexConsumer::HandleTranslationUnit(Ctx); + + // Then serialize the result. + if (auto Err = Format->writeTUSummary(Summary, Opts.SSAFTUSummaryFile)) { + Ctx.getDiagnostics().Report(diag::warn_ssaf_write_tu_summary_failed) + << Opts.SSAFTUSummaryFile << llvm::toString(std::move(Err)); + } +} + +TUSummaryExtractorFrontendAction::~TUSummaryExtractorFrontendAction() = default; + +TUSummaryExtractorFrontendAction::TUSummaryExtractorFrontendAction( + std::unique_ptr<FrontendAction> WrappedAction) + : WrapperFrontendAction(std::move(WrappedAction)) {} + +std::unique_ptr<ASTConsumer> +TUSummaryExtractorFrontendAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + auto WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile); + if (!WrappedConsumer) + return nullptr; + + if (auto Runner = TUSummaryRunner::create(CI, InFile)) { + std::vector<std::unique_ptr<ASTConsumer>> Consumers; + Consumers.reserve(2); + Consumers.push_back(std::move(WrappedConsumer)); + Consumers.push_back(std::move(Runner)); + return std::make_unique<MultiplexConsumer>(std::move(Consumers)); + } + return WrappedConsumer; +} diff --git a/clang/lib/Analysis... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/185616 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
