3535#include  " llvm/Support/Debug.h" 
3636#include  " llvm/Support/raw_os_ostream.h" 
3737
38+ #include  < map> 
3839#include  < set> 
3940#include  < sstream> 
4041#include  < string> 
@@ -1222,20 +1223,22 @@ namespace Cpp {
12221223    return  0 ;
12231224  }
12241225
1225-   intptr_t  GetVariableOffset (compat::Interpreter& I, Decl* D) {
1226+   intptr_t  GetVariableOffset (compat::Interpreter& I, Decl* D,
1227+                              CXXRecordDecl* BaseCXXRD) {
12261228    if  (!D)
12271229      return  0 ;
12281230
12291231    auto & C = I.getSema ().getASTContext ();
12301232
12311233    if  (auto * FD = llvm::dyn_cast<FieldDecl>(D)) {
1232-       const   clang::RecordDecl* RD  = FD->getParent ();
1234+       clang::RecordDecl* FieldParentRecordDecl  = FD->getParent ();
12331235      intptr_t  offset =
12341236          C.toCharUnitsFromBits (C.getFieldOffset (FD)).getQuantity ();
1235-       while  (RD->isAnonymousStructOrUnion ()) {
1236-         const  clang::RecordDecl* anon = RD;
1237-         RD = llvm::dyn_cast<RecordDecl>(anon->getParent ());
1238-         for  (auto  F = RD->field_begin (); F != RD->field_end (); ++F) {
1237+       while  (FieldParentRecordDecl->isAnonymousStructOrUnion ()) {
1238+         clang::RecordDecl* anon = FieldParentRecordDecl;
1239+         FieldParentRecordDecl = llvm::dyn_cast<RecordDecl>(anon->getParent ());
1240+         for  (auto  F = FieldParentRecordDecl->field_begin ();
1241+              F != FieldParentRecordDecl->field_end (); ++F) {
12391242          const  auto * RT = F->getType ()->getAs <RecordType>();
12401243          if  (!RT)
12411244            continue ;
@@ -1246,6 +1249,46 @@ namespace Cpp {
12461249        }
12471250        offset += C.toCharUnitsFromBits (C.getFieldOffset (FD)).getQuantity ();
12481251      }
1252+       if  (BaseCXXRD && BaseCXXRD != FieldParentRecordDecl) {
1253+         //  FieldDecl FD belongs to some class C, but the base class BaseCXXRD is
1254+         //  not C. That means BaseCXXRD derives from C. Offset needs to be
1255+         //  calculated for Derived class
1256+ 
1257+         //  Depth first Search is performed to the class that declears FD from
1258+         //  the base class
1259+         std::vector<CXXRecordDecl*> stack;
1260+         std::map<CXXRecordDecl*, CXXRecordDecl*> direction;
1261+         stack.push_back (BaseCXXRD);
1262+         while  (!stack.empty ()) {
1263+           CXXRecordDecl* RD = stack.back ();
1264+           stack.pop_back ();
1265+           size_t  num_bases = GetNumBases (RD);
1266+           bool  flag = false ;
1267+           for  (size_t  i = 0 ; i < num_bases; i++) {
1268+             auto * CRD = static_cast <CXXRecordDecl*>(GetBaseClass (RD, i));
1269+             direction[CRD] = RD;
1270+             if  (CRD == FieldParentRecordDecl) {
1271+               flag = true ;
1272+               break ;
1273+             }
1274+             stack.push_back (CRD);
1275+           }
1276+           if  (flag)
1277+             break ;
1278+         }
1279+         if  (auto * RD = llvm::dyn_cast<CXXRecordDecl>(FieldParentRecordDecl)) {
1280+           //  add in the offsets for the (multi level) base classes
1281+           while  (BaseCXXRD != RD) {
1282+             CXXRecordDecl* Parent = direction.at (RD);
1283+             offset += C.getASTRecordLayout (Parent)
1284+                           .getBaseClassOffset (RD)
1285+                           .getQuantity ();
1286+             RD = Parent;
1287+           }
1288+         } else  {
1289+           assert (false  && " Unreachable" 
1290+         }
1291+       }
12491292      return  offset;
12501293    }
12511294
@@ -1321,9 +1364,11 @@ namespace Cpp {
13211364    return  0 ;
13221365  }
13231366
1324-   intptr_t  GetVariableOffset (TCppScope_t var) {
1367+   intptr_t  GetVariableOffset (TCppScope_t var, TCppScope_t parent ) {
13251368    auto * D = static_cast <Decl*>(var);
1326-     return  GetVariableOffset (getInterp (), D);
1369+     auto * RD =
1370+         llvm::dyn_cast_or_null<CXXRecordDecl>(static_cast <Decl*>(parent));
1371+     return  GetVariableOffset (getInterp (), D, RD);
13271372  }
13281373
13291374  //  Check if the Access Specifier of the variable matches the provided value.
0 commit comments