@@ -2179,6 +2179,52 @@ static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC,
2179
2179
return true ;
2180
2180
}
2181
2181
2182
+ static unsigned computeFullDescSize (const ASTContext &ASTCtx,
2183
+ const Descriptor *Desc) {
2184
+
2185
+ if (Desc->isPrimitive ())
2186
+ return ASTCtx.getTypeSizeInChars (Desc->getType ()).getQuantity ();
2187
+
2188
+ if (Desc->isArray ())
2189
+ return ASTCtx.getTypeSizeInChars (Desc->getElemQualType ()).getQuantity () *
2190
+ Desc->getNumElems ();
2191
+
2192
+ if (Desc->isRecord ())
2193
+ return ASTCtx.getTypeSizeInChars (Desc->getType ()).getQuantity ();
2194
+
2195
+ llvm_unreachable (" Unhandled descriptor type" );
2196
+ return 0 ;
2197
+ }
2198
+
2199
+ static bool interp__builtin_object_size (InterpState &S, CodePtr OpPC,
2200
+ const InterpFrame *Frame,
2201
+ const Function *Func,
2202
+ const CallExpr *Call) {
2203
+ PrimType KindT = *S.getContext ().classify (Call->getArg (1 ));
2204
+ unsigned Kind = peekToAPSInt (S.Stk , KindT).getZExtValue ();
2205
+
2206
+ assert (Kind <= 3 && " unexpected kind" );
2207
+
2208
+ const Pointer &Ptr =
2209
+ S.Stk .peek <Pointer>(align (primSize (KindT)) + align (primSize (PT_Ptr)));
2210
+
2211
+ if (Ptr .isZero ())
2212
+ return false ;
2213
+
2214
+ const Descriptor *DeclDesc = Ptr .getDeclDesc ();
2215
+ if (!DeclDesc)
2216
+ return false ;
2217
+
2218
+ const ASTContext &ASTCtx = S.getASTContext ();
2219
+
2220
+ unsigned ByteOffset = 0 ;
2221
+ unsigned FullSize = computeFullDescSize (ASTCtx, DeclDesc);
2222
+
2223
+ pushInteger (S, FullSize - ByteOffset , Call->getType ());
2224
+
2225
+ return true ;
2226
+ }
2227
+
2182
2228
bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
2183
2229
const CallExpr *Call, uint32_t BuiltinID) {
2184
2230
if (!S.getASTContext ().BuiltinInfo .isConstantEvaluated (BuiltinID))
@@ -2681,6 +2727,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
2681
2727
return false ;
2682
2728
break ;
2683
2729
2730
+ case Builtin::BI__builtin_object_size:
2731
+ case Builtin::BI__builtin_dynamic_object_size:
2732
+ if (!interp__builtin_object_size (S, OpPC, Frame, F, Call))
2733
+ return false ;
2734
+ break ;
2735
+
2684
2736
default :
2685
2737
S.FFDiag (S.Current ->getLocation (OpPC),
2686
2738
diag::note_invalid_subexpr_in_const_expr)
0 commit comments