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 anchor source to the `AnchorSources`
13// list in the relevant force-linker header:
14//
15// // MyAnalysis.cpp
16// static AnalysisRegistry::Add<MyAnalysis>
17// Registered("One-line description of MyAnalysis");
18//
19// namespace clang::ssaf {
20// // NOLINTNEXTLINE(misc-use-internal-linkage)
21// volatile int MyAnalysisAnchorSource = 0;
22// } // namespace clang::ssaf
23//
24// // Extend SSAFBuiltinForceLinker.h (or the relevant force-linker header)
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_SCALABLESTATICANALYSIS_CORE_WHOLEPROGRAMANALYSIS_ANALYSISREGISTRY_H
32#define LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_WHOLEPROGRAMANALYSIS_ANALYSISREGISTRY_H
33
39#include "llvm/Support/Error.h"
40#include "llvm/Support/Registry.h"
41#include <memory>
42#include <string>
43#include <vector>
44
45LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT,
46 llvm::Registry<clang::ssaf::AnalysisBase>)
47
48namespace clang::ssaf {
49
50/// Unified registry for SummaryAnalysis and DerivedAnalysis implementations.
51///
52/// Internally uses a single llvm::Registry<AnalysisBase>. The correct kind
53/// is carried by the AnalysisBase::TheKind tag set in each subclass
54/// constructor.
55class AnalysisRegistry {
56 using RegistryT = llvm::Registry<AnalysisBase>;
57
58 AnalysisRegistry() = delete;
59
60public:
61 /// Registers AnalysisT with the unified registry.
62 ///
63 /// The registry entry name is derived automatically from
64 /// AnalysisT::ResultType::analysisName(), so name-mismatch bugs are
65 /// impossible.
66 ///
67 /// Add objects must be declared static at namespace scope.
68 template <typename AnalysisT> struct Add {
69 static_assert(std::is_base_of_v<SummaryAnalysisBase, AnalysisT> ||
70 std::is_base_of_v<DerivedAnalysisBase, AnalysisT>,
71 "AnalysisT must derive from SummaryAnalysis<...> or "
72 "DerivedAnalysis<...>");
73
74 explicit Add(llvm::StringRef Desc)
75 : Name(AnalysisT::ResultType::analysisName().str().str()),
76 Node(Name, Desc) {
77 if (contains(AnalysisT::ResultType::analysisName())) {
78 ErrorBuilder::fatal("duplicate analysis registration for '{0}'", Name);
79 }
80 getAnalysisNames().push_back(AnalysisT::ResultType::analysisName());
81 }
82
83 Add(const Add &) = delete;
84 Add &operator=(const Add &) = delete;
85
86 private:
87 std::string Name;
88 RegistryT::Add<AnalysisT> Node;
89 };
90
91 /// Returns true if an analysis is registered under \p Name.
92 static bool contains(const AnalysisName &Name);
93
94 /// Returns the names of all registered analyses.
95 static const std::vector<AnalysisName> &names();
96
97 /// Instantiates the analysis registered under \p Name, or returns an error
98 /// if no such analysis is registered.
99 static llvm::Expected<std::unique_ptr<AnalysisBase>>
100 instantiate(const AnalysisName &Name);
101
102private:
103 /// Returns the global list of registered analysis names.
104 ///
105 /// Uses a function-local static to avoid static initialization order
106 /// fiasco: Add<T> objects in other translation units may push names before
107 /// a plain static data member could be constructed.
108 static std::vector<AnalysisName> &getAnalysisNames();
109};
110
111} // namespace clang::ssaf
112
113#endif // LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_WHOLEPROGRAMANALYSIS_ANALYSISREGISTRY_H
LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT, llvm::Registry< clang::ssaf::JSONFormat::FormatInfo >) LLVM_DECLARE_REGISTRY_EX(CLANG_ABI_EXPORT
static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)
llvm::Registry< SummaryDataBuilderBase > RegistryT
bool Add(InterpState &S, CodePtr OpPC)
Definition Interp.h:406