RedDocMD added a comment. > So here you are implying that for reinterpret casts, the > `CastE->path_begin()-end()` range is empty? And that is why you need to > manually come up with a //possible// CXXBaseSpecifier list?
@steakhal, Yes. For illustration, the following code: struct Base { int field; }; struct Derived : public Base {}; struct DoubleDerived : public Derived {}; int f() { int DoubleDerived::*ddf = &Derived::field; int Base::*bf1 = static_cast<int Base::*>(ddf); int Base::*bf2 = reinterpret_cast<int Base::*>(ddf); } produces the following (truncated) AST dump -FunctionDecl 0x12f3890 <line:8:1, line:12:1> line:8:5 f 'int ()' `-CompoundStmt 0x12f3ec0 <col:9, line:12:1> |-DeclStmt 0x12f3b70 <line:9:3, col:44> | `-VarDecl 0x12f3a18 <col:3, col:39> col:23 used ddf 'int DoubleDerived::*' cinit | `-ImplicitCastExpr 0x12f3b48 <col:29, col:39> 'int DoubleDerived::*' <BaseToDerivedMemberPointer (Derived -> Base)> | `-UnaryOperator 0x12f3b30 <col:29, col:39> 'int Base::*' prefix '&' cannot overflow | `-DeclRefExpr 0x12f3ad0 <col:30, col:39> 'int' lvalue Field 0x12f33d0 'field' 'int' |-DeclStmt 0x12f3d20 <line:10:3, col:49> | `-VarDecl 0x12f3bf0 <col:3, col:48> col:14 bf1 'int Base::*' cinit | `-CXXStaticCastExpr 0x12f3ce0 <col:20, col:48> 'int Base::*' static_cast<int struct Base::*> <DerivedToBaseMemberPointer (Derived -> Base)> | `-ImplicitCastExpr 0x12f3cc8 <col:45> 'int DoubleDerived::*' <LValueToRValue> part_of_explicit_cast | `-DeclRefExpr 0x12f3c60 <col:45> 'int DoubleDerived::*' lvalue Var 0x12f3a18 'ddf' 'int DoubleDerived::*' `-DeclStmt 0x12f3ea8 <line:11:3, col:54> `-VarDecl 0x12f3d88 <col:3, col:53> col:14 bf2 'int Base::*' cinit `-CXXReinterpretCastExpr 0x12f3e78 <col:20, col:53> 'int Base::*' reinterpret_cast<int struct Base::*> <ReinterpretMemberPointer> `-ImplicitCastExpr 0x12f3e60 <col:50> 'int DoubleDerived::*' <LValueToRValue> part_of_explicit_cast `-DeclRefExpr 0x12f3df8 <col:50> 'int DoubleDerived::*' lvalue Var 0x12f3a18 'ddf' 'int DoubleDerived::*' If you compare the three cases: 1. The first statement has an implicit cast inserted during parsing, and so we need not calculate the path manually 2. The second statement has a `static_cast` and it also supplies a path, except that we need to remove these bases instead of adding. (Ref to D95877 <https://reviews.llvm.org/D95877>). 3. The third statement has no path provided, because it is a `reinterpret_cast` and the parser cannot produce a path in all cases (if you cast to an integer for an instance) - so it doesn't produce any path With the parser not providing us with info, we have to figure it out in a different way. Also, it is not one //possible// path but the //only// possible path. If there are multiple acceptable paths then it is illegal to define such a member-pointer and the frontend will reject it as such. > I strongly encourage you to find a better alternative to this manual graph > search. > This information must be available somewhere. > > Have you looked at `CXXRecordDecl::isDerivedFrom()`? Or any other member > functions of that class? Unfortunately, all the methods on CXXRecordDecl, like the one you mentioned, are for querying and thus returns a `bool`, while I need the entire path. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D96976/new/ https://reviews.llvm.org/D96976 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits