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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits