@@ -3650,7 +3650,7 @@ bool Compiler<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
36503650
36513651 assert (V.isStruct ());
36523652 assert (V.getStructNumBases () == 0 );
3653- if (!this ->visitAPValueInitializer (V, E))
3653+ if (!this ->visitAPValueInitializer (V, E, E-> getType () ))
36543654 return false ;
36553655
36563656 return this ->emitFinishInit (E);
@@ -4637,48 +4637,27 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
46374637
46384638template <class Emitter >
46394639bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
4640- const Expr *E) {
4641-
4640+ const Expr *E, QualType T) {
46424641 if (Val.isStruct ()) {
4643- const Record *R = this ->getRecord (E-> getType () );
4642+ const Record *R = this ->getRecord (T );
46444643 assert (R);
46454644 for (unsigned I = 0 , N = Val.getStructNumFields (); I != N; ++I) {
46464645 const APValue &F = Val.getStructField (I);
46474646 const Record::Field *RF = R->getField (I);
4647+ QualType FieldType = RF->Decl ->getType ();
46484648
4649- if (F.isInt () || F.isFloat () || F.isLValue () || F.isMemberPointer ()) {
4650- PrimType T = classifyPrim (RF->Decl ->getType ());
4651- if (!this ->visitAPValue (F, T, E))
4652- return false ;
4653- if (!this ->emitInitField (T, RF->Offset , E))
4654- return false ;
4655- } else if (F.isArray ()) {
4656- assert (RF->Desc ->isPrimitiveArray ());
4657- const auto *ArrType = RF->Decl ->getType ()->getAsArrayTypeUnsafe ();
4658- PrimType ElemT = classifyPrim (ArrType->getElementType ());
4659- assert (ArrType);
4660-
4661- if (!this ->emitGetPtrField (RF->Offset , E))
4649+ if (std::optional<PrimType> PT = classify (FieldType)) {
4650+ if (!this ->visitAPValue (F, *PT, E))
46624651 return false ;
4663-
4664- for (unsigned A = 0 , AN = F.getArraySize (); A != AN; ++A) {
4665- if (!this ->visitAPValue (F.getArrayInitializedElt (A), ElemT, E))
4666- return false ;
4667- if (!this ->emitInitElem (ElemT, A, E))
4668- return false ;
4669- }
4670-
4671- if (!this ->emitPopPtr (E))
4652+ if (!this ->emitInitField (*PT, RF->Offset , E))
46724653 return false ;
4673- } else if (F. isStruct () || F. isUnion ()) {
4654+ } else {
46744655 if (!this ->emitGetPtrField (RF->Offset , E))
46754656 return false ;
4676- if (!this ->visitAPValueInitializer (F, E))
4657+ if (!this ->visitAPValueInitializer (F, E, FieldType ))
46774658 return false ;
46784659 if (!this ->emitPopPtr (E))
46794660 return false ;
4680- } else {
4681- assert (false && " I don't think this should be possible" );
46824661 }
46834662 }
46844663 return true ;
@@ -4692,6 +4671,28 @@ bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
46924671 if (!this ->visitAPValue (F, T, E))
46934672 return false ;
46944673 return this ->emitInitField (T, RF->Offset , E);
4674+ } else if (Val.isArray ()) {
4675+ const auto *ArrType = T->getAsArrayTypeUnsafe ();
4676+ QualType ElemType = ArrType->getElementType ();
4677+ for (unsigned A = 0 , AN = Val.getArraySize (); A != AN; ++A) {
4678+ const APValue &Elem = Val.getArrayInitializedElt (A);
4679+ if (std::optional<PrimType> ElemT = classify (ElemType)) {
4680+ if (!this ->visitAPValue (Elem, *ElemT, E))
4681+ return false ;
4682+ if (!this ->emitInitElem (*ElemT, A, E))
4683+ return false ;
4684+ } else {
4685+ if (!this ->emitConstUint32 (A, E))
4686+ return false ;
4687+ if (!this ->emitArrayElemPtrUint32 (E))
4688+ return false ;
4689+ if (!this ->visitAPValueInitializer (Elem, E, ElemType))
4690+ return false ;
4691+ if (!this ->emitPopPtr (E))
4692+ return false ;
4693+ }
4694+ }
4695+ return true ;
46954696 }
46964697 // TODO: Other types.
46974698
@@ -6374,7 +6375,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
63746375 return false ;
63756376 return this ->emitInitGlobal (*T, *Index, E);
63766377 }
6377- return this ->visitAPValueInitializer (TPOD->getValue (), E);
6378+ return this ->visitAPValueInitializer (TPOD->getValue (), E,
6379+ TPOD->getType ());
63786380 }
63796381 return false ;
63806382 }
0 commit comments