@@ -90,6 +90,8 @@ bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
90
90
if (!Ctx->emitConstUint32 (Offset, E))
91
91
return false ;
92
92
return Ctx->emitArrayElemPtrPopUint32 (E);
93
+ case K_InitList:
94
+ return true ;
93
95
default :
94
96
llvm_unreachable (" Unhandled InitLink kind" );
95
97
}
@@ -1717,6 +1719,8 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
1717
1719
template <class Emitter >
1718
1720
bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
1719
1721
const Expr *ArrayFiller, const Expr *E) {
1722
+ InitLinkScope<Emitter> ILS (this , InitLink::InitList ());
1723
+
1720
1724
QualType QT = E->getType ();
1721
1725
if (const auto *AT = QT->getAs <AtomicType>())
1722
1726
QT = AT->getValueType ();
@@ -1754,6 +1758,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
1754
1758
auto initPrimitiveField = [=](const Record::Field *FieldToInit,
1755
1759
const Expr *Init, PrimType T) -> bool {
1756
1760
InitStackScope<Emitter> ISS (this , isa<CXXDefaultInitExpr>(Init));
1761
+ InitLinkScope<Emitter> ILS (this , InitLink::Field (FieldToInit->Offset ));
1757
1762
if (!this ->visit (Init))
1758
1763
return false ;
1759
1764
@@ -1766,6 +1771,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
1766
1771
const Expr *Init) -> bool {
1767
1772
InitStackScope<Emitter> ISS (this , isa<CXXDefaultInitExpr>(Init));
1768
1773
InitLinkScope<Emitter> ILS (this , InitLink::Field (FieldToInit->Offset ));
1774
+
1769
1775
// Non-primitive case. Get a pointer to the field-to-initialize
1770
1776
// on the stack and recurse into visitInitializer().
1771
1777
if (!this ->emitGetPtrField (FieldToInit->Offset , Init))
@@ -3812,6 +3818,7 @@ template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
3812
3818
3813
3819
if (!this ->emitGetPtrLocal (*LocalIndex, E))
3814
3820
return false ;
3821
+ InitLinkScope<Emitter> ILS (this , InitLink::Temp (*LocalIndex));
3815
3822
return this ->visitInitializer (E);
3816
3823
}
3817
3824
@@ -4848,18 +4855,49 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
4848
4855
// instance pointer of the current function frame, but e.g. to the declaration
4849
4856
// currently being initialized. Here we emit the necessary instruction(s) for
4850
4857
// this scenario.
4851
- if (!InitStackActive || !E-> isImplicit () )
4858
+ if (!InitStackActive)
4852
4859
return this ->emitThis (E);
4853
4860
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].
4855
4875
unsigned StartIndex = 0 ;
4876
+ unsigned EndIndex = 0 ;
4877
+ // Find the init list.
4856
4878
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
+
4857
4892
if (InitStack[StartIndex].Kind != InitLink::K_Field &&
4858
4893
InitStack[StartIndex].Kind != InitLink::K_Elem)
4859
4894
break ;
4860
4895
}
4861
4896
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 ;
4863
4901
if (!InitStack[I].template emit <Emitter>(this , E))
4864
4902
return false ;
4865
4903
}
0 commit comments