@@ -1265,6 +1265,24 @@ static size_t getBitOffsetOfField(ASTContext &C, const FieldDecl *FD) {
1265
1265
return Layout.getFieldOffset (FD->getFieldIndex ());
1266
1266
}
1267
1267
1268
+ static size_t getOffsetOfBase (ASTContext &C, const CXXBaseSpecifier *Base) {
1269
+ const CXXRecordDecl *Derived = Base->getDerived ();
1270
+ assert (Derived && " no parent for field!" );
1271
+
1272
+ const ASTRecordLayout &Layout = C.getASTRecordLayout (Derived);
1273
+
1274
+ QualType BaseQT = Base->getType ();
1275
+ BaseQT = desugarType (BaseQT, /* UnwrapAliases=*/ true , /* DropCV=*/ false ,
1276
+ /* DropRefs=*/ false );
1277
+ CXXRecordDecl *RD = BaseQT->getAsCXXRecordDecl ();
1278
+ assert (RD && " base isn't a record type?" );
1279
+
1280
+ if (Base->isVirtual ())
1281
+ return Layout.getVBaseClassOffset (RD).getQuantity ();
1282
+ else
1283
+ return Layout.getBaseClassOffset (RD).getQuantity ();
1284
+ }
1285
+
1268
1286
static bool ensureDeclared (ASTContext &C, QualType QT, SourceLocation SpecLoc) {
1269
1287
// If it's an ElaboratedType, get the underlying NamedType.
1270
1288
if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(QT))
@@ -4903,7 +4921,6 @@ bool offset_of(APValue &Result, ASTContext &C, MetaActions &Meta,
4903
4921
case ReflectionKind::Value:
4904
4922
case ReflectionKind::Template:
4905
4923
case ReflectionKind::Namespace:
4906
- case ReflectionKind::BaseSpecifier:
4907
4924
case ReflectionKind::DataMemberSpec:
4908
4925
case ReflectionKind::Annotation:
4909
4926
return DiagnoseReflectionKind (Diagnoser, Range, " a non-static data member" ,
@@ -4916,6 +4933,16 @@ bool offset_of(APValue &Result, ASTContext &C, MetaActions &Meta,
4916
4933
return DiagnoseReflectionKind (Diagnoser, Range, " a non-static data member" ,
4917
4934
DescriptionOf (RV));
4918
4935
}
4936
+ case ReflectionKind::BaseSpecifier: {
4937
+ CXXBaseSpecifier *Base = RV.getReflectedBaseSpecifier ();
4938
+ if (Base->isVirtual () && Base->getDerived ()->isAbstract ())
4939
+ return Diagnoser (Range.getBegin (),
4940
+ diag::metafn_offset_virtual_base_of_abstract)
4941
+ << Range;
4942
+
4943
+ size_t Offset = getOffsetOfBase (C, Base);
4944
+ return SetAndSucceed (Result, APValue (C.MakeIntValue (Offset, ResultTy)));
4945
+ }
4919
4946
}
4920
4947
llvm_unreachable (" unknown reflection kind" );
4921
4948
}
@@ -4990,7 +5017,6 @@ bool bit_offset_of(APValue &Result, ASTContext &C, MetaActions &Meta,
4990
5017
case ReflectionKind::Value:
4991
5018
case ReflectionKind::Template:
4992
5019
case ReflectionKind::Namespace:
4993
- case ReflectionKind::BaseSpecifier:
4994
5020
case ReflectionKind::DataMemberSpec:
4995
5021
case ReflectionKind::Annotation:
4996
5022
return DiagnoseReflectionKind (Diagnoser, Range, " a non-static data member" ,
@@ -5003,6 +5029,8 @@ bool bit_offset_of(APValue &Result, ASTContext &C, MetaActions &Meta,
5003
5029
return DiagnoseReflectionKind (Diagnoser, Range, " a non-static data member" ,
5004
5030
DescriptionOf (RV));
5005
5031
}
5032
+ case ReflectionKind::BaseSpecifier:
5033
+ return SetAndSucceed (Result, APValue (C.MakeIntValue (0 , ResultTy)));
5006
5034
}
5007
5035
llvm_unreachable (" unknown reflection kind" );
5008
5036
}
0 commit comments