diff options
author | Timm Bäder <tbaeder@redhat.com> | 2024-02-13 13:33:21 +0100 |
---|---|---|
committer | Timm Bäder <tbaeder@redhat.com> | 2024-02-13 13:41:06 +0100 |
commit | 9b718c0d5d0f1f146957753b7785f87f58cccfec (patch) | |
tree | f2896dd4324221954ed4915269b8629b1b3d2b8f | |
parent | 208edf7672cd2e84ae5da4df423adccd752ee1f1 (diff) | |
download | llvm-9b718c0d5d0f1f146957753b7785f87f58cccfec.zip llvm-9b718c0d5d0f1f146957753b7785f87f58cccfec.tar.gz llvm-9b718c0d5d0f1f146957753b7785f87f58cccfec.tar.bz2 |
[clang][Interp] Handle CXXUuidofExprs
Allocate storage and initialize it with the given APValue contents.
-rw-r--r-- | clang/lib/AST/Interp/ByteCodeExprGen.cpp | 60 | ||||
-rw-r--r-- | clang/lib/AST/Interp/ByteCodeExprGen.h | 1 | ||||
-rw-r--r-- | clang/lib/AST/Interp/Program.cpp | 2 | ||||
-rw-r--r-- | clang/test/AST/Interp/literals.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/PR40395.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaCXX/ms-uuid.cpp | 2 |
6 files changed, 74 insertions, 1 deletions
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index ba6c1d5..880e338 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2059,6 +2059,66 @@ bool ByteCodeExprGen<Emitter>::VisitExpressionTraitExpr( return this->emitConstBool(E->getValue(), E); } +template <class Emitter> +bool ByteCodeExprGen<Emitter>::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { + if (DiscardResult) + return true; + assert(!Initializing); + + std::optional<unsigned> GlobalIndex = P.getOrCreateGlobal(E->getGuidDecl()); + if (!GlobalIndex) + return false; + if (!this->emitGetPtrGlobal(*GlobalIndex, E)) + return false; + + const Record *R = this->getRecord(E->getType()); + assert(R); + + const APValue &V = E->getGuidDecl()->getAsAPValue(); + if (V.getKind() == APValue::None) + return true; + + assert(V.isStruct()); + assert(V.getStructNumBases() == 0); + // FIXME: This could be useful in visitAPValue, too. + for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I) { + const APValue &F = V.getStructField(I); + const Record::Field *RF = R->getField(I); + + if (F.isInt()) { + 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->emitDupPtr(E)) + return false; + if (!this->emitGetPtrField(RF->Offset, 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)) + return false; + } else { + assert(false && "I don't think this should be possible"); + } + } + + return this->emitInitPtr(E); +} + template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) { if (E->containsErrors()) return false; diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index ae216f5..c723170 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -113,6 +113,7 @@ public: bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E); bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E); bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E); + bool VisitCXXUuidofExpr(const CXXUuidofExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index b2b478a..964c037 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -169,7 +169,7 @@ std::optional<unsigned> Program::createGlobal(const ValueDecl *VD, if (const auto *Var = dyn_cast<VarDecl>(VD)) { IsStatic = Context::shouldBeGloballyIndexed(VD); IsExtern = !Var->getAnyInitializer(); - } else if (isa<UnnamedGlobalConstantDecl>(VD)) { + } else if (isa<UnnamedGlobalConstantDecl, MSGuidDecl>(VD)) { IsStatic = true; IsExtern = false; } else { diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 9202bb9..bc994c3 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -915,6 +915,13 @@ static_assert(ignoredDecls() == 12, ""); namespace DiscardExprs { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" + typedef struct _GUID { + __UINT32_TYPE__ Data1; + __UINT16_TYPE__ Data2; + __UINT16_TYPE__ Data3; + __UINT8_TYPE__ Data4[8]; + } GUID; + class __declspec(uuid("000000A0-0000-0000-C000-000000000049")) GuidType; struct A{ int a; }; constexpr int ignoredExprs() { @@ -951,6 +958,8 @@ namespace DiscardExprs { (float)1; (double)1.0f; (signed)4u; + __uuidof(GuidType); + __uuidof(number); // both-error {{cannot call operator __uuidof on a type with no GUID}} return 0; } diff --git a/clang/test/SemaCXX/PR40395.cpp b/clang/test/SemaCXX/PR40395.cpp index 469c86d..ea0fad2 100644 --- a/clang/test/SemaCXX/PR40395.cpp +++ b/clang/test/SemaCXX/PR40395.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++17 -fms-extensions -triple=x86_64-pc-win32 -verify %s +// RUN: %clang_cc1 -std=c++17 -fms-extensions -triple=x86_64-pc-win32 -verify %s -fexperimental-new-constant-interpreter // expected-no-diagnostics // PR40395 - ConstantExpr shouldn't cause the template object to infinitely diff --git a/clang/test/SemaCXX/ms-uuid.cpp b/clang/test/SemaCXX/ms-uuid.cpp index 21f93ec..172e036 100644 --- a/clang/test/SemaCXX/ms-uuid.cpp +++ b/clang/test/SemaCXX/ms-uuid.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -Wno-deprecated-declarations +// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -Wno-deprecated-declarations -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -fms-extensions %s -Wno-deprecated-declarations +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -fms-extensions %s -Wno-deprecated-declarations -fexperimental-new-constant-interpreter typedef struct _GUID { __UINT32_TYPE__ Data1; |