@@ -442,26 +442,42 @@ bool Pointer::isInitialized() const {
442442 assert (BS.Pointee && " Cannot check if null pointer was initialized" );
443443 const Descriptor *Desc = getFieldDesc ();
444444 assert (Desc);
445- if (Desc->isPrimitiveArray ()) {
446- if (isStatic () && BS.Base == 0 )
447- return true ;
445+ if (Desc->isPrimitiveArray ())
446+ return isElementInitialized (getIndex ());
448447
449- InitMapPtr &IM = getInitMap ();
448+ if (asBlockPointer ().Base == 0 )
449+ return true ;
450+ // Field has its bit in an inline descriptor.
451+ return getInlineDesc ()->IsInitialized ;
452+ }
453+
454+ bool Pointer::isElementInitialized (unsigned Index) const {
455+ if (!isBlockPointer ())
456+ return true ;
457+
458+ const Descriptor *Desc = getFieldDesc ();
459+ assert (Desc);
460+
461+ if (isStatic () && BS.Base == 0 )
462+ return true ;
463+
464+ if (isRoot () && BS.Base == sizeof (GlobalInlineDescriptor)) {
465+ const GlobalInlineDescriptor &GD =
466+ *reinterpret_cast <const GlobalInlineDescriptor *>(block ()->rawData ());
467+ return GD.InitState == GlobalInitState::Initialized;
468+ }
450469
470+ if (Desc->isPrimitiveArray ()) {
471+ InitMapPtr &IM = getInitMap ();
451472 if (!IM)
452473 return false ;
453474
454475 if (IM->first )
455476 return true ;
456477
457- return IM->second ->isElementInitialized (getIndex () );
478+ return IM->second ->isElementInitialized (Index );
458479 }
459-
460- if (asBlockPointer ().Base == 0 )
461- return true ;
462-
463- // Field has its bit in an inline descriptor.
464- return getInlineDesc ()->IsInitialized ;
480+ return isInitialized ();
465481}
466482
467483void Pointer::initialize () const {
@@ -524,6 +540,23 @@ void Pointer::initializeAllElements() const {
524540 }
525541}
526542
543+ bool Pointer::allElementsInitialized () const {
544+ assert (getFieldDesc ()->isPrimitiveArray ());
545+ assert (isArrayRoot ());
546+
547+ if (isStatic () && BS.Base == 0 )
548+ return true ;
549+
550+ if (isRoot () && BS.Base == sizeof (GlobalInlineDescriptor)) {
551+ const GlobalInlineDescriptor &GD =
552+ *reinterpret_cast <const GlobalInlineDescriptor *>(block ()->rawData ());
553+ return GD.InitState == GlobalInitState::Initialized;
554+ }
555+
556+ InitMapPtr &IM = getInitMap ();
557+ return IM && IM->first ;
558+ }
559+
527560void Pointer::activate () const {
528561 // Field has its bit in an inline descriptor.
529562 assert (BS.Base != 0 && " Only composite fields can be activated" );
@@ -771,13 +804,13 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
771804 R = APValue (APValue::UninitArray{}, NumElems, NumElems);
772805
773806 bool Ok = true ;
774- for (unsigned I = 0 ; I < NumElems; ++I) {
807+ OptPrimType ElemT = Ctx.classify (ElemTy);
808+ for (unsigned I = 0 ; I != NumElems; ++I) {
775809 APValue &Slot = R.getArrayInitializedElt (I);
776- const Pointer &EP = Ptr.atIndex (I);
777- if (OptPrimType T = Ctx.classify (ElemTy)) {
778- TYPE_SWITCH (*T, Slot = EP.deref <T>().toAPValue (ASTCtx));
810+ if (ElemT) {
811+ TYPE_SWITCH (*ElemT, Slot = Ptr.elem <T>(I).toAPValue (ASTCtx));
779812 } else {
780- Ok &= Composite (ElemTy, EP .narrow (), Slot);
813+ Ok &= Composite (ElemTy, Ptr. atIndex (I) .narrow (), Slot);
781814 }
782815 }
783816 return Ok;
0 commit comments