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

Reply via email to