[clang][ssaf] Add --ssaf-list-{extractor,format} flags (#185428)

These flags only work with the `clang` driver.
The `cc1` driver would ignore these flags.
Probably it could be implemented differently, but it's already better
than having nothing.
This commit is contained in:
Balázs Benics 2026-03-17 08:41:22 +00:00 committed by GitHub
parent c64d9af7b5
commit 9e43b35bef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 89 additions and 7 deletions

View File

@ -13,6 +13,8 @@ Two flags control summary extraction:
- ``--ssaf-extract-summaries=<name1>,<name2>,...``: Comma-separated list of summary extractor names to enable.
- ``--ssaf-tu-summary-file=<path>.<format>``: Output file for the extracted summaries. The file extension selects the serialization format (e.g. ``.json``).
- ``--ssaf-list-extractors``: List the available summary extractors.
- ``--ssaf-list-formats``: List the available serialization formats.
Example invocation:
@ -22,6 +24,8 @@ Example invocation:
--ssaf-tu-summary-file=my-tu-summary.json \
-c input.cpp -o input.o
clang --ssaf-list-extractors --ssaf-list-formats
Diagnostics
***********

View File

@ -550,6 +550,14 @@ public:
/// format.
std::string SSAFTUSummaryFile;
/// Show available SSAF summary extractors.
LLVM_PREFERRED_TYPE(bool)
unsigned SSAFShowExtractors : 1;
/// Show available SSAF serialization formats.
LLVM_PREFERRED_TYPE(bool)
unsigned SSAFShowFormats : 1;
public:
FrontendOptions()
: DisableFree(false), RelocatablePCH(false), ShowHelp(false),
@ -567,7 +575,8 @@ public:
EmitPrettySymbolGraphs(false), GenReducedBMI(false),
UseClangIRPipeline(false), ClangIRDisablePasses(false),
ClangIRDisableCIRVerifier(false), ClangIREnableIdiomRecognizer(false),
TimeTraceGranularity(500), TimeTraceVerbose(false) {}
TimeTraceGranularity(500), TimeTraceVerbose(false),
SSAFShowExtractors(false), SSAFShowFormats(false) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.

View File

@ -961,6 +961,18 @@ def _ssaf_tu_summary_file :
"The output file for the extracted summaries. "
"The extension selects which file format to use.">,
MarshallingInfoString<FrontendOpts<"SSAFTUSummaryFile">>;
def _ssaf_list_extractors :
Flag<["--"], "ssaf-list-extractors">,
Group<SSAF_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Display the list of available SSAF summary extractors">,
MarshallingInfoFlag<FrontendOpts<"SSAFShowExtractors">>;
def _ssaf_list_formats :
Flag<["--"], "ssaf-list-formats">,
Group<SSAF_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Display the list of available SSAF serialization formats">,
MarshallingInfoFlag<FrontendOpts<"SSAFShowFormats">>;
def Xarch__
: JoinedAndSeparate<["-"], "Xarch_">,
Flags<[NoXarchOption]>,

View File

@ -68,6 +68,7 @@
#include "clang/Support/Compiler.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Registry.h"
#include "llvm/Support/raw_ostream.h"
namespace clang::ssaf {
@ -80,6 +81,9 @@ bool isFormatRegistered(llvm::StringRef FormatName);
/// It's a fatal error if there is no format registered with the name.
std::unique_ptr<SerializationFormat> makeFormat(llvm::StringRef FormatName);
/// Print the list of available serialization formats.
void printAvailableFormats(llvm::raw_ostream &OS);
// Registry for adding new SerializationFormat implementations.
using SerializationFormatRegistry = llvm::Registry<SerializationFormat>;

View File

@ -30,6 +30,7 @@
#include "clang/Support/Compiler.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Registry.h"
#include "llvm/Support/raw_ostream.h"
namespace clang::ssaf {
@ -43,6 +44,9 @@ bool isTUSummaryExtractorRegistered(llvm::StringRef SummaryName);
std::unique_ptr<ASTConsumer> makeTUSummaryExtractor(llvm::StringRef SummaryName,
TUSummaryBuilder &Builder);
/// Print the list of available TUSummaryExtractors.
void printAvailableTUSummaryExtractors(llvm::raw_ostream &OS);
// Registry for adding new TUSummaryExtractor implementations.
using TUSummaryExtractorRegistry =
llvm::Registry<TUSummaryExtractor, TUSummaryBuilder &>;

View File

@ -105,6 +105,8 @@ add_clang_library(clangDriver
LINK_LIBS
clangBasic
clangFrontend
clangScalableStaticAnalysisFrameworkCore
clangScalableStaticAnalysisFrameworkFrontend
clangSerialization
clangLex
clangOptions

View File

@ -69,6 +69,9 @@
#include "clang/Driver/Types.h"
#include "clang/Options/OptionUtils.h"
#include "clang/Options/Options.h"
#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormatRegistry.h"
#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/ExtractorRegistry.h"
#include "clang/ScalableStaticAnalysisFramework/SSAFForceLinker.h" // IWYU pragma: keep
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
@ -2555,6 +2558,22 @@ bool Driver::HandleImmediateArgs(Compilation &C) {
return false;
}
// Honor --ssaf-list-extractors, --ssaf-list-formats and their combinations.
bool ListExtractors = C.getArgs().hasArg(options::OPT__ssaf_list_extractors);
bool ListFormats = C.getArgs().hasArg(options::OPT__ssaf_list_formats);
if (ListExtractors || ListFormats) {
if (ListExtractors)
ssaf::printAvailableTUSummaryExtractors(llvm::outs());
if (ListFormats)
ssaf::printAvailableFormats(llvm::outs());
return false;
}
if (C.getArgs().hasArg(options::OPT__ssaf_list_formats)) {
ssaf::printAvailableFormats(llvm::outs());
return false;
}
if (C.getArgs().hasArg(options::OPT_v) ||
C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) ||
C.getArgs().hasArg(options::OPT_print_supported_cpus) ||

View File

@ -29,3 +29,9 @@ ssaf::makeFormat(llvm::StringRef FormatName) {
assert(false && "Unknown SerializationFormat name");
return nullptr;
}
void ssaf::printAvailableFormats(llvm::raw_ostream &OS) {
OS << "OVERVIEW: Available SSAF serialization formats:\n\n";
for (const auto &Entry : SerializationFormatRegistry::entries())
OS << " " << Entry.getName() << " - " << Entry.getDesc() << "\n";
}

View File

@ -33,3 +33,9 @@ ssaf::makeTUSummaryExtractor(llvm::StringRef SummaryName,
assert(false && "Unknown SummaryExtractor name");
return nullptr;
}
void ssaf::printAvailableTUSummaryExtractors(llvm::raw_ostream &OS) {
OS << "OVERVIEW: Available SSAF summary extractors:\n\n";
for (const auto &Entry : TUSummaryExtractorRegistry::entries())
OS << " " << Entry.getName() << " - " << Entry.getDesc() << "\n";
}

View File

@ -1,7 +1,21 @@
// RUN: %clang --help 2>&1 | FileCheck %s
// RUN: %clang_cc1 --help 2>&1 | FileCheck %s
// DEFINE: %{filecheck} = FileCheck %s --match-full-lines --check-prefix
// CHECK: --ssaf-extract-summaries=<summary-names>
// CHECK-NEXT: Comma-separated list of summary names to extract
// CHECK-NEXT: --ssaf-tu-summary-file=<path>.<format>
// CHECK-NEXT: The output file for the extracted summaries. The extension selects which file format to use.
// RUN: %clang --help 2>&1 | %{filecheck}=HELP
// RUN: %clang_cc1 --help 2>&1 | %{filecheck}=HELP
// HELP: --ssaf-extract-summaries=<summary-names>
// HELP-NEXT: Comma-separated list of summary names to extract
// HELP-NEXT: --ssaf-list-extractors Display the list of available SSAF summary extractors
// HELP-NEXT: --ssaf-list-formats Display the list of available SSAF serialization formats
// HELP-NEXT: --ssaf-tu-summary-file=<path>.<format>
// HELP-NEXT: The output file for the extracted summaries. The extension selects which file format to use.
// FIXME: --ssaf-list-{extractors,formats} only work with the `clang` driver.
// RUN: %clang --ssaf-list-extractors 2>&1 | %{filecheck}=LIST-EXTRACTORS
// LIST-EXTRACTORS: OVERVIEW: Available SSAF summary extractors:
// RUN: %clang --ssaf-list-formats 2>&1 | %{filecheck}=LIST-FORMATS
// LIST-FORMATS: OVERVIEW: Available SSAF serialization formats:
// LIST-FORMATS: json - JSON serialization format
// RUN: %clang --ssaf-list-extractors --ssaf-list-formats 2>&1 | %{filecheck}=LIST-EXTRACTORS,LIST-FORMATS

View File

@ -16,6 +16,8 @@ static_library("Driver") {
"//clang/lib/Basic",
"//clang/lib/Frontend",
"//clang/lib/Options",
"//clang/lib/ScalableStaticAnalysisFramework/Core",
"//clang/lib/ScalableStaticAnalysisFramework/Frontend",
"//llvm/include/llvm/Config:llvm-config",
"//llvm/lib/BinaryFormat",
"//llvm/lib/Option",