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
44namespace clang::ssaf {
45
46/// Unified registry for SummaryAnalysis and DerivedAnalysis implementations.
47///
48/// Internally uses a single llvm::Registry<AnalysisBase>. The correct kind
49/// is carried by the AnalysisBase::TheKind tag set in each subclass
50/// constructor.
51class AnalysisRegistry {
52 using RegistryT = llvm::Registry<AnalysisBase>;
53
54 AnalysisRegistry() = delete;
55
56public:
57 /// Registers AnalysisT with the unified registry.
58 ///
59 /// The registry entry name is derived automatically from
60 /// AnalysisT::ResultType::analysisName(), so name-mismatch bugs are
61 /// impossible.
62 ///
63 /// Add objects must be declared static at namespace scope.
64 template <typename AnalysisT> struct Add {
65 static_assert(std::is_base_of_v<SummaryAnalysisBase, AnalysisT> ||
66 std::is_base_of_v<DerivedAnalysisBase, AnalysisT>,
67 "AnalysisT must derive from SummaryAnalysis<...> or "
68 "DerivedAnalysis<...>");
69
70 explicit Add(llvm::StringRef Desc)
71 : Name(AnalysisT::ResultType::analysisName().str().str()),
72 Node(Name, Desc) {
73 if (contains(AnalysisT::ResultType::analysisName())) {
74 ErrorBuilder::fatal("duplicate analysis registration for '{0}'", Name);
75 }
76 getAnalysisNames().push_back(AnalysisT::ResultType::analysisName());
77 }
78
79 Add(const Add &) = delete;
80 Add &operator=(const Add &) = delete;
81
82 private:
83 std::string Name;
84 RegistryT::Add<AnalysisT> Node;
85 };
86
87 /// Returns true if an analysis is registered under \p Name.
88 static bool contains(const AnalysisName &Name);
89
90 /// Returns the names of all registered analyses.
91 static const std::vector<AnalysisName> &names();
92
93 /// Instantiates the analysis registered under \p Name, or returns an error
94 /// if no such analysis is registered.
96 instantiate(const AnalysisName &Name);
97
98private:
99 /// Returns the global list of registered analysis names.
100 ///
101 /// Uses a function-local static to avoid static initialization order
102 /// fiasco: Add<T> objects in other translation units may push names before
103 /// a plain static data member could be constructed.
104 static std::vector<AnalysisName> &getAnalysisNames();
105};
106
107} // namespace clang::ssaf
108
109#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