* Copyright (c) 2026 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#ifndef PYPTO_IR_VERIFIER_VERIFIER_H_
#define PYPTO_IR_VERIFIER_VERIFIER_H_
#include <memory>
#include <string>
#include <unordered_set>
#include <vector>
#include "core/error.h"
#include "ir/program.h"
namespace pypto {
namespace ir {
* \brief Base class for IR property verifiers
*
* Each verifier implements a specific check on IR programs.
* Verifiers can detect errors or warnings and add them to a diagnostics vector.
* Each verifier receives a ProgramPtr and internally decides whether to iterate
* over functions or check program-level properties.
*
* To create a new property verifier:
* 1. Inherit from PropertyVerifier
* 2. Implement GetName() to return a unique name
* 3. Implement Verify() to perform the verification logic
*
* Example:
* @code
* class MyVerifier : public PropertyVerifier {
* public:
* std::string GetName() const override { return "MyVerifier"; }
* void Verify(const ProgramPtr& program, std::vector<Diagnostic>& diagnostics) override {
* for (const auto& [gv, func] : program->functions_) {
* // Verification logic per function
* }
* }
* };
* @endcode
*/
class PropertyVerifier {
public:
virtual ~PropertyVerifier() = default;
* \brief Get the name of this verifier
* \return Unique name (e.g., "SSAVerify", "TypeCheck")
*/
[[nodiscard]] virtual std::string GetName() const = 0;
* \brief Verify a program and collect diagnostics
* \param program Program to verify
* \param diagnostics Vector to append diagnostics to
*
* This method should examine the program and add any detected issues
* to the diagnostics vector. It should not throw exceptions - all issues
* should be reported through diagnostics.
*/
virtual void Verify(const ProgramPtr& program, std::vector<Diagnostic>& diagnostics) = 0;
};
using PropertyVerifierPtr = std::shared_ptr<PropertyVerifier>;
using VerifyRule = PropertyVerifier;
using VerifyRulePtr = PropertyVerifierPtr;
namespace verifier_detail {
template <typename VerifierT>
void VerifyFunctionBodies(const ProgramPtr& program, std::vector<Diagnostic>& diagnostics)
{
if (!program) {
return;
}
for (const auto& entry : program->functions_) {
const auto& func = entry.second;
if (!func) {
continue;
}
VerifierT verifier(diagnostics);
if (func->body_) {
verifier.VisitStmt(func->body_);
}
}
}
}
* \brief Factory function for creating SSA property verifier
* \return Shared pointer to SSA PropertyVerifier
*/
PropertyVerifierPtr CreateSSAPropertyVerifier();
* \brief Factory function for creating type check property verifier
* \return Shared pointer to TypeCheck PropertyVerifier
*/
PropertyVerifierPtr CreateTypeCheckPropertyVerifier();
* \brief Factory function for creating no nested call property verifier
* \return Shared pointer to NoNestedCall PropertyVerifier
*/
PropertyVerifierPtr CreateNoNestedCallPropertyVerifier();
inline VerifyRulePtr CreateSSAVerifyRule() { return CreateSSAPropertyVerifier(); }
inline VerifyRulePtr CreateTypeCheckRule() { return CreateTypeCheckPropertyVerifier(); }
inline VerifyRulePtr CreateNoNestedCallVerifyRule() { return CreateNoNestedCallPropertyVerifier(); }
* \brief IR verification system
*
* IRVerifier manages a collection of property verifiers and applies them to programs.
* Verifiers can be enabled/disabled individually, and the verifier can operate in two modes:
* - Verify(): Collects all diagnostics without throwing
* - VerifyOrThrow(): Collects diagnostics and throws if errors are found
*
* Usage:
* @code
* auto verifier = IRVerifier::CreateDefault();
* verifier.DisableRule("TypeCheck");
* auto diagnostics = verifier.Verify(program);
* verifier.VerifyOrThrow(program);
* @endcode
*/
class IRVerifier {
public:
IRVerifier();
* \brief Add a property verifier
* \param rule Shared pointer to the verifier to add
*
* Verifiers are executed in the order they are added.
* If a verifier with the same name already exists, it will not be added again.
*/
void AddRule(PropertyVerifierPtr rule);
void EnableRule(const std::string& name);
void DisableRule(const std::string& name);
[[nodiscard]] bool IsRuleEnabled(const std::string& name) const;
[[nodiscard]] std::vector<Diagnostic> Verify(const ProgramPtr& program) const;
void VerifyOrThrow(const ProgramPtr& program) const;
static std::string GenerateReport(const std::vector<Diagnostic>& diagnostics);
static IRVerifier CreateDefault();
private:
std::vector<PropertyVerifierPtr> rules_;
std::unordered_set<std::string> disabled_rules_;
};
}
}
#endif