clang 23.0.0git
AnalysisRegistry.h
Go to the documentation of this file.
1//===- AnalysisRegistry.h ---------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Unified registry for both SummaryAnalysis and DerivedAnalysis subclasses.
10//
11// To register an analysis, add a static Add<AnalysisT> and an anchor source
12// in its translation unit, then add the matching anchor destination to the
13// relevant force-linker header:
14//
15// // MyAnalysis.cpp
16// static AnalysisRegistry::Add<MyAnalysis>
17// Registered("One-line description of MyAnalysis");
18//
19// volatile int SSAFMyAnalysisAnchorSource = 0;
20//
21// // SSAFBuiltinForceLinker.h (or the relevant force-linker header)
22// extern volatile int SSAFMyAnalysisAnchorSource;
23// [[maybe_unused]] static int SSAFMyAnalysisAnchorDestination =
24// SSAFMyAnalysisAnchorSource;
25//
26// The registry entry name is derived automatically from
27// MyAnalysis::analysisName(), so name-mismatch bugs are impossible.
28//
29//===----------------------------------------------------------------------===//
30
31#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_WHOLEPROGRAMANALYSIS_ANALYSISREGISTRY_H
32#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_WHOLEPROGRAMANALYSIS_ANALYSISREGISTRY_H
33
38#include "llvm/Support/Error.h"
39#include "llvm/Support/Registry.h"
40#include <memory>
41#include <string>
42#include <vector>
43
44LLVM_DECLARE_REGISTRY(llvm::Registry<clang::ssaf::AnalysisBase>)
45
46namespace clang::ssaf {
47
48/// Unified registry for SummaryAnalysis and DerivedAnalysis implementations.
49///
50/// Internally uses a single llvm::Registry<AnalysisBase>. The correct kind
51/// is carried by the AnalysisBase::TheKind tag set in each subclass
52/// constructor.
53class AnalysisRegistry {
54 using RegistryT = llvm::Registry<AnalysisBase>;
55
56 AnalysisRegistry() = delete;
57
58public:
59 /// Registers AnalysisT with the unified registry.
60 ///
61 /// The registry entry name is derived automatically from
62 /// AnalysisT::ResultType::analysisName(), so name-mismatch bugs are
63 /// impossible.
64 ///
65 /// Add objects must be declared static at namespace scope.
66 template <typename AnalysisT> struct Add {
67 static_assert(std::is_base_of_v<SummaryAnalysisBase, AnalysisT> ||
68 std::is_base_of_v<DerivedAnalysisBase, AnalysisT>,
69 "AnalysisT must derive from SummaryAnalysis<...> or "
70 "DerivedAnalysis<...>");
71
72 explicit Add(llvm::StringRef Desc)
73 : Name(AnalysisT::ResultType::analysisName().str().str()),
74 Node(Name, Desc) {
75 if (contains(AnalysisT::ResultType::analysisName())) {
76 ErrorBuilder::fatal("duplicate analysis registration for '{0}'", Name);
77 }
78 getAnalysisNames().push_back(AnalysisT::ResultType::analysisName());
79 }
80
81 Add(const Add &) = delete;
82 Add &operator=(const Add &) = delete;
83
84 private:
85 std::string Name;
86 RegistryT::Add<AnalysisT> Node;
87 };
88
89 /// Returns true if an analysis is registered under \p Name.
90 static bool contains(const AnalysisName &Name);
91
92 /// Returns the names of all registered analyses.
93 static const std::vector<AnalysisName> &names();
94
95 /// Instantiates the analysis registered under \p Name, or returns an error
96 /// if no such analysis is registered.
98 instantiate(const AnalysisName &Name);
99
100private:
101 /// Returns the global list of registered analysis names.
102 ///
103 /// Uses a function-local static to avoid static initialization order
104 /// fiasco: Add<T> objects in other translation units may push names before
105 /// a plain static data member could be constructed.
106 static std::vector<AnalysisName> &getAnalysisNames();
107};
108
109} // namespace clang::ssaf
110
111#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_WHOLEPROGRAMANALYSIS_ANALYSISREGISTRY_H
Uniquely identifies a whole-program analysis and the AnalysisResult it produces.
static bool contains(const AnalysisName &Name)
Returns true if an analysis is registered under Name.
static const std::vector< AnalysisName > & names()
Returns the names of all registered analyses.
static llvm::Expected< std::unique_ptr< AnalysisBase > > instantiate(const AnalysisName &Name)
Instantiates the analysis registered under Name, or returns an error if no such analysis is registere...
static void fatal(const char *Fmt, Args &&...ArgVals)
Report a fatal error with formatted message and terminate execution.
Add & operator=(const Add &)=delete