tbaeder updated this revision to Diff 471534. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136920/new/
https://reviews.llvm.org/D136920 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/arrays.cpp
Index: clang/test/AST/Interp/arrays.cpp =================================================================== --- clang/test/AST/Interp/arrays.cpp +++ clang/test/AST/Interp/arrays.cpp @@ -181,6 +181,18 @@ } }; +class A { +public: + int a; + constexpr A() : a(10) {} +}; +class B { +public: + A a[2]; + constexpr B() {} +}; +constexpr B b; + namespace IncDec { // FIXME: Pointer arithmethic needs to be supported in inc/dec // unary operators Index: clang/lib/AST/Interp/ByteCodeExprGen.h =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -270,6 +270,9 @@ return FPO.getRoundingMode(); } + bool callFunction(const Function *Func, unsigned NumArgs, + const Expr *const *Args, const Expr *E); + protected: /// Variable to storage mapping. llvm::DenseMap<const ValueDecl *, Scope::Local> Locals; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1007,6 +1007,29 @@ assert(false && "default initializer for non-primitive type"); } + return true; + } else if (const auto *Ctor = dyn_cast<CXXConstructExpr>(Initializer)) { + const ArrayType *AT = Ctor->getType()->getAsArrayTypeUnsafe(); + const auto *CAT = cast<ConstantArrayType>(AT); + size_t NumElems = CAT->getSize().getZExtValue(); + const Function *Func = getFunction(Ctor->getConstructor()); + if (!Func || !Func->isConstexpr()) + return false; + + for (size_t I = 0; I != NumElems; ++I) { + if (!this->emitDupPtr(Initializer)) + return false; + if (!this->emitConstUint64(I, Initializer)) + return false; + if (!this->emitAddOffsetUint64(Initializer)) + return false; + if (!this->emitNarrowPtr(Initializer)) + return false; + + if (!this->callFunction(Func, Ctor->getNumArgs(), Ctor->getArgs(), + Initializer)) + return false; + } return true; } @@ -1030,13 +1053,8 @@ if (!this->emitDupPtr(Initializer)) return false; - // Constructor arguments. - for (const auto *Arg : CtorExpr->arguments()) { - if (!this->visit(Arg)) - return false; - } - - return this->emitCall(Func, Initializer); + return this->callFunction(Func, CtorExpr->getNumArgs(), CtorExpr->getArgs(), + Initializer); } else if (const auto *InitList = dyn_cast<InitListExpr>(Initializer)) { const Record *R = getRecord(InitList->getType()); @@ -1161,6 +1179,20 @@ return Func; } +template <class Emitter> +bool ByteCodeExprGen<Emitter>::callFunction(const Function *Func, + unsigned NumArgs, + const Expr *const *Args, + const Expr *E) { + // Constructor arguments. + for (unsigned I = 0; I != NumArgs; ++I) { + if (!this->visit(Args[I])) + return false; + } + + return this->emitCall(Func, E); +} + template <class Emitter> bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *Exp) { ExprScope<Emitter> RootScope(this); @@ -1249,16 +1281,10 @@ } } - // Put arguments on the stack. - for (const auto *Arg : E->arguments()) { - if (!this->visit(Arg)) - return false; - } - - // In any case call the function. The return value will end up on the stack and - // if the function has RVO, we already have the pointer on the stack to write - // the result into. - if (!this->emitCall(Func, E)) + // Emit arguments and call the function. The return value will end up on the + // stack and if the function has RVO, we already have the pointer on the + // stack to write the result into. + if (!this->callFunction(Func, E->getNumArgs(), E->getArgs(), E)) return false; if (DiscardResult && !ReturnType->isVoidType() && T)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits