Skip to content

Commit

Permalink
Merge branch 'p2996' of https://github.com/bloomberg/clang-p2996 into…
Browse files Browse the repository at this point in the history
… dealias
  • Loading branch information
changkhothuychung committed Oct 11, 2024
2 parents e1c7e5d + 342e733 commit ae807d7
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 61 deletions.
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ public:

let HasCustomParsing = 1;
let TemplateDependent = 1;
let Documentation = [Undocumented];
let Documentation = [InternalOnly];
}

def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
Expand Down
8 changes: 3 additions & 5 deletions clang/lib/AST/APValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,7 @@ static void profileReflection(llvm::FoldingSetNodeID &ID, APValue V) {
if (auto *TST = dyn_cast<TemplateSpecializationType>(QT)) {
// Note: This sugar only kept for alias template specializations.
ID.AddInteger(Type::TemplateSpecialization);
ID.AddPointer(TST->getTemplateName().getAsTemplateDecl());
if (auto *D = QT->getAsRecordDecl())
ID.AddPointer(D->getCanonicalDecl());
QT.getCanonicalType().Profile(ID);
} else {
ID.AddInteger(0);
if (auto *TDT = dyn_cast<TypedefType>(QT)) {
Expand All @@ -530,8 +528,8 @@ static void profileReflection(llvm::FoldingSetNodeID &ID, APValue V) {
}
case ReflectionKind::Declaration:
if (auto *PVD = dyn_cast<ParmVarDecl>(V.getReflectedDecl())) {
auto *FD = cast<FunctionDecl>(PVD->getDeclContext())->getFirstDecl();
PVD = FD->getParamDecl(PVD->getFunctionScopeIndex());
if (auto *FD = dyn_cast<FunctionDecl>(PVD->getDeclContext()))
PVD = FD->getFirstDecl()->getParamDecl(PVD->getFunctionScopeIndex());
ID.AddPointer(PVD);
} else {
ID.AddPointer(V.getReflectedDecl());
Expand Down
38 changes: 38 additions & 0 deletions clang/lib/AST/ExprConstantMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ static bool is_volatile(APValue &Result, ASTContext &C, MetaActions &Meta,
EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy,
SourceRange Range, ArrayRef<Expr *> Args);

static bool is_mutable_member(APValue &Result, ASTContext &C, MetaActions &Meta,
EvalFn Evaluator, DiagFn Diagnoser,
QualType ResultTy, SourceRange Range,
ArrayRef<Expr *> Args);

static bool is_lvalue_reference_qualified(APValue &Result, ASTContext &C,
MetaActions &Meta, EvalFn Evaluator,
DiagFn Diagnoser, QualType ResultTy,
Expand Down Expand Up @@ -611,6 +616,7 @@ static constexpr Metafunction Metafunctions[] = {
{ Metafunction::MFRK_bool, 1, 1, is_enumerator },
{ Metafunction::MFRK_bool, 1, 1, is_const },
{ Metafunction::MFRK_bool, 1, 1, is_volatile },
{ Metafunction::MFRK_bool, 1, 1, is_mutable_member },
{ Metafunction::MFRK_bool, 1, 1, is_lvalue_reference_qualified },
{ Metafunction::MFRK_bool, 1, 1, is_rvalue_reference_qualified },
{ Metafunction::MFRK_bool, 1, 1, has_static_storage_duration },
Expand Down Expand Up @@ -3494,6 +3500,38 @@ bool is_volatile(APValue &Result, ASTContext &C, MetaActions &Meta,
llvm_unreachable("invalid reflection type");
}

bool is_mutable_member(APValue &Result, ASTContext &C, MetaActions &Meta,
EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy,
SourceRange Range, ArrayRef<Expr *> Args) {
assert(Args[0]->getType()->isReflectionType());
assert(ResultTy == C.BoolTy);

APValue RV;
if (!Evaluator(RV, Args[0], true))
return true;

switch (RV.getReflectionKind()) {
case ReflectionKind::Null:
case ReflectionKind::Template:
case ReflectionKind::Namespace:
case ReflectionKind::BaseSpecifier:
case ReflectionKind::DataMemberSpec:
case ReflectionKind::Annotation:
case ReflectionKind::Type:
case ReflectionKind::Object:
case ReflectionKind::Value:
return SetAndSucceed(Result, makeBool(C, false));
case ReflectionKind::Declaration: {
bool result = false;
if (auto *FD = dyn_cast<FieldDecl>(RV.getReflectedDecl()))
result = FD->isMutable();

return SetAndSucceed(Result, makeBool(C, result));
}
}
llvm_unreachable("invalid reflection type");
}

bool is_lvalue_reference_qualified(APValue &Result, ASTContext &C,
MetaActions &Meta, EvalFn Evaluator,
DiagFn Diagnoser, QualType ResultTy,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Reflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
namespace clang {

bool TagDataMemberSpec::operator==(TagDataMemberSpec const &Rhs) const {
return (Ty == Ty &&
return (Ty == Rhs.Ty &&
Alignment == Rhs.Alignment &&
BitWidth == Rhs.BitWidth &&
Name == Rhs.Name);
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -9044,6 +9044,8 @@ TreeTransform<Derived>::TransformCXXDependentMemberSpliceExpr(
CXXDependentMemberSpliceExpr *E) {
ExprResult Base = getDerived().TransformExpr(E->getBase());
ExprResult RHS = getDerived().TransformExpr(E->getRHS());
if (Base.isInvalid() || RHS.isInvalid())
return ExprError();

return getSema().BuildMemberReferenceExpr(
nullptr, Base.get(), E->getOpLoc(),
Expand Down
164 changes: 116 additions & 48 deletions libcxx/include/experimental/meta
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,15 @@ consteval auto nonstatic_data_members_of(info class_type) -> vector<info>;
consteval auto subobjects_of(info class_type) -> vector<info>;
consteval auto enumerators_of(info enum_type) -> vector<info>;

// public member queries
consteval auto get_public_members(info) -> vector<info>;
consteval auto get_public_bases(info) -> vector<info>;
consteval auto get_static_data_members(info) -> vector<info>;
consteval auto get_nonstatic_data_members(info) -> vector<info>;

// member access queries
struct access_context {
consteval access_context() = default;
consteval access_context();
consteval access_context(const access_context &) = default;
consteval access_context(access_context &&) = default;

Expand Down Expand Up @@ -137,6 +143,7 @@ consteval auto is_bit_field(info) -> bool;
consteval auto is_enumerator(info) -> bool;
consteval auto is_const(info) -> bool;
consteval auto is_volatile(info) -> bool;
consteval auto is_mutable_member(info) -> bool;
consteval auto is_lvalue_reference_qualified(info) -> bool;
consteval auto is_rvalue_reference_qualified(info) -> bool;
consteval auto has_static_storage_duration(info) -> bool;
Expand Down Expand Up @@ -362,6 +369,13 @@ template <reflection_range R = initializer_list<info>>
consteval auto type_unwrap_reference(info) -> info;
consteval auto type_unwrap_ref_decay(info) -> info;

// tuple and variant queries
consteval auto type_tuple_size(info) -> size_t;
consteval auto type_tuple_element(size_t, info) -> info;

consteval auto type_variant_size(info) -> size_t;
consteval auto type_variant_alternative(size_t, info) -> info;

// function parameters (P3096)
consteval auto parameters_of(info) -> vector<info>;
consteval auto has_consistent_identifier(info) -> bool;
Expand Down Expand Up @@ -463,6 +477,7 @@ enum : unsigned {
__metafn_is_enumerator,
__metafn_is_const,
__metafn_is_volatile,
__metafn_is_mutable_member,
__metafn_is_lvalue_reference_qualified,
__metafn_is_rvalue_reference_qualified,
__metafn_has_static_storage_duration,
Expand Down Expand Up @@ -778,16 +793,16 @@ consteval auto u8display_string_of(info r) -> u8string_view;

// Enumeration of all overloadable operators.
enum class operators {
new_object = 1, delete_object, new_array, delete_array, coroutine_await,
parentheses, square_brackets, arrow, arrow_asterisk, tilde,
exclamation_mark, plus, minus, asterisk, solidus, percent,
caret, ampersand, pipe, equals, plus_equals, minus_equals,
asterisk_equals, solidus_equals, percent_equals, caret_equals,
ampersand_equals, pipe_equals, equals_equals, exclamation_equals,
less, greater, less_equals, greater_equals, three_way_compare,
ampersand_ampersand, pipe_pipe, less_less, greater_greater,
less_less_equals, greater_greater_equals, plus_plus, minus_minus,
comma,
op_new = 1, op_delete, op_array_new, op_array_delete, op_co_await,
op_parentheses, op_square_brackets, op_arrow, op_arrow_star, op_tilde,
op_exclaim, op_plus, op_minus, op_star, op_slash, op_percent, op_caret,
op_ampersand, op_pipe, op_equals, op_plus_equals, op_minus_equals,
op_star_equals, op_slash_equals, op_percent_equals, op_caret_equals,
op_ampersand_equals, op_pipe_equals, op_equals_equals, op_exclaim_equals,
op_less, op_greater, op_less_equals, op_greater_equals, op_three_way_compare,
op_ampersand_ampersand, op_pipe_pipe, op_less_less, op_greater_greater,
op_less_less_equals, op_greater_greater_equals, op_plus_plus, op_minus_minus,
op_comma,
};

// Returns the operator overloaded by the represented operator function or
Expand All @@ -801,6 +816,29 @@ consteval auto has_identifier(info r) -> bool {
return __metafunction(detail::__metafn_has_identifier, r);
}

// Returns the string representation of the operator.
consteval auto operator_symbol_of(operators op) -> string_view {
static constexpr string_view op_names[45] = {
{}, "new", "delete", "new[]", "delete[]", "coawait", "()", "[]", "->",
"->*", "~", "!", "+", "-", "*", "/", "%", "^", "&", "|", "=", "+=", "-=",
"*=", "/=", "%=", "^", "&=", "|=", "==", "!=", "<", ">", "<=", ">=",
"<=>", "&&", "||", "<<", ">>", "<<=", ">>=", "++", "--", ","
};
return op_names[int(op)];
}

consteval auto u8operator_symbol_of(operators op) -> u8string_view {
static constexpr u8string_view op_names[45] = {
{}, u8"new", u8"delete", u8"new[]", u8"delete[]", u8"coawait", u8"()",
u8"[]", u8"->", u8"->*", u8"~", u8"!", u8"+", u8"-", u8"*", u8"/", u8"%",
u8"^", u8"&", u8"|", u8"=", u8"+=", u8"-=", u8"*=", u8"/=", u8"%=",
u8"^", u8"&=", u8"|=", u8"==", u8"!=", u8"<", u8">", u8"<=", u8">=",
u8"<=>", u8"&&", u8"||", u8"<<", u8">>", u8"<<=", u8">>=", u8"++",
u8"--", u8","
};
return op_names[int(op)];
}

// Returns the source location of the reflected entity.
consteval auto source_location_of(info r) -> source_location {
auto ptr = __metafunction(detail::__metafn_source_location_of, r);
Expand Down Expand Up @@ -947,13 +985,36 @@ consteval auto enumerators_of(info r) -> vector<info> {
return vector<info>{rng.begin(), rng.end()};
}

// Returns whether the reflected entity is a public class member.
consteval auto is_public(info r) -> bool {
return __metafunction(detail::__metafn_is_public, r);
}

consteval auto get_public_members(info r) -> vector<info> {
return members_of(r) | views::filter(is_public) | ranges::to<vector>();
}

consteval auto get_public_bases(info r) -> vector<info> {
return bases_of(r) | views::filter(is_public) | ranges::to<vector>();
}

consteval auto get_public_static_data_members(info r) -> vector<info> {
return static_data_members_of(r) | views::filter(is_public) |
ranges::to<vector>();
}

consteval auto get_public_nonstatic_data_members(info r) -> vector<info> {
return nonstatic_data_members_of(r) | views::filter(is_public) |
ranges::to<vector>();
}

class access_context {
const info repr;

consteval access_context(info repr) : repr(repr) { }

public:
consteval access_context() noexcept : repr() { };
consteval access_context() noexcept : repr(LIFT(::)) { };
consteval access_context(const access_context &) noexcept = default;
consteval access_context(access_context &&) noexcept = default;

Expand Down Expand Up @@ -1061,11 +1122,6 @@ consteval auto extract(info r) -> Ty {
return __metafunction(detail::__metafn_extract, LIFT(Ty), r);
}

// Returns whether the reflected entity is a public class member.
consteval auto is_public(info r) -> bool {
return __metafunction(detail::__metafn_is_public, r);
}

// Returns whether the reflected entity is a protected class member.
consteval auto is_protected(info r) -> bool {
return __metafunction(detail::__metafn_is_protected, r);
Expand Down Expand Up @@ -1141,6 +1197,11 @@ consteval auto is_volatile(info r) -> bool {
return __metafunction(detail::__metafn_is_volatile, r);
}

// Returns whether the reflected entity is a mutable class member.
consteval auto is_mutable_member(info r) -> bool {
return __metafunction(detail::__metafn_is_mutable_member, r);
}

// Returns whether the reflected member function or function type is
// lvalue-reference qualified.
consteval auto is_lvalue_reference_qualified(info r) -> bool {
Expand Down Expand Up @@ -2071,6 +2132,25 @@ consteval auto type_unwrap_ref_decay(info type) -> info {
return dealias(substitute(LIFT(unwrap_ref_decay_t), {type}));
}

consteval auto type_tuple_size(info type) -> size_t {
return extract<size_t>(substitute(LIFT(tuple_size_v), {type}));
}

consteval auto type_tuple_element(size_t index, info type) -> info {
return dealias(substitute(LIFT(tuple_element_t),
{std::meta::reflect_value(index), type}));
}

consteval auto type_variant_size(info type) -> size_t {
return extract<size_t>(substitute(LIFT(variant_size_v), {type}));
}

consteval auto type_variant_alternative(size_t index, info type) -> info {
return dealias(substitute(LIFT(variant_alternative_t),
{std::meta::reflect_value(index), type}));
}


namespace detail {
template <class T> struct __wrap_workaround { using type = T; };
consteval auto __workaround_expand_compiler_builtins(info type) -> info {
Expand Down Expand Up @@ -2246,32 +2326,20 @@ struct pretty_printer {
}
}

static constexpr basic_string_view<CharT> op_names[45] = {
{}, string_constant("new"), string_constant("delete"),
string_constant("new[]"), string_constant("delete[]"),
string_constant("coawait"), string_constant("()"), string_constant("[]"),
string_constant("->"), string_constant("->*"), string_constant("~"),
string_constant("!"), string_constant("+"), string_constant("-"),
string_constant("*"), string_constant("/"), string_constant("%"),
string_constant("^"), string_constant("&"), string_constant("|"),
string_constant("="), string_constant("+="), string_constant("-="),
string_constant("*="), string_constant("/="), string_constant("%="),
string_constant("^"), string_constant("&="), string_constant("|="),
string_constant("=="), string_constant("!="), string_constant("<"),
string_constant(">"), string_constant("<="), string_constant(">="),
string_constant("<=>"), string_constant("&&"), string_constant("||"),
string_constant("<<"), string_constant(">>"), string_constant("<<="),
string_constant(">>="), string_constant("++"), string_constant("--"),
string_constant(","),
};

static consteval auto identifier_helper(info R) {
if constexpr (IsUtf8)
return u8identifier_of(R);
else
return identifier_of(R);
}

static consteval auto operator_symbol_helper(operators Op) {
if constexpr (IsUtf8)
return u8operator_symbol_of(Op);
else
return operator_symbol_of(Op);
}

template <info R>
static consteval info type_of_object_from_memptr() {
return []<typename T,
Expand Down Expand Up @@ -2551,15 +2619,15 @@ consteval auto pretty_printer<CharT>::tprint_impl::render() -> string_t {

string_t result = "operator";
switch (op) {
case std::meta::operators::new_object:
case std::meta::operators::delete_object:
case std::meta::operators::new_array:
case std::meta::operators::delete_array:
case std::meta::operators::coroutine_await:
case std::meta::operators::op_new:
case std::meta::operators::op_delete:
case std::meta::operators::op_array_new:
case std::meta::operators::op_array_delete:
case std::meta::operators::op_co_await:
result += " ";
[[fallthrough]];
default:
return result + string_t {op_names[int(operator_of(R))]};
return result + operator_symbol_helper(op);
}
} else if (is_conversion_function_template(R))
return string_constant("(conversion-function-template)");
Expand Down Expand Up @@ -2600,15 +2668,15 @@ consteval auto pretty_printer<CharT>::tprint_impl::render() -> string_t {

result = "operator";
switch (op) {
case std::meta::operators::new_object:
case std::meta::operators::delete_object:
case std::meta::operators::new_array:
case std::meta::operators::delete_array:
case std::meta::operators::coroutine_await:
case std::meta::operators::op_new:
case std::meta::operators::op_delete:
case std::meta::operators::op_array_new:
case std::meta::operators::op_array_delete:
case std::meta::operators::op_co_await:
result += " ";
[[fallthrough]];
default:
return result + string_t {op_names[int(operator_of(R))]};
return result + operator_symbol_helper(op);
}
} else if constexpr (is_conversion_function(R)) {
#if __has_feature(parameter_reflection)
Expand Down
Loading

0 comments on commit ae807d7

Please sign in to comment.