LLVM isa <>如何实现?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (70)

来自http://llvm.org/docs/CodingStandards.html#ci_rtti_exceptions

LLVM确实广泛使用了使用像isa <>,cast <>和dyn_cast <>这样的模板的RTTI手动滚动形式。这种RTTI形式可以选择加入任何类。它也比dynamic_cast <>效率更高。

如何实现这个?

提问于
用户回答回答于

基本上每个类都应该实现classof()方法,它可以完成所有必要的工作。例如,Value的classof()例程如下所示:

  // Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const Value *) {
    return true; // Values are always values.
  }

为了检查我们是否有适当类型的类,每个类都有唯一的ValueID。ni 可以在include / llvm / Value.h文件中查看ValueID的完整列表。这个ValueID的用法如下:

  /// Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const Function *) { return true; }
  static inline bool classof(const Value *V) {
    return V->getValueID() == Value::FunctionVal;
  }

简而言之,每个类都应该实现classof()方法来执行必要的决策。有问题的实施由一组唯一的ValueID组成。因此,为了实现classof(),只需要将参数的ValueID与自己的ValueID进行比较。

用户回答回答于

首先,LLVM系统非常具体,完全没有RTTI系统的直接替代品。

Premises:

对于大多数类,不需要生成RTTI信息

  • 当需要时,信息只在给定的层次结构内才有意义.
  • 我们排除了这个系统的多重继承.

识别一个对象类:

采取简单的层次结构,例如:

struct Base {}; /* abstract */
struct DerivedLeft: Base {}; /* abstract */
struct DerivedRight:Base {};
struct MostDerivedL1: DerivedLeft {};
struct MostDerivedL2: DerivedLeft {};
struct MostDerivedR: DerivedRight {};

我们将创建一个特定于此层次结构的枚举,并为每个可以实例化的层次结构成员(其他都是无用的)使用枚举成员。

enum BaseId {
  DerivedRightId,
  MostDerivedL1Id,
  MostDerivedL2Id,
  MostDerivedRId
};

然后,Base类将增加一个方法,该方法将返回此枚举。

struct Base {
  static inline bool classof(Base const*) { return true; }

  Base(BaseId id): Id(id) {}

  BaseId getValueID() const { return Id; }

  BaseId Id;
};

而且每一个具体的类都以这种方式增强:

struct DerivedRight: Base {
  static inline bool classof(DerivedRight const*) { return true; }

  static inline bool classof(Base const* B) {
    switch(B->getValueID()) {
    case DerivedRightId: case MostDerivedRId: return true;
    default: return false;
    }
  }

  DerivedRight(BaseId id = DerivedRightId): Base(id) {}
};

现在,可以简单地查询确切的类型,以进行投射。

隐藏实施细节

一个给定的类应该实现两个classof方法:一个为最深的基础(测试合适的值BaseId)和一个为自己(纯优化)。例如:

struct MostDerivedL1: DerivedLeft {
  static inline bool classof(MostDerivedL1 const*) { return true; }

  static inline bool classof(Base const* B) {
    return B->getValueID() == MostDerivedL1Id;
  }

  MostDerivedL1(): DerivedLeft(MostDerivedL1Id) {}
};

通过这种方式,我们可以通过模板检查是否可以投射。

template <typename To, typename From>
bool isa(From const& f) {
  return To::classof(&f);
}

扫码关注云+社区

领取腾讯云代金券