@@ -90,6 +90,8 @@ bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
9090 if (!Ctx->emitConstUint32 (Offset, E))
9191 return false ;
9292 return Ctx->emitArrayElemPtrPopUint32 (E);
93+ case K_InitList:
94+ return true ;
9395 default :
9496 llvm_unreachable (" Unhandled InitLink kind" );
9597 }
@@ -1717,6 +1719,8 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
17171719template <class Emitter >
17181720bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
17191721 const Expr *ArrayFiller, const Expr *E) {
1722+ InitLinkScope<Emitter> ILS (this , InitLink::InitList ());
1723+
17201724 QualType QT = E->getType ();
17211725 if (const auto *AT = QT->getAs <AtomicType>())
17221726 QT = AT->getValueType ();
@@ -1754,6 +1758,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
17541758 auto initPrimitiveField = [=](const Record::Field *FieldToInit,
17551759 const Expr *Init, PrimType T) -> bool {
17561760 InitStackScope<Emitter> ISS (this , isa<CXXDefaultInitExpr>(Init));
1761+ InitLinkScope<Emitter> ILS (this , InitLink::Field (FieldToInit->Offset ));
17571762 if (!this ->visit (Init))
17581763 return false ;
17591764
@@ -1766,6 +1771,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
17661771 const Expr *Init) -> bool {
17671772 InitStackScope<Emitter> ISS (this , isa<CXXDefaultInitExpr>(Init));
17681773 InitLinkScope<Emitter> ILS (this , InitLink::Field (FieldToInit->Offset ));
1774+
17691775 // Non-primitive case. Get a pointer to the field-to-initialize
17701776 // on the stack and recurse into visitInitializer().
17711777 if (!this ->emitGetPtrField (FieldToInit->Offset , Init))
@@ -3812,6 +3818,7 @@ template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
38123818
38133819 if (!this ->emitGetPtrLocal (*LocalIndex, E))
38143820 return false ;
3821+ InitLinkScope<Emitter> ILS (this , InitLink::Temp (*LocalIndex));
38153822 return this ->visitInitializer (E);
38163823 }
38173824
@@ -4848,18 +4855,49 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
48484855 // instance pointer of the current function frame, but e.g. to the declaration
48494856 // currently being initialized. Here we emit the necessary instruction(s) for
48504857 // this scenario.
4851- if (!InitStackActive || !E-> isImplicit () )
4858+ if (!InitStackActive)
48524859 return this ->emitThis (E);
48534860
4854- if (InitStackActive && !InitStack.empty ()) {
4861+ if (!InitStack.empty ()) {
4862+ // If our init stack is, for example:
4863+ // 0 Stack: 3 (decl)
4864+ // 1 Stack: 6 (init list)
4865+ // 2 Stack: 1 (field)
4866+ // 3 Stack: 6 (init list)
4867+ // 4 Stack: 1 (field)
4868+ //
4869+ // We want to find the LAST element in it that's an init list,
4870+ // which is marked with the K_InitList marker. The index right
4871+ // before that points to an init list. We need to find the
4872+ // elements before the K_InitList element that point to a base
4873+ // (e.g. a decl or This), optionally followed by field, elem, etc.
4874+ // In the example above, we want to emit elements [0..2].
48554875 unsigned StartIndex = 0 ;
4876+ unsigned EndIndex = 0 ;
4877+ // Find the init list.
48564878 for (StartIndex = InitStack.size () - 1 ; StartIndex > 0 ; --StartIndex) {
4879+ if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
4880+ InitStack[StartIndex].Kind == InitLink::K_This) {
4881+ EndIndex = StartIndex;
4882+ --StartIndex;
4883+ break ;
4884+ }
4885+ }
4886+
4887+ // Walk backwards to find the base.
4888+ for (; StartIndex > 0 ; --StartIndex) {
4889+ if (InitStack[StartIndex].Kind == InitLink::K_InitList)
4890+ continue ;
4891+
48574892 if (InitStack[StartIndex].Kind != InitLink::K_Field &&
48584893 InitStack[StartIndex].Kind != InitLink::K_Elem)
48594894 break ;
48604895 }
48614896
4862- for (unsigned I = StartIndex, N = InitStack.size (); I != N; ++I) {
4897+ // Emit the instructions.
4898+ for (unsigned I = StartIndex; I != EndIndex; ++I) {
4899+ if (InitStack[I].Kind == InitLink::K_InitList)
4900+ continue ;
48634901 if (!InitStack[I].template emit <Emitter>(this , E))
48644902 return false ;
48654903 }
0 commit comments