diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
| -rw-r--r-- | clang/lib/AST/ByteCode/Compiler.cpp | 91 |
1 files changed, 48 insertions, 43 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index f15b3c1..836d22f 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1842,7 +1842,6 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, const Expr *Init, PrimType T, bool Activate = false) -> bool { InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init)); - InitLinkScope<Emitter> ILS(this, InitLink::Field(FieldToInit->Offset)); if (!this->visit(Init)) return false; @@ -5385,55 +5384,57 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { // instance pointer of the current function frame, but e.g. to the declaration // currently being initialized. Here we emit the necessary instruction(s) for // this scenario. - if (!InitStackActive) + if (!InitStackActive || InitStack.empty()) return this->emitThis(E); - if (!InitStack.empty()) { - // If our init stack is, for example: - // 0 Stack: 3 (decl) - // 1 Stack: 6 (init list) - // 2 Stack: 1 (field) - // 3 Stack: 6 (init list) - // 4 Stack: 1 (field) - // - // We want to find the LAST element in it that's an init list, - // which is marked with the K_InitList marker. The index right - // before that points to an init list. We need to find the - // elements before the K_InitList element that point to a base - // (e.g. a decl or This), optionally followed by field, elem, etc. - // In the example above, we want to emit elements [0..2]. - unsigned StartIndex = 0; - unsigned EndIndex = 0; - // Find the init list. - for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) { - if (InitStack[StartIndex].Kind == InitLink::K_InitList || - InitStack[StartIndex].Kind == InitLink::K_This) { - EndIndex = StartIndex; - --StartIndex; - break; - } + // If our init stack is, for example: + // 0 Stack: 3 (decl) + // 1 Stack: 6 (init list) + // 2 Stack: 1 (field) + // 3 Stack: 6 (init list) + // 4 Stack: 1 (field) + // + // We want to find the LAST element in it that's an init list, + // which is marked with the K_InitList marker. The index right + // before that points to an init list. We need to find the + // elements before the K_InitList element that point to a base + // (e.g. a decl or This), optionally followed by field, elem, etc. + // In the example above, we want to emit elements [0..2]. + unsigned StartIndex = 0; + unsigned EndIndex = 0; + // Find the init list. + for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) { + if (InitStack[StartIndex].Kind == InitLink::K_InitList || + InitStack[StartIndex].Kind == InitLink::K_This) { + EndIndex = StartIndex; + --StartIndex; + break; } + } - // Walk backwards to find the base. - for (; StartIndex > 0; --StartIndex) { - if (InitStack[StartIndex].Kind == InitLink::K_InitList) - continue; + // Walk backwards to find the base. + for (; StartIndex > 0; --StartIndex) { + if (InitStack[StartIndex].Kind == InitLink::K_InitList) + continue; - if (InitStack[StartIndex].Kind != InitLink::K_Field && - InitStack[StartIndex].Kind != InitLink::K_Elem) - break; - } + if (InitStack[StartIndex].Kind != InitLink::K_Field && + InitStack[StartIndex].Kind != InitLink::K_Elem) + break; + } - // Emit the instructions. - for (unsigned I = StartIndex; I != EndIndex; ++I) { - if (InitStack[I].Kind == InitLink::K_InitList) - continue; - if (!InitStack[I].template emit<Emitter>(this, E)) - return false; - } - return true; + if (StartIndex == 0 && EndIndex == 0) + EndIndex = InitStack.size() - 1; + + assert(StartIndex < EndIndex); + + // Emit the instructions. + for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) { + if (InitStack[I].Kind == InitLink::K_InitList) + continue; + if (!InitStack[I].template emit<Emitter>(this, E)) + return false; } - return this->emitThis(E); + return true; } template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) { @@ -6295,6 +6296,10 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) { } assert(NestedField); + unsigned FirstLinkOffset = + R->getField(cast<FieldDecl>(IFD->chain()[0]))->Offset; + InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr)); + InitLinkScope<Emitter> ILS(this, InitLink::Field(FirstLinkOffset)); if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr, IsUnion)) return false; |
