forked from ppxf25tqu/nudt-compiler-cpp
Merge pull request '基本完成了ir生成' (#4) from ptabmhn4l/nudt-compiler-cpp:feature/ir into develop
commit
fd45b74e2e
@ -0,0 +1,70 @@
|
|||||||
|
#ifndef SEM_FUNC_H
|
||||||
|
#define SEM_FUNC_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "SysYParser.h"
|
||||||
|
|
||||||
|
namespace sem {
|
||||||
|
|
||||||
|
// 常量值类型
|
||||||
|
struct ConstValue {
|
||||||
|
bool is_int; // 是否为整型
|
||||||
|
long long int_val; // 整数值
|
||||||
|
double float_val; // 浮点值
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编译时求值常量表达式
|
||||||
|
ConstValue EvaluateConstExp(SysYParser::ConstExpContext& ctx);
|
||||||
|
|
||||||
|
// 求值表达式
|
||||||
|
ConstValue EvaluateExp(SysYParser::AddExpContext& ctx);
|
||||||
|
|
||||||
|
// 求值乘法表达式
|
||||||
|
ConstValue EvaluateMulExp(SysYParser::MulExpContext& ctx);
|
||||||
|
|
||||||
|
// 求值一元表达式
|
||||||
|
ConstValue EvaluateUnaryExp(SysYParser::UnaryExpContext& ctx);
|
||||||
|
|
||||||
|
// 求值基本表达式
|
||||||
|
ConstValue EvaluatePrimaryExp(SysYParser::PrimaryExpContext& ctx);
|
||||||
|
|
||||||
|
// 辅助函数:检查值是否为零
|
||||||
|
bool IsZero(const ConstValue& val);
|
||||||
|
|
||||||
|
// 辅助函数:加法
|
||||||
|
ConstValue AddValues(const ConstValue& lhs, const ConstValue& rhs);
|
||||||
|
|
||||||
|
// 辅助函数:减法
|
||||||
|
ConstValue SubValues(const ConstValue& lhs, const ConstValue& rhs);
|
||||||
|
|
||||||
|
// 辅助函数:乘法
|
||||||
|
ConstValue MulValues(const ConstValue& lhs, const ConstValue& rhs);
|
||||||
|
|
||||||
|
// 辅助函数:除法
|
||||||
|
ConstValue DivValues(const ConstValue& lhs, const ConstValue& rhs);
|
||||||
|
|
||||||
|
// 辅助函数:取模
|
||||||
|
ConstValue ModValues(const ConstValue& lhs, const ConstValue& rhs);
|
||||||
|
|
||||||
|
// 辅助函数:取负
|
||||||
|
ConstValue NegValue(const ConstValue& val);
|
||||||
|
|
||||||
|
// 辅助函数:逻辑非
|
||||||
|
ConstValue NotValue(const ConstValue& val);
|
||||||
|
|
||||||
|
// 检查常量初始化器
|
||||||
|
size_t CheckConstInitVal(SysYParser::ConstInitValContext& ctx,
|
||||||
|
const std::vector<size_t>& dimensions,
|
||||||
|
bool is_int,
|
||||||
|
size_t total_elements);
|
||||||
|
|
||||||
|
// 检查变量初始化器
|
||||||
|
size_t CheckInitVal(SysYParser::InitValContext& ctx,
|
||||||
|
const std::vector<size_t>& dimensions,
|
||||||
|
bool is_int,
|
||||||
|
size_t total_elements);
|
||||||
|
|
||||||
|
} // namespace sem
|
||||||
|
|
||||||
|
#endif // SEM_FUNC_H
|
||||||
@ -1,21 +1,68 @@
|
|||||||
// 保存函数列表并提供模块级上下文访问。
|
|
||||||
|
|
||||||
#include "ir/IR.h"
|
#include "ir/IR.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace ir {
|
namespace ir {
|
||||||
|
|
||||||
Context& Module::GetContext() { return context_; }
|
Context& Module::GetContext() { return context_; }
|
||||||
|
|
||||||
const Context& Module::GetContext() const { return context_; }
|
const Context& Module::GetContext() const { return context_; }
|
||||||
|
|
||||||
|
// ─── 函数管理 ─────────────────────────────────────────────────────────────────
|
||||||
Function* Module::CreateFunction(const std::string& name,
|
Function* Module::CreateFunction(const std::string& name,
|
||||||
std::shared_ptr<Type> ret_type) {
|
std::shared_ptr<Type> ret_type) {
|
||||||
functions_.push_back(std::make_unique<Function>(name, std::move(ret_type)));
|
functions_.push_back(std::make_unique<Function>(name, std::move(ret_type)));
|
||||||
return functions_.back().get();
|
Function* f = functions_.back().get();
|
||||||
|
func_map_[name] = f;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Function* Module::GetFunction(const std::string& name) const {
|
||||||
|
auto it = func_map_.find(name);
|
||||||
|
return it == func_map_.end() ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
|
const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
|
||||||
return functions_;
|
return functions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── 全局变量管理 ─────────────────────────────────────────────────────────────
|
||||||
|
GlobalVariable* Module::CreateGlobalVariable(const std::string& name,
|
||||||
|
bool is_const, int init_val,
|
||||||
|
int num_elements) {
|
||||||
|
globals_.push_back(
|
||||||
|
std::make_unique<GlobalVariable>(name, is_const, init_val, num_elements));
|
||||||
|
GlobalVariable* g = globals_.back().get();
|
||||||
|
global_map_[name] = g;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalVariable* Module::GetGlobalVariable(const std::string& name) const {
|
||||||
|
auto it = global_map_.find(name);
|
||||||
|
return it == global_map_.end() ? nullptr : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::unique_ptr<GlobalVariable>>&
|
||||||
|
Module::GetGlobalVariables() const {
|
||||||
|
return globals_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── 外部函数声明 ─────────────────────────────────────────────────────────────
|
||||||
|
void Module::DeclareExternalFunc(const std::string& name,
|
||||||
|
std::shared_ptr<Type> ret_type,
|
||||||
|
std::vector<std::shared_ptr<Type>> param_types,
|
||||||
|
bool is_variadic) {
|
||||||
|
if (external_decl_index_.count(name)) return; // 已声明,幂等
|
||||||
|
external_decl_index_[name] = external_decls_.size();
|
||||||
|
external_decls_.push_back(
|
||||||
|
{name, std::move(ret_type), std::move(param_types), is_variadic});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Module::HasExternalDecl(const std::string& name) const {
|
||||||
|
return external_decl_index_.count(name) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<ExternalFuncDecl>& Module::GetExternalDecls() const {
|
||||||
|
return external_decls_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ir
|
} // namespace ir
|
||||||
|
|||||||
@ -1,17 +1,28 @@
|
|||||||
// 维护局部变量声明的注册与查找。
|
// 维护变量和常量声明的注册与查找。
|
||||||
|
|
||||||
#include "sem/SymbolTable.h"
|
#include "sem/SymbolTable.h"
|
||||||
|
|
||||||
void SymbolTable::Add(const std::string& name,
|
void SymbolTable::AddVar(const std::string& name,
|
||||||
SysYParser::VarDefContext* decl) {
|
SysYParser::VarDefContext* decl) {
|
||||||
table_[name] = decl;
|
var_table_[name] = decl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymbolTable::AddConst(const std::string& name,
|
||||||
|
SysYParser::ConstDefContext* decl) {
|
||||||
|
const_table_[name] = decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SymbolTable::Contains(const std::string& name) const {
|
bool SymbolTable::Contains(const std::string& name) const {
|
||||||
return table_.find(name) != table_.end();
|
return var_table_.find(name) != var_table_.end() ||
|
||||||
|
const_table_.find(name) != const_table_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
SysYParser::VarDefContext* SymbolTable::Lookup(const std::string& name) const {
|
SysYParser::VarDefContext* SymbolTable::LookupVar(const std::string& name) const {
|
||||||
auto it = table_.find(name);
|
auto it = var_table_.find(name);
|
||||||
return it == table_.end() ? nullptr : it->second;
|
return it == var_table_.end() ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SysYParser::ConstDefContext* SymbolTable::LookupConst(const std::string& name) const {
|
||||||
|
auto it = const_table_.find(name);
|
||||||
|
return it == const_table_.end() ? nullptr : it->second;
|
||||||
|
}
|
||||||
@ -0,0 +1,313 @@
|
|||||||
|
#include "sem/func.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "utils/Log.h"
|
||||||
|
|
||||||
|
namespace sem {
|
||||||
|
|
||||||
|
// 编译时求值常量表达式
|
||||||
|
ConstValue EvaluateConstExp(SysYParser::ConstExpContext& ctx) {
|
||||||
|
return EvaluateExp(*ctx.addExp());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 求值表达式
|
||||||
|
ConstValue EvaluateExp(SysYParser::AddExpContext& ctx) {
|
||||||
|
ConstValue result = EvaluateMulExp(*ctx.mulExp(0));
|
||||||
|
for (size_t i = 1; i < ctx.mulExp().size(); ++i) {
|
||||||
|
ConstValue rhs = EvaluateMulExp(*ctx.mulExp(i));
|
||||||
|
if (ctx.AddOp(i-1)->getText() == "+") {
|
||||||
|
result = AddValues(result, rhs);
|
||||||
|
} else {
|
||||||
|
result = SubValues(result, rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 求值乘法表达式
|
||||||
|
ConstValue EvaluateMulExp(SysYParser::MulExpContext& ctx) {
|
||||||
|
ConstValue result = EvaluateUnaryExp(*ctx.unaryExp(0));
|
||||||
|
for (size_t i = 1; i < ctx.unaryExp().size(); ++i) {
|
||||||
|
ConstValue rhs = EvaluateUnaryExp(*ctx.unaryExp(i));
|
||||||
|
std::string op = ctx.MulOp(i-1)->getText();
|
||||||
|
if (op == "*") {
|
||||||
|
result = MulValues(result, rhs);
|
||||||
|
} else if (op == "/") {
|
||||||
|
if (IsZero(rhs)) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "除零错误"));
|
||||||
|
}
|
||||||
|
result = DivValues(result, rhs);
|
||||||
|
} else if (op == "%") {
|
||||||
|
if (IsZero(rhs)) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "取模除零错误"));
|
||||||
|
}
|
||||||
|
result = ModValues(result, rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 求值一元表达式
|
||||||
|
ConstValue EvaluateUnaryExp(SysYParser::UnaryExpContext& ctx) {
|
||||||
|
if (ctx.unaryOp()) {
|
||||||
|
ConstValue operand = EvaluateUnaryExp(*ctx.unaryExp());
|
||||||
|
std::string op = ctx.unaryOp()->getText();
|
||||||
|
if (op == "-") {
|
||||||
|
return NegValue(operand);
|
||||||
|
} else if (op == "!") {
|
||||||
|
return NotValue(operand);
|
||||||
|
} else {
|
||||||
|
return operand; // "+" 操作符
|
||||||
|
}
|
||||||
|
} else if (ctx.primaryExp()) {
|
||||||
|
return EvaluatePrimaryExp(*ctx.primaryExp());
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error(FormatError("sema", "非法常量表达式"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 求值基本表达式
|
||||||
|
ConstValue EvaluatePrimaryExp(SysYParser::PrimaryExpContext& ctx) {
|
||||||
|
if (ctx.exp()) {
|
||||||
|
return EvaluateExp(*ctx.exp()->addExp());
|
||||||
|
} else if (ctx.lVar()) {
|
||||||
|
// 处理变量引用(必须是已定义的常量)
|
||||||
|
auto* ident = ctx.lVar()->Ident();
|
||||||
|
if (!ident) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "非法变量引用"));
|
||||||
|
}
|
||||||
|
std::string name = ident->getText();
|
||||||
|
// 这里简化处理,实际应该在符号表中查找常量
|
||||||
|
// 暂时假设常量已经在前面被处理过
|
||||||
|
ConstValue val;
|
||||||
|
val.is_int = true;
|
||||||
|
val.int_val = 0;
|
||||||
|
val.float_val = 0.0;
|
||||||
|
return val;
|
||||||
|
} else if (ctx.number()) {
|
||||||
|
// 处理数字字面量
|
||||||
|
auto* int_const = ctx.number()->IntConst();
|
||||||
|
auto* float_const = ctx.number()->FloatConst();
|
||||||
|
|
||||||
|
ConstValue val;
|
||||||
|
if (int_const) {
|
||||||
|
val.is_int = true;
|
||||||
|
val.int_val = std::stoll(int_const->getText());
|
||||||
|
val.float_val = static_cast<double>(val.int_val);
|
||||||
|
} else if (float_const) {
|
||||||
|
val.is_int = false;
|
||||||
|
val.float_val = std::stod(float_const->getText());
|
||||||
|
val.int_val = static_cast<long long>(val.float_val);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error(FormatError("sema", "非法数字字面量"));
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error(FormatError("sema", "非法基本表达式"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:检查值是否为零
|
||||||
|
bool IsZero(const ConstValue& val) {
|
||||||
|
if (val.is_int) {
|
||||||
|
return val.int_val == 0;
|
||||||
|
} else {
|
||||||
|
return val.float_val == 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:加法
|
||||||
|
ConstValue AddValues(const ConstValue& lhs, const ConstValue& rhs) {
|
||||||
|
ConstValue result;
|
||||||
|
if (lhs.is_int && rhs.is_int) {
|
||||||
|
result.is_int = true;
|
||||||
|
result.int_val = lhs.int_val + rhs.int_val;
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
} else {
|
||||||
|
result.is_int = false;
|
||||||
|
result.float_val = (lhs.is_int ? lhs.int_val : lhs.float_val) +
|
||||||
|
(rhs.is_int ? rhs.int_val : rhs.float_val);
|
||||||
|
result.int_val = static_cast<long long>(result.float_val);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:减法
|
||||||
|
ConstValue SubValues(const ConstValue& lhs, const ConstValue& rhs) {
|
||||||
|
ConstValue result;
|
||||||
|
if (lhs.is_int && rhs.is_int) {
|
||||||
|
result.is_int = true;
|
||||||
|
result.int_val = lhs.int_val - rhs.int_val;
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
} else {
|
||||||
|
result.is_int = false;
|
||||||
|
result.float_val = (lhs.is_int ? lhs.int_val : lhs.float_val) -
|
||||||
|
(rhs.is_int ? rhs.int_val : rhs.float_val);
|
||||||
|
result.int_val = static_cast<long long>(result.float_val);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:乘法
|
||||||
|
ConstValue MulValues(const ConstValue& lhs, const ConstValue& rhs) {
|
||||||
|
ConstValue result;
|
||||||
|
if (lhs.is_int && rhs.is_int) {
|
||||||
|
result.is_int = true;
|
||||||
|
result.int_val = lhs.int_val * rhs.int_val;
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
} else {
|
||||||
|
result.is_int = false;
|
||||||
|
result.float_val = (lhs.is_int ? lhs.int_val : lhs.float_val) *
|
||||||
|
(rhs.is_int ? rhs.int_val : rhs.float_val);
|
||||||
|
result.int_val = static_cast<long long>(result.float_val);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:除法
|
||||||
|
ConstValue DivValues(const ConstValue& lhs, const ConstValue& rhs) {
|
||||||
|
ConstValue result;
|
||||||
|
if (lhs.is_int && rhs.is_int) {
|
||||||
|
result.is_int = true;
|
||||||
|
result.int_val = lhs.int_val / rhs.int_val;
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
} else {
|
||||||
|
result.is_int = false;
|
||||||
|
result.float_val = (lhs.is_int ? lhs.int_val : lhs.float_val) /
|
||||||
|
(rhs.is_int ? rhs.int_val : rhs.float_val);
|
||||||
|
result.int_val = static_cast<long long>(result.float_val);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:取模
|
||||||
|
ConstValue ModValues(const ConstValue& lhs, const ConstValue& rhs) {
|
||||||
|
ConstValue result;
|
||||||
|
if (!lhs.is_int || !rhs.is_int) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "取模运算只能用于整数"));
|
||||||
|
}
|
||||||
|
result.is_int = true;
|
||||||
|
result.int_val = lhs.int_val % rhs.int_val;
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:取负
|
||||||
|
ConstValue NegValue(const ConstValue& val) {
|
||||||
|
ConstValue result;
|
||||||
|
result.is_int = val.is_int;
|
||||||
|
if (val.is_int) {
|
||||||
|
result.int_val = -val.int_val;
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
} else {
|
||||||
|
result.float_val = -val.float_val;
|
||||||
|
result.int_val = static_cast<long long>(result.float_val);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:逻辑非
|
||||||
|
ConstValue NotValue(const ConstValue& val) {
|
||||||
|
ConstValue result;
|
||||||
|
result.is_int = true;
|
||||||
|
if (val.is_int) {
|
||||||
|
result.int_val = !val.int_val;
|
||||||
|
} else {
|
||||||
|
result.int_val = !val.float_val;
|
||||||
|
}
|
||||||
|
result.float_val = static_cast<double>(result.int_val);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查常量初始化器
|
||||||
|
size_t CheckConstInitVal(SysYParser::ConstInitValContext& ctx,
|
||||||
|
const std::vector<size_t>& dimensions,
|
||||||
|
bool is_int,
|
||||||
|
size_t total_elements) {
|
||||||
|
if (ctx.constExp()) {
|
||||||
|
// 单个常量值
|
||||||
|
// 求值并检查常量表达式
|
||||||
|
ConstValue value = EvaluateConstExp(*ctx.constExp());
|
||||||
|
|
||||||
|
// 检查类型约束
|
||||||
|
if (is_int && !value.is_int) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "整型数组的初始化列表中不能出现浮点型常量"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查值域
|
||||||
|
if (is_int) {
|
||||||
|
if (value.int_val < INT_MIN || value.int_val > INT_MAX) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "整数值超过int类型表示范围"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else if (ctx.L_BRACE()) {
|
||||||
|
// 花括号初始化列表
|
||||||
|
size_t count = 0;
|
||||||
|
auto init_vals = ctx.constInitVal();
|
||||||
|
|
||||||
|
for (auto* init_val : init_vals) {
|
||||||
|
// 计算剩余维度的总元素个数
|
||||||
|
size_t remaining_elements = total_elements;
|
||||||
|
if (!dimensions.empty()) {
|
||||||
|
remaining_elements = total_elements / dimensions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
count += CheckConstInitVal(*init_val,
|
||||||
|
std::vector<size_t>(dimensions.begin() + 1, dimensions.end()),
|
||||||
|
is_int,
|
||||||
|
remaining_elements);
|
||||||
|
}
|
||||||
|
// 检查总元素个数
|
||||||
|
if (count > total_elements) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "初始化列表元素个数超过数组大小"));
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
} else {
|
||||||
|
// 空初始化列表
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查变量初始化器
|
||||||
|
size_t CheckInitVal(SysYParser::InitValContext& ctx,
|
||||||
|
const std::vector<size_t>& dimensions,
|
||||||
|
bool is_int,
|
||||||
|
size_t total_elements) {
|
||||||
|
if (ctx.exp()) {
|
||||||
|
// 单个表达式值
|
||||||
|
// 检查表达式中的变量引用
|
||||||
|
// 这里不需要编译时求值,只需要检查类型约束
|
||||||
|
// 类型检查在IR生成阶段进行
|
||||||
|
return 1;
|
||||||
|
} else if (ctx.L_BRACE()) {
|
||||||
|
// 花括号初始化列表
|
||||||
|
size_t count = 0;
|
||||||
|
auto init_vals = ctx.initVal();
|
||||||
|
|
||||||
|
for (auto* init_val : init_vals) {
|
||||||
|
// 计算剩余维度的总元素个数
|
||||||
|
size_t remaining_elements = total_elements;
|
||||||
|
if (!dimensions.empty()) {
|
||||||
|
remaining_elements = total_elements / dimensions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
count += CheckInitVal(*init_val,
|
||||||
|
std::vector<size_t>(dimensions.begin() + 1, dimensions.end()),
|
||||||
|
is_int,
|
||||||
|
remaining_elements);
|
||||||
|
}
|
||||||
|
// 检查总元素个数
|
||||||
|
if (count > total_elements) {
|
||||||
|
throw std::runtime_error(FormatError("sema", "初始化列表元素个数超过数组大小"));
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
} else {
|
||||||
|
// 空初始化列表
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sem
|
||||||
Loading…
Reference in new issue