@@ -2196,6 +2196,53 @@ static unsigned computeFullDescSize(const ASTContext &ASTCtx,
2196
2196
return 0 ;
2197
2197
}
2198
2198
2199
+ static unsigned computePointerOffset (const ASTContext &ASTCtx,
2200
+ const Pointer &Ptr) {
2201
+ unsigned Result = 0 ;
2202
+
2203
+ Pointer P = Ptr;
2204
+ while (P.isArrayElement () || P.isField ()) {
2205
+ P = P.expand ();
2206
+ const Descriptor *D = P.getFieldDesc ();
2207
+
2208
+ if (P.isArrayElement ()) {
2209
+ unsigned ElemSize =
2210
+ ASTCtx.getTypeSizeInChars (D->getElemQualType ()).getQuantity ();
2211
+ if (P.isOnePastEnd ())
2212
+ Result += ElemSize * P.getNumElems ();
2213
+ else
2214
+ Result += ElemSize * P.getIndex ();
2215
+ P = P.expand ().getArray ();
2216
+ } else if (P.isBaseClass ()) {
2217
+
2218
+ const auto *RD = cast<CXXRecordDecl>(D->asDecl ());
2219
+ bool IsVirtual = Ptr.isVirtualBaseClass ();
2220
+ P = P.getBase ();
2221
+ const Record *BaseRecord = P.getRecord ();
2222
+
2223
+ const ASTRecordLayout &Layout =
2224
+ ASTCtx.getASTRecordLayout (cast<CXXRecordDecl>(BaseRecord->getDecl ()));
2225
+ if (IsVirtual)
2226
+ Result += Layout.getVBaseClassOffset (RD).getQuantity ();
2227
+ else
2228
+ Result += Layout.getBaseClassOffset (RD).getQuantity ();
2229
+ } else if (P.isField ()) {
2230
+ const FieldDecl *FD = P.getField ();
2231
+ const ASTRecordLayout &Layout =
2232
+ ASTCtx.getASTRecordLayout (FD->getParent ());
2233
+ unsigned FieldIndex = FD->getFieldIndex ();
2234
+ uint64_t FieldOffset =
2235
+ ASTCtx.toCharUnitsFromBits (Layout.getFieldOffset (FieldIndex))
2236
+ .getQuantity ();
2237
+ Result += FieldOffset;
2238
+ P = P.getBase ();
2239
+ } else
2240
+ llvm_unreachable (" Unhandled descriptor type" );
2241
+ }
2242
+
2243
+ return Result;
2244
+ }
2245
+
2199
2246
static bool interp__builtin_object_size (InterpState &S, CodePtr OpPC,
2200
2247
const InterpFrame *Frame,
2201
2248
const Function *Func,
@@ -2217,7 +2264,7 @@ static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC,
2217
2264
2218
2265
const ASTContext &ASTCtx = S.getASTContext ();
2219
2266
2220
- unsigned ByteOffset = 0 ;
2267
+ unsigned ByteOffset = computePointerOffset (ASTCtx, Ptr) ;
2221
2268
unsigned FullSize = computeFullDescSize (ASTCtx, DeclDesc);
2222
2269
2223
2270
pushInteger (S, FullSize - ByteOffset, Call->getType ());
0 commit comments