@@ -3654,7 +3654,7 @@ bool Compiler<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
36543654
36553655 assert (V.isStruct ());
36563656 assert (V.getStructNumBases () == 0 );
3657- if (!this ->visitAPValueInitializer (V, E))
3657+ if (!this ->visitAPValueInitializer (V, E, E-> getType () ))
36583658 return false ;
36593659
36603660 return this ->emitFinishInit (E);
@@ -4641,48 +4641,27 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
46414641
46424642template <class Emitter >
46434643bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
4644- const Expr *E) {
4645-
4644+ const Expr *E, QualType T) {
46464645 if (Val.isStruct ()) {
4647- const Record *R = this ->getRecord (E-> getType () );
4646+ const Record *R = this ->getRecord (T );
46484647 assert (R);
46494648 for (unsigned I = 0 , N = Val.getStructNumFields (); I != N; ++I) {
46504649 const APValue &F = Val.getStructField (I);
46514650 const Record::Field *RF = R->getField (I);
4651+ QualType FieldType = RF->Decl ->getType ();
46524652
4653- if (F.isInt () || F.isFloat () || F.isLValue () || F.isMemberPointer ()) {
4654- PrimType T = classifyPrim (RF->Decl ->getType ());
4655- if (!this ->visitAPValue (F, T, E))
4656- return false ;
4657- if (!this ->emitInitField (T, RF->Offset , E))
4658- return false ;
4659- } else if (F.isArray ()) {
4660- assert (RF->Desc ->isPrimitiveArray ());
4661- const auto *ArrType = RF->Decl ->getType ()->getAsArrayTypeUnsafe ();
4662- PrimType ElemT = classifyPrim (ArrType->getElementType ());
4663- assert (ArrType);
4664-
4665- if (!this ->emitGetPtrField (RF->Offset , E))
4653+ if (std::optional<PrimType> PT = classify (FieldType)) {
4654+ if (!this ->visitAPValue (F, *PT, E))
46664655 return false ;
4667-
4668- for (unsigned A = 0 , AN = F.getArraySize (); A != AN; ++A) {
4669- if (!this ->visitAPValue (F.getArrayInitializedElt (A), ElemT, E))
4670- return false ;
4671- if (!this ->emitInitElem (ElemT, A, E))
4672- return false ;
4673- }
4674-
4675- if (!this ->emitPopPtr (E))
4656+ if (!this ->emitInitField (*PT, RF->Offset , E))
46764657 return false ;
4677- } else if (F. isStruct () || F. isUnion ()) {
4658+ } else {
46784659 if (!this ->emitGetPtrField (RF->Offset , E))
46794660 return false ;
4680- if (!this ->visitAPValueInitializer (F, E))
4661+ if (!this ->visitAPValueInitializer (F, E, FieldType ))
46814662 return false ;
46824663 if (!this ->emitPopPtr (E))
46834664 return false ;
4684- } else {
4685- assert (false && " I don't think this should be possible" );
46864665 }
46874666 }
46884667 return true ;
@@ -4696,6 +4675,28 @@ bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
46964675 if (!this ->visitAPValue (F, T, E))
46974676 return false ;
46984677 return this ->emitInitField (T, RF->Offset , E);
4678+ } else if (Val.isArray ()) {
4679+ const auto *ArrType = T->getAsArrayTypeUnsafe ();
4680+ QualType ElemType = ArrType->getElementType ();
4681+ for (unsigned A = 0 , AN = Val.getArraySize (); A != AN; ++A) {
4682+ const APValue &Elem = Val.getArrayInitializedElt (A);
4683+ if (std::optional<PrimType> ElemT = classify (ElemType)) {
4684+ if (!this ->visitAPValue (Elem, *ElemT, E))
4685+ return false ;
4686+ if (!this ->emitInitElem (*ElemT, A, E))
4687+ return false ;
4688+ } else {
4689+ if (!this ->emitConstUint32 (A, E))
4690+ return false ;
4691+ if (!this ->emitArrayElemPtrUint32 (E))
4692+ return false ;
4693+ if (!this ->visitAPValueInitializer (Elem, E, ElemType))
4694+ return false ;
4695+ if (!this ->emitPopPtr (E))
4696+ return false ;
4697+ }
4698+ }
4699+ return true ;
46994700 }
47004701 // TODO: Other types.
47014702
@@ -6385,7 +6386,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
63856386 return false ;
63866387 return this ->emitInitGlobal (*T, *Index, E);
63876388 }
6388- return this ->visitAPValueInitializer (TPOD->getValue (), E);
6389+ return this ->visitAPValueInitializer (TPOD->getValue (), E,
6390+ TPOD->getType ());
63896391 }
63906392 return false ;
63916393 }
0 commit comments