这个头文件定义了一个用于生成中间表示(IR)的数据结构,主要用于编译器前端将抽象语法树(AST)转换为中间代码。以下是文件中定义的主要类和功能的整理和解释: --- ### **1. 类型系统(Type System)** #### **1.1 `Type` 类** - **作用**:表示所有基本标量类型(如 `int`、`float`、`void` 等)以及指针类型和函数类型。 - **成员**: - `Kind` 枚举:表示类型的种类(如 `kInt`、`kFloat`、`kPointer` 等)。 - `kind`:当前类型的种类。 - 构造函数:`Type(Kind kind)`,用于初始化类型。 - 静态方法:如 `getIntType()`、`getFloatType()` 等,用于获取特定类型的单例对象。 - 类型检查方法:如 `isInt()`、`isFloat()` 等,用于检查当前类型是否为某种类型。 - `getSize()`:获取类型的大小。 - `as()`:将当前类型动态转换为派生类(如 `PointerType` 或 `FunctionType`)。 #### **1.2 `PointerType` 类** - **作用**:表示指针类型,派生自 `Type`。 - **成员**: - `baseType`:指针指向的基础类型。 - 静态方法:`get(Type *baseType)`,用于获取指向 `baseType` 的指针类型。 - `getBaseType()`:获取指针指向的基础类型。 #### **1.3 `FunctionType` 类** - **作用**:表示函数类型,派生自 `Type`。 - **成员**: - `returnType`:函数的返回类型。 - `paramTypes`:函数的参数类型列表。 - 静态方法:`get(Type *returnType, const std::vector ¶mTypes)`,用于获取函数类型。 - `getReturnType()`:获取函数的返回类型。 - `getParamTypes()`:获取函数的参数类型列表。 --- ### **2. 中间表示(IR)** #### **2.1 `Value` 类** - **作用**:表示 IR 中的所有值(如指令、常量、参数等)。 - **成员**: - `Kind` 枚举:表示值的种类(如 `kAdd`、`kSub`、`kConstant` 等)。 - `kind`:当前值的种类。 - `type`:值的类型。 - `name`:值的名称。 - `uses`:值的用途列表(表示哪些指令使用了该值)。 - 构造函数:`Value(Kind kind, Type *type, const std::string &name)`。 - 类型检查方法:如 `isInt()`、`isFloat()` 等。 - `getUses()`:获取值的用途列表。 - `replaceAllUsesWith(Value *value)`:将该值的所有用途替换为另一个值。 - `print(std::ostream &os)`:打印值的表示。 #### **2.2 `ConstantValue` 类** - **作用**:表示编译时常量(如整数常量、浮点数常量)。 - **成员**: - `iScalar` 和 `fScalar`:分别存储整数和浮点数常量的值。 - 静态方法:`get(int value)` 和 `get(float value)`,用于获取常量值。 - `getInt()` 和 `getFloat()`:获取常量的值。 #### **2.3 `Argument` 类** - **作用**:表示函数或基本块的参数。 - **成员**: - `block`:参数所属的基本块。 - `index`:参数的索引。 - 构造函数:`Argument(Type *type, BasicBlock *block, int index, const std::string &name)`。 - `getParent()`:获取参数所属的基本块。 - `getIndex()`:获取参数的索引。 #### **2.4 `BasicBlock` 类** - **作用**:表示基本块,包含一系列指令。 - **成员**: - `parent`:基本块所属的函数。 - `instructions`:基本块中的指令列表。 - `arguments`:基本块的参数列表。 - `successors` 和 `predecessors`:基本块的后继和前驱列表。 - 构造函数:`BasicBlock(Function *parent, const std::string &name)`。 - `getParent()`:获取基本块所属的函数。 - `getInstructions()`:获取基本块中的指令列表。 - `createArgument()`:为基本块创建一个参数。 #### **2.5 `Instruction` 类** - **作用**:表示 IR 中的指令,派生自 `User`。 - **成员**: - `Kind` 枚举:表示指令的种类(如 `kAdd`、`kSub`、`kLoad` 等)。 - `kind`:当前指令的种类。 - `parent`:指令所属的基本块。 - 构造函数:`Instruction(Kind kind, Type *type, BasicBlock *parent, const std::string &name)`。 - `getParent()`:获取指令所属的基本块。 - `getFunction()`:获取指令所属的函数。 - 指令分类方法:如 `isBinary()`、`isUnary()`、`isMemory()` 等。 #### **2.6 `User` 类** - **作用**:表示使用其他值的指令或全局值,派生自 `Value`。 - **成员**: - `operands`:指令的操作数列表。 - 构造函数:`User(Kind kind, Type *type, const std::string &name)`。 - `getOperand(int index)`:获取指定索引的操作数。 - `addOperand(Value *value)`:添加一个操作数。 - `replaceOperand(int index, Value *value)`:替换指定索引的操作数。 #### **2.7 具体指令类** - **`CallInst`**:表示函数调用指令。 - **`UnaryInst`**:表示一元操作指令(如取反、类型转换)。 - **`BinaryInst`**:表示二元操作指令(如加法、减法)。 - **`ReturnInst`**:表示返回指令。 - **`UncondBrInst`**:表示无条件跳转指令。 - **`CondBrInst`**:表示条件跳转指令。 - **`AllocaInst`**:表示栈内存分配指令。 - **`LoadInst`**:表示从内存加载值的指令。 - **`StoreInst`**:表示将值存储到内存的指令。 --- ### **3. 模块和函数** #### **3.1 `Function` 类** - **作用**:表示函数,包含多个基本块。 - **成员**: - `parent`:函数所属的模块。 - `blocks`:函数中的基本块列表。 - 构造函数:`Function(Module *parent, Type *type, const std::string &name)`。 - `getReturnType()`:获取函数的返回类型。 - `getParamTypes()`:获取函数的参数类型列表。 - `addBasicBlock()`:为函数添加一个基本块。 #### **3.2 `GlobalValue` 类** - **作用**:表示全局变量或常量。 - **成员**: - `parent`:全局值所属的模块。 - `hasInit`:是否有初始化值。 - `isConst`:是否是常量。 - 构造函数:`GlobalValue(Module *parent, Type *type, const std::string &name, const std::vector &dims, Value *init)`。 - `init()`:获取全局值的初始化值。 #### **3.3 `Module` 类** - **作用**:表示整个编译单元(如一个源文件)。 - **成员**: - `children`:模块中的所有值(如函数、全局变量)。 - `functions`:模块中的函数列表。 - `globals`:模块中的全局变量列表。 - `createFunction()`:创建一个函数。 - `createGlobalValue()`:创建一个全局变量。 - `getFunction()`:获取指定名称的函数。 - `getGlobalValue()`:获取指定名称的全局变量。 --- ### **4. 工具类** #### **4.1 `Use` 类** - **作用**:表示值与其使用者之间的关系。 - **成员**: - `index`:值在使用者操作数列表中的索引。 - `user`:使用者。 - `value`:被使用的值。 - 构造函数:`Use(int index, User *user, Value *value)`。 - `getValue()`:获取被使用的值。 #### **4.2 `range` 类** - **作用**:封装迭代器对 `[begin, end)`,用于遍历容器。 - **成员**: - `begin()` 和 `end()`:返回范围的起始和结束迭代器。 - `size()`:返回范围的大小。 - `empty()`:判断范围是否为空。 --- ### **5. 总结** - **类型系统**:`Type`、`PointerType`、`FunctionType` 用于表示 IR 中的类型。 - **中间表示**:`Value`、`ConstantValue`、`Instruction` 等用于表示 IR 中的值和指令。 - **模块和函数**:`Module`、`Function`、`GlobalValue` 用于组织 IR 的结构。 - **工具类**:`Use` 和 `range` 用于辅助实现 IR 的数据结构和遍历。 这个头文件定义了一个完整的 IR 数据结构,适用于编译器前端将 AST 转换为中间代码,并支持后续的优化和目标代码生成。