From cfdc5e297bbac3703f6b8ed61b85222f393d970a Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Thu, 31 Oct 2024 15:23:06 -0400 Subject: [PATCH] `type_of` metafunction should dealias the type (#93) Fixes issue #91. --- clang/lib/AST/ExprConstantMeta.cpp | 29 ++++++++++++++----- .../reflection/related-reflections.pass.cpp | 6 ++-- .../reflection/to-and-from-values.pass.cpp | 6 ++-- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index 734194bbf06c70..a4af62a98d0db7 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -2069,14 +2069,19 @@ bool type_of(APValue &Result, ASTContext &C, MetaActions &Meta, switch (RV.getReflectionKind()) { case ReflectionKind::Null: - case ReflectionKind::Type: + case ReflectionKind::Type: { + QualType QT = desugarType(RV.getTypeOfReflectedResult(C), + /*UnwrapAliases=*/ true, /*DropCV=*/false, + /*DropRefs=*/false); + return SetAndSucceed(Result, makeReflection(QT)); + } case ReflectionKind::Template: case ReflectionKind::Namespace: return Diagnoser(Range.getBegin(), diag::metafn_no_associated_property) << DescriptionOf(RV) << 0 << Range; case ReflectionKind::Object: { QualType QT = desugarType(RV.getTypeOfReflectedResult(C), - /*UnwrapAliases=*/false, /*DropCV=*/false, + /*UnwrapAliases=*/ true, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } @@ -2094,20 +2099,21 @@ bool type_of(APValue &Result, ASTContext &C, MetaActions &Meta, bool UnwrapAliases = isa(VD) || isa(VD); bool DropCV = isa(VD); - QualType QT = desugarType(VD->getType(), UnwrapAliases, DropCV, + QualType QT = desugarType(VD->getType(), + /*UnwrapAliases=*/ true, DropCV, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } case ReflectionKind::BaseSpecifier: { QualType QT = RV.getReflectedBaseSpecifier()->getType(); - QT = desugarType(QT, /*UnwrapAliases=*/false, /*DropCV=*/false, + QT = desugarType(QT, /*UnwrapAliases=*/true, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } case ReflectionKind::DataMemberSpec: { QualType QT = RV.getReflectedDataMemberSpec()->Ty; - QT = desugarType(QT, /*UnwrapAliases=*/false, /*DropCV=*/false, + QT = desugarType(QT, /*UnwrapAliases=*/true, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } @@ -5618,12 +5624,19 @@ bool return_type_of(APValue &Result, ASTContext &C, MetaActions &Meta, return true; switch (RV.getReflectionKind()) { - case ReflectionKind::Type: - if (auto *FPT = dyn_cast(RV.getReflectedType())) - return SetAndSucceed(Result, makeReflection(FPT->getReturnType())); + case ReflectionKind::Type: { + if (auto *FPT = dyn_cast(RV.getReflectedType())) { + QualType QT = + desugarType(FPT->getReturnType(), /*UnwrapAliases=*/ true, /*DropCV=*/false, + /*DropRefs=*/false); + return SetAndSucceed(Result, makeReflection(QT)); + } return Diagnoser(Range.getBegin(), diag::metafn_cannot_introspect_type) << 3 << 2 << Range; + } + + case ReflectionKind::Declaration: if (auto *FD = dyn_cast(RV.getReflectedDecl()); FD && !isa(FD) && !isa(FD)) diff --git a/libcxx/test/std/experimental/reflection/related-reflections.pass.cpp b/libcxx/test/std/experimental/reflection/related-reflections.pass.cpp index 4f373b75f7122b..8b6d76408f5abd 100644 --- a/libcxx/test/std/experimental/reflection/related-reflections.pass.cpp +++ b/libcxx/test/std/experimental/reflection/related-reflections.pass.cpp @@ -32,8 +32,8 @@ extern int_alias ia; extern decltype(int_alias{}) dtia; static_assert(type_of(^^i) == ^^int); -static_assert(type_of(^^ia) == ^^int_alias); -static_assert(type_of(^^ia) != ^^int); +static_assert(type_of(^^ia) != ^^int_alias); +static_assert(type_of(^^ia) == ^^int); static_assert(type_of(^^dtia) == ^^int); static_assert(type_of(^^dtia) != ^^int_alias); static_assert(^^int_alias != ^^int); @@ -43,7 +43,7 @@ constexpr auto a = data_member_spec(^^int, {}); constexpr auto b = data_member_spec(^^int_alias, {}); static_assert(type_of(a) == ^^int); -static_assert(type_of(b) == ^^int_alias); +static_assert(type_of(b) != ^^int_alias); } // namespace expression_type // ================ diff --git a/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp b/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp index 048c5ac553622c..d3723045a26b19 100644 --- a/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp +++ b/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp @@ -215,12 +215,14 @@ struct S{}; using Alias1 = int; constexpr Alias1 a1 = 3; -static_assert(type_of(^^a1) == ^^const Alias1); +static_assert(type_of(^^a1) != ^^const Alias1); +static_assert(type_of(^^a1) == ^^const int); static_assert(type_of(value_of(^^a1)) == ^^int); using Alias2 = S; constexpr Alias2 a2 {}; -static_assert(type_of(^^a2) == ^^const Alias2); +static_assert(type_of(^^a2) != ^^const Alias2); +static_assert(type_of(^^a2) == ^^const S); static_assert(type_of(value_of(^^a2)) == ^^const S); constexpr const int &ref = a1;