labath added a comment.

Implementing `classof` via an enum is the simplest and most common solution, 
but it is not the only thing possible. The central enum thingy is fine when all 
the subclasses are also defined centrally, but for a more distributed scenario 
like this one, it begins to smell, as now the `LanguageRuntime` class suddenly 
needs to be aware of all of its subclasses.

A way to implement that without the all-encompassing enum would be via 
something like:

  struct Runtime: {
  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
  static char ID;
  };
  
  ...
  
  struct DerivedRuntime: ParentRuntime {
  bool isA(const void *ClassID) const override { return ClassID == &ID || 
ParentRuntime::isA(ClassID); }
  
  static bool classof(const Runtime *R) { return R->isA(&ID); }
  static char ID;
  };

It takes a while to wrap your head around this, but what it basically does is 
use pointer equality instead of enum comparisons. Then, if you have a multi 
level hierarchy (like we have here), it uses the virtual `isA` function to 
check for subclasses instead of doing a range comparison: The desired target 
class type is captured in the `classof` call. Then the `|| Parent::isA` chain 
builds up a list of actual classes that this object is an instance of. If the 
captured type is found in this list, then the cast can proceed. You can see 
this in action in `llvm/Support/Error.h` (though the ErrorInfo class does not 
implement the `classof` method, because it wants to do casting differently.)

This is a bit more complex set up, but I think the overall result is worth it.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62934/new/

https://reviews.llvm.org/D62934



_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to