Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 33 additions & 31 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3650,7 +3650,7 @@ bool Compiler<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {

assert(V.isStruct());
assert(V.getStructNumBases() == 0);
if (!this->visitAPValueInitializer(V, E))
if (!this->visitAPValueInitializer(V, E, E->getType()))
return false;

return this->emitFinishInit(E);
Expand Down Expand Up @@ -4637,48 +4637,27 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,

template <class Emitter>
bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
const Expr *E) {

const Expr *E, QualType T) {
if (Val.isStruct()) {
const Record *R = this->getRecord(E->getType());
const Record *R = this->getRecord(T);
assert(R);
for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) {
const APValue &F = Val.getStructField(I);
const Record::Field *RF = R->getField(I);
QualType FieldType = RF->Decl->getType();

if (F.isInt() || F.isFloat() || F.isLValue() || F.isMemberPointer()) {
PrimType T = classifyPrim(RF->Decl->getType());
if (!this->visitAPValue(F, T, E))
return false;
if (!this->emitInitField(T, RF->Offset, E))
return false;
} else if (F.isArray()) {
assert(RF->Desc->isPrimitiveArray());
const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe();
PrimType ElemT = classifyPrim(ArrType->getElementType());
assert(ArrType);

if (!this->emitGetPtrField(RF->Offset, E))
if (std::optional<PrimType> PT = classify(FieldType)) {
if (!this->visitAPValue(F, *PT, E))
return false;

for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) {
if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E))
return false;
if (!this->emitInitElem(ElemT, A, E))
return false;
}

if (!this->emitPopPtr(E))
if (!this->emitInitField(*PT, RF->Offset, E))
return false;
} else if (F.isStruct() || F.isUnion()) {
} else {
if (!this->emitGetPtrField(RF->Offset, E))
return false;
if (!this->visitAPValueInitializer(F, E))
if (!this->visitAPValueInitializer(F, E, FieldType))
return false;
if (!this->emitPopPtr(E))
return false;
} else {
assert(false && "I don't think this should be possible");
}
}
return true;
Expand All @@ -4692,6 +4671,28 @@ bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val,
if (!this->visitAPValue(F, T, E))
return false;
return this->emitInitField(T, RF->Offset, E);
} else if (Val.isArray()) {
const auto *ArrType = T->getAsArrayTypeUnsafe();
QualType ElemType = ArrType->getElementType();
for (unsigned A = 0, AN = Val.getArraySize(); A != AN; ++A) {
const APValue &Elem = Val.getArrayInitializedElt(A);
if (std::optional<PrimType> ElemT = classify(ElemType)) {
if (!this->visitAPValue(Elem, *ElemT, E))
return false;
if (!this->emitInitElem(*ElemT, A, E))
return false;
} else {
if (!this->emitConstUint32(A, E))
return false;
if (!this->emitArrayElemPtrUint32(E))
return false;
if (!this->visitAPValueInitializer(Elem, E, ElemType))
return false;
if (!this->emitPopPtr(E))
return false;
}
}
return true;
}
// TODO: Other types.

Expand Down Expand Up @@ -6374,7 +6375,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
return false;
return this->emitInitGlobal(*T, *Index, E);
}
return this->visitAPValueInitializer(TPOD->getValue(), E);
return this->visitAPValueInitializer(TPOD->getValue(), E,
TPOD->getType());
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ByteCode/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
VarCreationState visitDecl(const VarDecl *VD);
/// Visit an APValue.
bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E);
bool visitAPValueInitializer(const APValue &Val, const Expr *E);
bool visitAPValueInitializer(const APValue &Val, const Expr *E, QualType T);
/// Visit the given decl as if we have a reference to it.
bool visitDeclRef(const ValueDecl *D, const Expr *E);

Expand Down
25 changes: 25 additions & 0 deletions clang/test/AST/ByteCode/cxx20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -964,3 +964,28 @@ namespace PseudoDtor {
static_assert(f3() == 0);
#endif
}

namespace NastyChar {
struct nasty_char {
template <typename T> friend auto operator<=>(T, T) = delete;
template <typename T> friend void operator+(T &&) = delete;
template <typename T> friend void operator-(T &&) = delete;
template <typename T> friend void operator&(T &&) = delete;

char c;
};


template <unsigned N> struct ToNastyChar {
constexpr ToNastyChar(const char (&r)[N]) {
for (unsigned I = 0; I != N; ++I)
text[I] = nasty_char{r[I]};
}
nasty_char text[N];
};

template <unsigned N> ToNastyChar(const char (&)[N]) -> ToNastyChar<N>;

template <ToNastyChar t> constexpr auto to_nasty_char() { return t; }
constexpr auto result = to_nasty_char<"12345">();
}