================ @@ -484,83 +484,87 @@ class Call { } // end eval namespace -class CheckerBase : public ProgramPointTag { - /// A single checker class (i.e. a subclass of `CheckerBase`) can implement - /// multiple user-facing checkers that have separate names and can be enabled - /// separately, but are backed by the same singleton checker object. - SmallVector<std::optional<CheckerNameRef>, 1> RegisteredNames; - - friend class ::clang::ento::CheckerManager; +/// A `CheckerFrontend` instance is what the user recognizes as "one checker": +/// it has a public canonical name (injected from the `CheckerManager`), can be +/// enabled or disabled, can have associated checker options and can be printed +/// as the "source" of bug reports. +/// The singleton instance of a simple `Checker<...>` is-a `CheckerFrontend` +/// (for historical reasons, to preserve old straightforward code), while the +/// singleton instance of a `CheckerFamily<...>` class owns multiple +/// `CheckerFrontend` instances as data members. +/// Modeling checkers that are hidden from the user but can be enabled or +/// disabled separately (as dependencies of other checkers) are also considered +/// to be `CheckerFrontend`s. +class CheckerFrontend { + /// The `Name` is nullopt if and only if the checker is disabled. + std::optional<CheckerNameRef> Name; public: - CheckerNameRef getName(CheckerPartIdx Idx = DefaultPart) const { - assert(Idx < RegisteredNames.size() && "Checker part index is too large!"); - std::optional<CheckerNameRef> Name = RegisteredNames[Idx]; - assert(Name && "Requested checker part is not registered!"); - return *Name; - } - - bool isPartEnabled(CheckerPartIdx Idx) const { - return Idx < RegisteredNames.size() && RegisteredNames[Idx].has_value(); - } - - void registerCheckerPart(CheckerPartIdx Idx, CheckerNameRef Name) { - // Paranoia: notice if e.g. UINT_MAX is passed as a checker part index. - assert(Idx < 256 && "Checker part identifiers should be small integers."); - - if (Idx >= RegisteredNames.size()) - RegisteredNames.resize(Idx + 1, std::nullopt); - - assert(!RegisteredNames[Idx] && "Repeated registration of checker a part!"); - RegisteredNames[Idx] = Name; - } - - StringRef getTagDescription() const override { - // When the ExplodedGraph is dumped for debugging (in DOT format), this - // method is called to attach a description to nodes created by this - // checker _class_. Ideally this should be recognizable identifier of the - // whole class, but for this debugging purpose it's sufficient to use the - // name of the first registered checker part. - for (const auto &OptName : RegisteredNames) - if (OptName) - return *OptName; - - return "Unregistered checker"; + void enable(CheckerManager &Mgr) { + assert(!Name && "Checker part registered twice!"); + Name = Mgr.getCurrentCheckerName(); } + bool isEnabled() const { return static_cast<bool>(Name); } ---------------- steakhal wrote:
```suggestion bool isEnabled() const { return Name.has_value(); } ``` https://github.com/llvm/llvm-project/pull/139256 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits