summaryrefslogtreecommitdiff
path: root/clang/lib/AST/Interp/ByteCodeExprGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/ByteCodeExprGen.cpp')
-rw-r--r--clang/lib/AST/Interp/ByteCodeExprGen.cpp78
1 files changed, 61 insertions, 17 deletions
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 70328c1f52af..859a3fabea32 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1595,6 +1595,30 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
}
template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitSYCLUniqueStableNameExpr(
+ const SYCLUniqueStableNameExpr *E) {
+ if (DiscardResult)
+ return true;
+
+ assert(!Initializing);
+
+ auto &A = Ctx.getASTContext();
+ std::string ResultStr = E->ComputeName(A);
+
+ QualType CharTy = A.CharTy.withConst();
+ APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1);
+ QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr,
+ ArraySizeModifier::Normal, 0);
+
+ StringLiteral *SL =
+ StringLiteral::Create(A, ResultStr, StringLiteralKind::Ordinary,
+ /*Pascal=*/false, ArrayTy, E->getLocation());
+
+ unsigned StringIndex = P.createGlobalString(SL);
+ return this->emitGetPtrGlobal(StringIndex, E);
+}
+
+template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitCharacterLiteral(
const CharacterLiteral *E) {
if (DiscardResult)
@@ -2088,6 +2112,21 @@ bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr(
if (T->isRecordType()) {
const CXXConstructorDecl *Ctor = E->getConstructor();
+ // If we're discarding a construct expression, we still need
+ // to allocate a variable and call the constructor and destructor.
+ if (DiscardResult) {
+ if (Ctor->isTrivial())
+ return true;
+ assert(!Initializing);
+ std::optional<unsigned> LocalIndex = allocateLocal(E);
+
+ if (!LocalIndex)
+ return false;
+
+ if (!this->emitGetPtrLocal(*LocalIndex, E))
+ return false;
+ }
+
// Zero initialization.
if (E->requiresZeroInitialization()) {
const Record *R = getRecord(E->getType());
@@ -2108,19 +2147,6 @@ bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr(
assert(Func->hasThisPointer());
assert(!Func->hasRVO());
- // If we're discarding a construct expression, we still need
- // to allocate a variable and call the constructor and destructor.
- if (DiscardResult) {
- assert(!Initializing);
- std::optional<unsigned> LocalIndex = allocateLocal(E);
-
- if (!LocalIndex)
- return false;
-
- if (!this->emitGetPtrLocal(*LocalIndex, E))
- return false;
- }
-
// The This pointer is already on the stack because this is an initializer,
// but we need to dup() so the call() below has its own copy.
if (!this->emitDupPtr(E))
@@ -2538,8 +2564,6 @@ bool ByteCodeExprGen<Emitter>::VisitShuffleVectorExpr(
assert(E->getNumSubExprs() > 2);
const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)};
- assert(Vecs[0]->getType() == Vecs[1]->getType());
-
const VectorType *VT = Vecs[0]->getType()->castAs<VectorType>();
PrimType ElemT = classifyPrim(VT->getElementType());
unsigned NumInputElems = VT->getNumElements();
@@ -3371,6 +3395,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
switch (E->getOpcode()) {
case UO_PostInc: { // x++
+ if (!Ctx.getLangOpts().CPlusPlus14)
+ return this->emitInvalid(E);
+
if (!this->visit(SubExpr))
return false;
@@ -3389,6 +3416,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E);
}
case UO_PostDec: { // x--
+ if (!Ctx.getLangOpts().CPlusPlus14)
+ return this->emitInvalid(E);
+
if (!this->visit(SubExpr))
return false;
@@ -3407,6 +3437,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E);
}
case UO_PreInc: { // ++x
+ if (!Ctx.getLangOpts().CPlusPlus14)
+ return this->emitInvalid(E);
+
if (!this->visit(SubExpr))
return false;
@@ -3451,6 +3484,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return E->isGLValue() || this->emitLoadPop(*T, E);
}
case UO_PreDec: { // --x
+ if (!Ctx.getLangOpts().CPlusPlus14)
+ return this->emitInvalid(E);
+
if (!this->visit(SubExpr))
return false;
@@ -3724,8 +3760,16 @@ bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
}
}
- if (std::optional<unsigned> I = P.getOrCreateDummy(D))
- return this->emitGetPtrGlobal(*I, E);
+ if (std::optional<unsigned> I = P.getOrCreateDummy(D)) {
+ if (!this->emitGetPtrGlobal(*I, E))
+ return false;
+ // Convert the dummy pointer to another pointer type if we have to.
+ if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
+ if (!this->emitDecayPtr(PT_Ptr, PT, E))
+ return false;
+ }
+ return true;
+ }
return this->emitInvalidDeclRef(E, E);
}