Separate parameter/variable reflections.
This commit is contained in:
@@ -40,6 +40,7 @@ template <typename T> class BasicReaderBase;
|
||||
class Expr;
|
||||
class FieldDecl;
|
||||
class NamespaceDecl;
|
||||
class ParmVarDecl;
|
||||
struct PrintingPolicy;
|
||||
class Type;
|
||||
class UsingShadowDecl;
|
||||
@@ -564,6 +565,9 @@ public:
|
||||
bool isReflectedEntityProxy() const {
|
||||
return isReflection() && getReflectionKind() == ReflectionKind::EntityProxy;
|
||||
}
|
||||
bool isReflectedParameter() const {
|
||||
return isReflection() && getReflectionKind() == ReflectionKind::Parameter;
|
||||
}
|
||||
bool isReflectedBaseSpecifier() const {
|
||||
return isReflection() &&
|
||||
getReflectionKind() == ReflectionKind::BaseSpecifier;
|
||||
@@ -763,6 +767,7 @@ public:
|
||||
const TemplateName getReflectedTemplate() const;
|
||||
Decl *getReflectedNamespace() const;
|
||||
UsingShadowDecl *getReflectedEntityProxy() const;
|
||||
ParmVarDecl *getReflectedParameter() const;
|
||||
CXXBaseSpecifier *getReflectedBaseSpecifier() const;
|
||||
TagDataMemberSpec *getReflectedDataMemberSpec() const;
|
||||
CXX26AnnotationAttr *getReflectedAnnotation() const;
|
||||
|
||||
@@ -507,6 +507,10 @@ let Class = PropertyTypeCase<APValue, "Reflection"> in {
|
||||
let Conditional = [{ kind == ReflectionKind::EntityProxy }];
|
||||
let Read = [{ base.getReflectedEntityProxy() }];
|
||||
}
|
||||
def : Property<"baseParameter", DeclRef> {
|
||||
let Conditional = [{ kind == ReflectionKind::Parameter }];
|
||||
let Read = [{ base.getReflectedParameter() }];
|
||||
}
|
||||
def : Property<"baseBaseSpecDerivedFrom", CXXRecordDeclRef> {
|
||||
let Conditional = [{ kind == ReflectionKind::BaseSpecifier }];
|
||||
let Read = [{ base.getReflectedBaseSpecifier()->getDerived() }];
|
||||
@@ -574,6 +578,9 @@ let Class = PropertyTypeCase<APValue, "Reflection"> in {
|
||||
case ReflectionKind::EntityProxy:
|
||||
V = APValue(kind, *baseEntityProxy);
|
||||
break;
|
||||
case ReflectionKind::Parameter:
|
||||
V = APValue(kind, *baseParameter);
|
||||
break;
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
V = APValue(
|
||||
kind,
|
||||
|
||||
@@ -3054,6 +3054,10 @@ DEF_TRAVERSE_STMT(CXXReflectExpr, {
|
||||
TRY_TO(TraverseDecl(RV.getReflectedEntityProxy()));
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
TRY_TO(TraverseDecl(RV.getReflectedParameter()));
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Annotation: {
|
||||
TRY_TO(TraverseStmt(RV.getReflectedAnnotation()->getArg()));
|
||||
break;
|
||||
|
||||
@@ -87,6 +87,11 @@ enum class ReflectionKind {
|
||||
/// Corresponds to a UsingShadowDecl.
|
||||
EntityProxy,
|
||||
|
||||
/// \brief A reflection of a function parameter.
|
||||
///
|
||||
/// Corresponds to a ParmVarDecl.
|
||||
Parameter,
|
||||
|
||||
/// \brief A reflection of a base class specifier.
|
||||
///
|
||||
/// Corresponds to a CXXBaseSpecifier.
|
||||
|
||||
@@ -552,6 +552,13 @@ static void profileReflection(llvm::FoldingSetNodeID &ID, APValue V) {
|
||||
ID.AddPointer(TDecl);
|
||||
return;
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(V.getReflectedParameter());
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(PVD->getDeclContext()))
|
||||
PVD = FD->getFirstDecl()->getParamDecl(PVD->getFunctionScopeIndex());
|
||||
ID.AddPointer(PVD);
|
||||
return;
|
||||
}
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
@@ -936,6 +943,13 @@ UsingShadowDecl *APValue::getReflectedEntityProxy() const {
|
||||
const_cast<void *>(getOpaqueReflectionData()));
|
||||
}
|
||||
|
||||
ParmVarDecl *APValue::getReflectedParameter() const {
|
||||
assert(getReflectionKind() == ReflectionKind::Parameter &&
|
||||
"not a reflection of a parameter");
|
||||
return reinterpret_cast<ParmVarDecl *>(
|
||||
const_cast<void *>(getOpaqueReflectionData()));
|
||||
}
|
||||
|
||||
CXXBaseSpecifier *APValue::getReflectedBaseSpecifier() const {
|
||||
assert(getReflectionKind() == ReflectionKind::BaseSpecifier &&
|
||||
"not a reflection of a base specifier");
|
||||
@@ -1304,6 +1318,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
|
||||
case ReflectionKind::EntityProxy:
|
||||
Repr = "entity-proxy";
|
||||
break;
|
||||
case ReflectionKind::Parameter:
|
||||
Repr = "parameter";
|
||||
break;
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
Repr = "base-specifier";
|
||||
break;
|
||||
@@ -1647,6 +1664,7 @@ void APValue::setReflection(ReflectionKind RK, const void *Ptr) {
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
|
||||
@@ -982,6 +982,14 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E,
|
||||
D |= ExprDependence::UnexpandedPack;
|
||||
return D | computeDeclDependence(VD, Ctx);
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
ParmVarDecl *PD = RV.getReflectedParameter();
|
||||
if (PD->getType()->isDependentType())
|
||||
D |= ExprDependence::ValueInstantiation;
|
||||
if (PD->getType()->containsUnexpandedParameterPack())
|
||||
D |= ExprDependence::UnexpandedPack;
|
||||
return D | computeDeclDependence(PD, Ctx);
|
||||
}
|
||||
case ReflectionKind::Template: {
|
||||
const TemplateName Template = RV.getReflectedTemplate();
|
||||
|
||||
|
||||
@@ -625,13 +625,6 @@ static bool get_ith_parameter_of(APValue &Result, ASTContext &C,
|
||||
QualType ResultTy, SourceRange Range,
|
||||
ArrayRef<Expr *> Args, Decl *ContainingDecl);
|
||||
|
||||
static bool has_consistent_identifier(APValue &Result, ASTContext &C,
|
||||
MetaActions &Meta, EvalFn Evaluator,
|
||||
DiagFn Diagnoser, bool AllowInjection,
|
||||
QualType ResultTy, SourceRange Range,
|
||||
ArrayRef<Expr *> Args,
|
||||
Decl *ContainingDecl);
|
||||
|
||||
static bool has_ellipsis_parameter(APValue &Result, ASTContext &C,
|
||||
MetaActions &Meta, EvalFn Evaluator,
|
||||
DiagFn Diagnoser, bool AllowInjection,
|
||||
@@ -663,6 +656,11 @@ static bool return_type_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
SourceRange Range, ArrayRef<Expr *> Args,
|
||||
Decl *ContainingDecl);
|
||||
|
||||
static bool variable_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
EvalFn Evaluator, DiagFn Diagnoser, bool AllowInjection,
|
||||
QualType ResultTy, SourceRange Range,
|
||||
ArrayRef<Expr *> Args, Decl *ContainingDecl);
|
||||
|
||||
static bool get_ith_annotation_of(APValue &Result, ASTContext &C,
|
||||
MetaActions &Meta, EvalFn Evaluator,
|
||||
DiagFn Diagnoser, bool AllowInjection,
|
||||
@@ -827,12 +825,12 @@ static constexpr Metafunction Metafunctions[] = {
|
||||
|
||||
// P3096 metafunction extensions
|
||||
{ Metafunction::MFRK_metaInfo, 3, 3, get_ith_parameter_of },
|
||||
{ Metafunction::MFRK_bool, 1, 1, has_consistent_identifier },
|
||||
{ Metafunction::MFRK_bool, 1, 1, has_ellipsis_parameter },
|
||||
{ Metafunction::MFRK_bool, 1, 1, has_default_argument },
|
||||
{ Metafunction::MFRK_bool, 1, 1, is_explicit_object_parameter },
|
||||
{ Metafunction::MFRK_bool, 1, 1, is_function_parameter },
|
||||
{ Metafunction::MFRK_metaInfo, 1, 1, return_type_of },
|
||||
{ Metafunction::MFRK_metaInfo, 1, 1, variable_of },
|
||||
|
||||
// P3394 annotation metafunction extensions
|
||||
{ Metafunction::MFRK_metaInfo, 3, 3, get_ith_annotation_of },
|
||||
@@ -897,6 +895,8 @@ static APValue makeReflection(Decl *D) {
|
||||
return APValue(ReflectionKind::Template, D);
|
||||
else if (isa<UsingShadowDecl>(D))
|
||||
return APValue(ReflectionKind::EntityProxy, D);
|
||||
else if (isa<ParmVarDecl>(D))
|
||||
return APValue(ReflectionKind::Parameter, D);
|
||||
|
||||
return APValue(ReflectionKind::Declaration, D);
|
||||
}
|
||||
@@ -1654,6 +1654,9 @@ StringRef DescriptionOf(APValue RV, bool Granular = true) {
|
||||
case ReflectionKind::BaseSpecifier: {
|
||||
return "a base class specifier";
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
return "a parameter";
|
||||
}
|
||||
case ReflectionKind::DataMemberSpec: {
|
||||
return "a description of a non-static data member";
|
||||
}
|
||||
@@ -1718,6 +1721,7 @@ bool get_begin_enumerator_decl_of(APValue &Result, ASTContext &C,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation: {
|
||||
return DiagnoseReflectionKind(Diagnoser, Range, "an enum type",
|
||||
@@ -1759,6 +1763,7 @@ bool get_next_enumerator_decl_of(APValue &Result, ASTContext &C,
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation: {
|
||||
@@ -1821,6 +1826,7 @@ bool get_ith_base_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
@@ -1882,6 +1888,7 @@ bool get_ith_template_argument_of(APValue &Result, ASTContext &C,
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
@@ -1970,6 +1977,7 @@ bool get_begin_member_decl_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Null:
|
||||
case ReflectionKind::Declaration:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value:
|
||||
@@ -2088,15 +2096,6 @@ bool identifier_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Declaration: {
|
||||
if (auto *PVD = dyn_cast<ParmVarDecl>(RV.getReflectedDecl())) {
|
||||
bool ConsistentName = getParameterName(PVD, Name);
|
||||
if (EnforceConsistent && !ConsistentName) {
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_inconsistent_name)
|
||||
<< DescriptionOf(RV) << Range;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto *ND = dyn_cast<NamedDecl>(RV.getReflectedDecl())) {
|
||||
if (!findTemplateOfDecl(ND).isNull())
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_name_is_not_identifier)
|
||||
@@ -2124,6 +2123,14 @@ bool identifier_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
bool ConsistentName = getParameterName(RV.getReflectedParameter(), Name);
|
||||
if (EnforceConsistent && !ConsistentName) {
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_inconsistent_name)
|
||||
<< DescriptionOf(RV) << Range;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Template: {
|
||||
const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl();
|
||||
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(TD)) {
|
||||
@@ -2209,20 +2216,28 @@ bool has_identifier(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
auto *PVD = RV.getReflectedParameter();
|
||||
|
||||
std::string Name;
|
||||
bool Consistent = getParameterName(PVD, Name);
|
||||
|
||||
HasIdentifier = Consistent && !Name.empty();
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Declaration: {
|
||||
auto *D = RV.getReflectedDecl();
|
||||
|
||||
if (auto *PVD = dyn_cast<ParmVarDecl>(D)) {
|
||||
std::string Name;
|
||||
(void) getParameterName(PVD, Name);
|
||||
|
||||
HasIdentifier = !Name.empty();
|
||||
break;
|
||||
} else if (auto *FD = dyn_cast<FunctionDecl>(D);
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(D);
|
||||
FD && FD->getTemplateSpecializationArgs())
|
||||
break;
|
||||
else if (isa<VarTemplateSpecializationDecl>(D))
|
||||
break;
|
||||
else if (auto *PVD = dyn_cast<ParmVarDecl>(D)) {
|
||||
std::string Name;
|
||||
(void) getParameterName(PVD, Name);
|
||||
HasIdentifier = !Name.empty();
|
||||
}
|
||||
else if (auto *ND = dyn_cast<NamedDecl>(D))
|
||||
HasIdentifier = (ND->getIdentifier() != nullptr);
|
||||
|
||||
@@ -2342,6 +2357,9 @@ bool source_location_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::EntityProxy:
|
||||
return findDeclLoc(Result, C, Evaluator, ResultTy,
|
||||
RV.getReflectedEntityProxy());
|
||||
case ReflectionKind::Parameter:
|
||||
return findDeclLoc(Result, C, Evaluator, ResultTy,
|
||||
RV.getReflectedParameter());
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
return findBaseSpecLoc(Result, C, Evaluator, ResultTy,
|
||||
RV.getReflectedBaseSpecifier());
|
||||
@@ -2391,9 +2409,15 @@ bool type_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(VD))
|
||||
Meta.EnsureInstantiationOfExceptionSpec(Range.getBegin(), FD);
|
||||
|
||||
bool DropCV = isa<ParmVarDecl>(VD);
|
||||
QualType QT = desugarType(VD->getType(),
|
||||
/*UnwrapAliases=*/ true, DropCV,
|
||||
/*UnwrapAliases=*/ true, /*DropCV=*/false,
|
||||
/*DropRefs=*/false);
|
||||
return SetAndSucceed(Result, makeReflection(QT));
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
ParmVarDecl *PVD = RV.getReflectedParameter();
|
||||
QualType QT = desugarType(PVD->getType(),
|
||||
/*UnwrapAliases=*/ true, /*DropCV=*/true,
|
||||
/*DropRefs=*/false);
|
||||
return SetAndSucceed(Result, makeReflection(QT));
|
||||
}
|
||||
@@ -2466,6 +2490,9 @@ bool parent_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
return DiagWrapper(parentOf(Result,
|
||||
RV.getReflectedTemplate().getAsTemplateDecl()));
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
return DiagWrapper(parentOf(Result, RV.getReflectedParameter()));
|
||||
}
|
||||
case ReflectionKind::Namespace:
|
||||
if (isa<TranslationUnitDecl>(RV.getReflectedNamespace())) {
|
||||
if (Diagnoser)
|
||||
@@ -2506,6 +2533,7 @@ bool underlying_entity_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Declaration:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, RV);
|
||||
@@ -2547,6 +2575,7 @@ bool proxied_entity_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return DiagnoseReflectionKind(Diagnoser, Range, "an entity proxy");
|
||||
@@ -2600,6 +2629,7 @@ bool object_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Type:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
@@ -2720,6 +2750,7 @@ bool constant_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
@@ -2762,6 +2793,7 @@ bool template_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
@@ -2786,6 +2818,7 @@ static bool CanActAsTemplateArg(const APValue &RV) {
|
||||
}
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
case ReflectionKind::Null:
|
||||
@@ -3230,6 +3263,7 @@ bool extract(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract)
|
||||
@@ -3282,6 +3316,7 @@ bool is_ACCESS(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Annotation:
|
||||
case ReflectionKind::Namespace:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -3345,6 +3380,7 @@ bool is_virtual(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, IsVirtual));
|
||||
@@ -3531,26 +3567,22 @@ bool is_const(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
case ReflectionKind::Type: {
|
||||
bool result = isConstQualifiedType(RV.getReflectedType());
|
||||
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
}
|
||||
case ReflectionKind::Declaration: {
|
||||
bool result = false;
|
||||
if (!isa<ParmVarDecl>(RV.getReflectedDecl()))
|
||||
result = isConstQualifiedType(RV.getReflectedDecl()->getType());
|
||||
|
||||
bool result = isConstQualifiedType(RV.getReflectedDecl()->getType());
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
}
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value: {
|
||||
bool result = isConstQualifiedType(RV.getTypeOfReflectedResult(C));
|
||||
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
}
|
||||
}
|
||||
@@ -3573,6 +3605,7 @@ bool is_volatile(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
@@ -3583,10 +3616,7 @@ bool is_volatile(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
}
|
||||
case ReflectionKind::Declaration: {
|
||||
bool result = false;
|
||||
if (!isa<ParmVarDecl>(RV.getReflectedDecl()))
|
||||
result = isVolatileQualifiedType(RV.getReflectedDecl()->getType());
|
||||
|
||||
bool result = isVolatileQualifiedType(RV.getReflectedDecl()->getType());
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
}
|
||||
case ReflectionKind::Object:
|
||||
@@ -3955,6 +3985,7 @@ bool is_static_member(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
@@ -4086,6 +4117,7 @@ bool is_alias(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Declaration:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Annotation:
|
||||
case ReflectionKind::EntityProxy:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -4163,6 +4195,7 @@ bool has_complete_definition(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
break;
|
||||
@@ -4202,6 +4235,7 @@ bool is_enumerable_type(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
break;
|
||||
@@ -4497,6 +4531,7 @@ bool has_template_arguments(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -4604,6 +4639,7 @@ bool is_constructor(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -4753,6 +4789,7 @@ bool is_destructor(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -4785,6 +4822,7 @@ bool is_special_member_function(APValue &Result, ASTContext &C,
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -5137,6 +5175,7 @@ bool offset_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member",
|
||||
@@ -5210,6 +5249,7 @@ bool size_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
<< 3 << DescriptionOf(RV);
|
||||
@@ -5235,6 +5275,7 @@ bool bit_offset_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member",
|
||||
@@ -5306,6 +5347,7 @@ bool bit_size_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
<< 3 << DescriptionOf(RV);
|
||||
@@ -5370,6 +5412,7 @@ bool alignment_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
<< 4 << DescriptionOf(RV) << Range;
|
||||
@@ -5429,6 +5472,7 @@ bool get_ith_parameter_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return true;
|
||||
@@ -5437,43 +5481,6 @@ bool get_ith_parameter_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
<< 5 << DescriptionOf(RV) << Range;
|
||||
}
|
||||
|
||||
bool has_consistent_identifier(APValue &Result, ASTContext &C,
|
||||
MetaActions &Meta, EvalFn Evaluator,
|
||||
DiagFn Diagnoser, bool AllowInjection,
|
||||
QualType ResultTy, SourceRange Range,
|
||||
ArrayRef<Expr *> Args, Decl *ContainingDecl) {
|
||||
assert(Args[0]->getType()->isReflectionType());
|
||||
assert(ResultTy == C.BoolTy);
|
||||
|
||||
APValue RV;
|
||||
if (!Evaluator(RV, Args[0], true))
|
||||
return true;
|
||||
|
||||
switch (RV.getReflectionKind()) {
|
||||
case ReflectionKind::Declaration:
|
||||
if (auto *PVD = dyn_cast<ParmVarDecl>(RV.getReflectedDecl())) {
|
||||
[[maybe_unused]] std::string Unused;
|
||||
bool Consistent = getParameterName(PVD, Unused);
|
||||
|
||||
return SetAndSucceed(Result, makeBool(C, Consistent));
|
||||
}
|
||||
[[fallthrough]];
|
||||
case ReflectionKind::Null:
|
||||
case ReflectionKind::Type:
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
case ReflectionKind::EntityProxy:
|
||||
return has_identifier(Result, C, Meta, Evaluator, Diagnoser, AllowInjection,
|
||||
ResultTy, Range, Args, ContainingDecl);
|
||||
}
|
||||
llvm_unreachable("unknown reflection kind");
|
||||
}
|
||||
|
||||
bool has_ellipsis_parameter(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
EvalFn Evaluator, DiagFn Diagnoser,
|
||||
bool AllowInjection, QualType ResultTy,
|
||||
@@ -5494,6 +5501,7 @@ bool has_ellipsis_parameter(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
@@ -5530,12 +5538,11 @@ bool has_default_argument(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
return true;
|
||||
|
||||
switch (RV.getReflectionKind()) {
|
||||
case ReflectionKind::Declaration: {
|
||||
if (auto *PVD = dyn_cast<ParmVarDecl>(RV.getReflectedDecl())) {
|
||||
PVD = getMostRecentParmVarDecl(PVD);
|
||||
return SetAndSucceed(Result, makeBool(C, PVD->hasDefaultArg()));
|
||||
}
|
||||
[[fallthrough]];
|
||||
case ReflectionKind::Parameter: {
|
||||
ParmVarDecl *PVD = getMostRecentParmVarDecl(RV.getReflectedParameter());
|
||||
return SetAndSucceed(Result, makeBool(C, PVD->hasDefaultArg()));
|
||||
}
|
||||
case ReflectionKind::Declaration:
|
||||
case ReflectionKind::Null:
|
||||
case ReflectionKind::Type:
|
||||
case ReflectionKind::Object:
|
||||
@@ -5549,7 +5556,6 @@ bool has_default_argument(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
return DiagnoseReflectionKind(Diagnoser, Range, "a function parameter",
|
||||
DescriptionOf(RV));
|
||||
}
|
||||
}
|
||||
llvm_unreachable("unknown reflection kind");
|
||||
}
|
||||
|
||||
@@ -5566,10 +5572,8 @@ bool is_explicit_object_parameter(APValue &Result, ASTContext &C,
|
||||
return true;
|
||||
|
||||
bool result = false;
|
||||
if (RV.isReflectedDecl()) {
|
||||
if (auto *PVD = dyn_cast<ParmVarDecl>(RV.getReflectedDecl()))
|
||||
result = PVD->isExplicitObjectParameter();
|
||||
}
|
||||
if (RV.isReflectedParameter())
|
||||
result = RV.getReflectedParameter()->isExplicitObjectParameter();
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
}
|
||||
|
||||
@@ -5585,11 +5589,7 @@ bool is_function_parameter(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
if (!Evaluator(RV, Args[0], true))
|
||||
return true;
|
||||
|
||||
bool result = false;
|
||||
if (RV.isReflectedDecl()) {
|
||||
result = isa<const ParmVarDecl>(RV.getReflectedDecl());
|
||||
}
|
||||
return SetAndSucceed(Result, makeBool(C, result));
|
||||
return SetAndSucceed(Result, makeBool(C, RV.isReflectedParameter()));
|
||||
}
|
||||
|
||||
bool return_type_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
@@ -5631,6 +5631,7 @@ bool return_type_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
@@ -5639,6 +5640,33 @@ bool return_type_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
llvm_unreachable("unknown reflection kind");
|
||||
}
|
||||
|
||||
bool variable_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
EvalFn Evaluator, DiagFn Diagnoser, bool AllowInjection,
|
||||
QualType ResultTy, SourceRange Range, ArrayRef<Expr *> Args,
|
||||
Decl *ContainingDecl) {
|
||||
assert(Args[0]->getType()->isReflectionType());
|
||||
assert(ResultTy == C.MetaInfoTy);
|
||||
|
||||
APValue RV;
|
||||
if (!Evaluator(RV, Args[0], true))
|
||||
return true;
|
||||
|
||||
if (!RV.isReflectedParameter())
|
||||
return DiagnoseReflectionKind(Diagnoser, Range, "a function parameter",
|
||||
DescriptionOf(RV));
|
||||
|
||||
ParmVarDecl *PVD = RV.getReflectedParameter();
|
||||
FunctionDecl *FD = cast<FunctionDecl>(PVD->getDeclContext());
|
||||
|
||||
if (Meta.CurrentCtx()->getCanonicalDecl() != FD->getCanonicalDecl())
|
||||
return true;
|
||||
assert(FD->getDefinition());
|
||||
PVD = FD->getDefinition()->getParamDecl(PVD->getFunctionScopeIndex());
|
||||
|
||||
APValue Var(ReflectionKind::Declaration, PVD);
|
||||
return SetAndSucceed(Result, Var);
|
||||
}
|
||||
|
||||
bool get_ith_annotation_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
EvalFn Evaluator, DiagFn Diagnoser,
|
||||
bool AllowInjection, QualType ResultTy,
|
||||
@@ -5709,6 +5737,7 @@ bool get_ith_annotation_of(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property)
|
||||
@@ -5781,6 +5810,7 @@ bool annotate(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
case ReflectionKind::EntityProxy:
|
||||
@@ -5956,6 +5986,7 @@ bool is_accessible(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, true));
|
||||
@@ -6019,6 +6050,7 @@ bool is_access_specified(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Object:
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return SetAndSucceed(Result, makeBool(C, false));
|
||||
@@ -6195,6 +6227,7 @@ bool reflect_invoke(APValue &Result, ASTContext &C, MetaActions &Meta,
|
||||
case ReflectionKind::Type:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
return Diagnoser(Range.getBegin(), diag::metafn_cannot_invoke)
|
||||
|
||||
@@ -4993,7 +4993,7 @@ void CXXNameMangler::mangleReflection(const APValue &R) {
|
||||
Out << 'd';
|
||||
|
||||
Decl *D = R.getReflectedDecl();
|
||||
if (auto * ED = dyn_cast<EnumConstantDecl>(D)) {
|
||||
if (auto *ED = dyn_cast<EnumConstantDecl>(D)) {
|
||||
mangleIntegerLiteral(ED->getType(), ED->getInitVal());
|
||||
} else if (auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
|
||||
GlobalDecl GD(CD, Ctor_Complete);
|
||||
@@ -5001,20 +5001,23 @@ void CXXNameMangler::mangleReflection(const APValue &R) {
|
||||
} else if (auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
|
||||
GlobalDecl GD(DD, Dtor_Complete);
|
||||
mangle(GD);
|
||||
} else if (auto *PVD = dyn_cast<ParmVarDecl>(D)) {
|
||||
if (const FunctionDecl *Func
|
||||
= dyn_cast<FunctionDecl>(PVD->getDeclContext())) {
|
||||
Out << 'p';
|
||||
unsigned Num = Func->getNumParams() - PVD->getFunctionScopeIndex();
|
||||
if (Num > 1)
|
||||
mangleNumber(Num - 2);
|
||||
Out << '_';
|
||||
}
|
||||
} else {
|
||||
mangle(cast<NamedDecl>(D));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
auto *PVD = R.getReflectedParameter();
|
||||
if (const FunctionDecl *Func
|
||||
= dyn_cast<FunctionDecl>(PVD->getDeclContext())) {
|
||||
Out << 'p';
|
||||
unsigned Num = Func->getNumParams() - PVD->getFunctionScopeIndex();
|
||||
if (Num > 1)
|
||||
mangleNumber(Num - 2);
|
||||
Out << '_';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ReflectionKind::Template: {
|
||||
Out << 't';
|
||||
|
||||
|
||||
@@ -2207,6 +2207,7 @@ void MicrosoftCXXNameMangler::mangleReflection(const APValue &R) {
|
||||
case ReflectionKind::Template:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::EntityProxy:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
|
||||
@@ -1699,6 +1699,7 @@ ExprResult Sema::BuildReflectionSpliceExpr(SourceLocation TemplateKWLoc,
|
||||
case ReflectionKind::Type:
|
||||
case ReflectionKind::Namespace:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
Diag(Splice->getBeginLoc(),
|
||||
@@ -1834,6 +1835,7 @@ DeclContext *Sema::TryFindDeclContextOf(SpliceSpecifier *Splice) {
|
||||
case ReflectionKind::Value:
|
||||
case ReflectionKind::Declaration:
|
||||
case ReflectionKind::BaseSpecifier:
|
||||
case ReflectionKind::Parameter:
|
||||
case ReflectionKind::DataMemberSpec:
|
||||
case ReflectionKind::Annotation:
|
||||
Diag(Splice->getBeginLoc(), diag::err_expected_class_or_namespace)
|
||||
|
||||
@@ -9071,6 +9071,14 @@ TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
|
||||
E->getOperandRange().getBegin(),
|
||||
cast<UsingShadowDecl>(Transformed)));
|
||||
}
|
||||
case ReflectionKind::Parameter: {
|
||||
Decl *Transformed = getDerived().TransformDecl(E->getExprLoc(),
|
||||
RV.getReflectedParameter());
|
||||
return RecordConstevalOnly.RecordAndReturn(
|
||||
getSema().BuildCXXReflectExpr(E->getOperatorLoc(),
|
||||
E->getOperandRange().getBegin(),
|
||||
Transformed));
|
||||
}
|
||||
case ReflectionKind::Namespace: {
|
||||
Decl *Transformed =
|
||||
getDerived().TransformDecl(E->getExprLoc(),
|
||||
|
||||
@@ -340,14 +340,12 @@ consteval auto is_entity_proxy(info) -> bool;
|
||||
|
||||
// function parameters (P3096)
|
||||
consteval auto parameters_of(info) -> vector<info>;
|
||||
consteval auto has_consistent_identifier(info) -> bool;
|
||||
consteval auto any_identifier_of(info) -> string_view;
|
||||
consteval auto u8any_identifier_of(info) -> u8string_view;
|
||||
consteval auto has_ellipsis_parameter(info) -> bool;
|
||||
consteval auto has_default_argument(info) -> bool;
|
||||
consteval auto is_explicit_object_parameter(info) -> bool;
|
||||
consteval auto is_function_parameter(info) -> bool;
|
||||
consteval auto return_type_of(info) -> info;
|
||||
consteval auto variable_of(info) -> info;
|
||||
|
||||
// annotations (P3394)
|
||||
consteval auto annotations_of(info) -> vector<info>;
|
||||
@@ -528,12 +526,12 @@ enum : unsigned {
|
||||
|
||||
// P3096 parameter reflection metafunctions
|
||||
__metafn_get_ith_parameter_of,
|
||||
__metafn_has_consistent_identifier,
|
||||
__metafn_has_ellipsis_parameter,
|
||||
__metafn_has_default_argument,
|
||||
__metafn_is_explicit_object_parameter,
|
||||
__metafn_is_function_parameter,
|
||||
__metafn_return_type_of,
|
||||
__metafn_variable_of,
|
||||
|
||||
// P3394 annotation metafunctions
|
||||
__metafn_get_ith_annotation_of,
|
||||
@@ -2082,20 +2080,6 @@ consteval auto parameters_of(info r) -> vector<info> {
|
||||
return vector<info>{rng.begin(), rng.end()};
|
||||
}
|
||||
|
||||
consteval auto has_consistent_identifier(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_has_consistent_identifier, r);
|
||||
}
|
||||
|
||||
consteval auto any_identifier_of(info r) -> string_view {
|
||||
return __metafunction(detail::__metafn_identifier_of, ^^const char *, r,
|
||||
/*UTF8=*/false, /*EnforceConsistent=*/false);
|
||||
}
|
||||
|
||||
consteval auto u8any_identifier_of(info r) -> u8string_view {
|
||||
return __metafunction(detail::__metafn_identifier_of, ^^const char8_t *,
|
||||
r, /*UTF8=*/true, /*EnforceConsistent=*/false);
|
||||
}
|
||||
|
||||
consteval auto has_ellipsis_parameter(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_has_ellipsis_parameter, r);
|
||||
}
|
||||
@@ -2116,6 +2100,10 @@ consteval auto return_type_of(info r) -> info {
|
||||
return __metafunction(detail::__metafn_return_type_of, r);
|
||||
}
|
||||
|
||||
consteval auto variable_of(info r) -> info {
|
||||
return __metafunction(detail::__metafn_variable_of, r);
|
||||
}
|
||||
|
||||
#endif // __has_feature(parameter_reflection)
|
||||
|
||||
#if __has_feature(annotation_attributes)
|
||||
|
||||
@@ -53,17 +53,17 @@ static_assert(parameters_of(type_of(^^fn)) ==
|
||||
std::vector {^^int, ^^bool, ^^const S<int> &});
|
||||
static_assert(type_of(parameters_of(^^fn)[0]) == ^^int);
|
||||
static_assert(identifier_of(parameters_of(^^fn)[0]) == "a");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[0]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(^^fn)[0]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[0]));
|
||||
static_assert(type_of(parameters_of(^^fn)[1]) == ^^bool);
|
||||
static_assert(identifier_of(parameters_of(^^fn)[1]) == "b");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[1]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[1]));
|
||||
static_assert(!has_default_argument(parameters_of(^^fn)[1]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[1]));
|
||||
static_assert(type_of(parameters_of(^^fn)[2]) == ^^const S<int> &);
|
||||
static_assert(identifier_of(parameters_of(^^fn)[2]) == "s");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[2]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[2]));
|
||||
static_assert(!has_default_argument(parameters_of(^^fn)[2]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[2]));
|
||||
static_assert(!has_ellipsis_parameter(^^fn));
|
||||
@@ -91,7 +91,7 @@ constexpr auto ctor =
|
||||
static_assert(parameters_of(ctor).size() == 1);
|
||||
static_assert(type_of(parameters_of(ctor)[0]) == ^^int);
|
||||
static_assert(identifier_of(parameters_of(ctor)[0]) == "a");
|
||||
static_assert(has_consistent_identifier(parameters_of(ctor)[0]));
|
||||
static_assert(has_identifier(parameters_of(ctor)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(ctor)[0]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(ctor)[0]));
|
||||
static_assert(!has_ellipsis_parameter(ctor));
|
||||
@@ -106,12 +106,12 @@ static_assert(parameters_of(^^Cls::fn).size() == 2);
|
||||
static_assert(parameters_of(type_of(^^Cls::fn)) == std::vector {^^int, ^^bool});
|
||||
static_assert(type_of(parameters_of(^^Cls::fn)[0]) == ^^int);
|
||||
static_assert(identifier_of(parameters_of(^^Cls::fn)[0]) == "a");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn)[0]));
|
||||
static_assert(has_identifier(parameters_of(^^Cls::fn)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(^^Cls::fn)[0]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^Cls::fn)[0]));
|
||||
static_assert(type_of(parameters_of(^^Cls::fn)[1]) == ^^bool);
|
||||
static_assert(identifier_of(parameters_of(^^Cls::fn)[1]) == "b");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn)[1]));
|
||||
static_assert(has_identifier(parameters_of(^^Cls::fn)[1]));
|
||||
static_assert(has_default_argument(parameters_of(^^Cls::fn)[1]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^Cls::fn)[1]));
|
||||
static_assert(!has_ellipsis_parameter(^^Cls::fn));
|
||||
@@ -123,12 +123,11 @@ static_assert(parameters_of(type_of(^^Cls::fn2)) ==
|
||||
std::vector {^^Cls &, ^^int});
|
||||
static_assert(type_of(parameters_of(^^Cls::fn2)[0]) == ^^Cls &);
|
||||
static_assert(identifier_of(parameters_of(^^Cls::fn2)[0]) == "self");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn2)[0]));
|
||||
static_assert(has_identifier(parameters_of(^^Cls::fn2)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(^^Cls::fn2)[0]));
|
||||
static_assert(is_explicit_object_parameter(parameters_of(^^Cls::fn2)[0]));
|
||||
static_assert(type_of(parameters_of(^^Cls::fn2)[1]) == ^^int);
|
||||
static_assert(!has_identifier(parameters_of(^^Cls::fn2)[1]));
|
||||
static_assert(has_consistent_identifier(parameters_of(^^Cls::fn2)[1]));
|
||||
static_assert(!has_default_argument(parameters_of(^^Cls::fn2)[1]));
|
||||
static_assert(has_ellipsis_parameter(^^Cls::fn2));
|
||||
static_assert(has_ellipsis_parameter(type_of(^^Cls::fn2)));
|
||||
@@ -139,7 +138,7 @@ static_assert(parameters_of(^^Cls::sfn).size() == 1);
|
||||
static_assert(parameters_of(type_of(^^Cls::sfn)) == std::vector {^^int});
|
||||
static_assert(type_of(parameters_of(^^Cls::sfn)[0]) == ^^int);
|
||||
static_assert(identifier_of(parameters_of(^^Cls::sfn)[0]) == "a");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^Cls::sfn)[0]));
|
||||
static_assert(has_identifier(parameters_of(^^Cls::sfn)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(^^Cls::sfn)[0]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^Cls::sfn)[0]));
|
||||
static_assert(has_ellipsis_parameter(^^Cls::sfn));
|
||||
@@ -163,17 +162,17 @@ consteval bool check() {
|
||||
std::vector {^^int &&, ^^char &&, ^^bool &&});
|
||||
static_assert(type_of(parameters_of(Fn)[0]) == ^^int &&);
|
||||
static_assert(identifier_of(parameters_of(Fn)[0]) == "ts");
|
||||
static_assert(has_consistent_identifier(parameters_of(Fn)[0]));
|
||||
static_assert(has_identifier(parameters_of(Fn)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(Fn)[0]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(Fn)[0]));
|
||||
static_assert(type_of(parameters_of(Fn)[1]) == ^^char &&);
|
||||
static_assert(identifier_of(parameters_of(Fn)[1]) == "ts");
|
||||
static_assert(has_consistent_identifier(parameters_of(Fn)[1]));
|
||||
static_assert(has_identifier(parameters_of(Fn)[1]));
|
||||
static_assert(!has_default_argument(parameters_of(Fn)[1]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(Fn)[1]));
|
||||
static_assert(type_of(parameters_of(Fn)[2]) == ^^bool &&);
|
||||
static_assert(identifier_of(parameters_of(Fn)[2]) == "ts");
|
||||
static_assert(has_consistent_identifier(parameters_of(Fn)[2]));
|
||||
static_assert(has_identifier(parameters_of(Fn)[2]));
|
||||
static_assert(!has_default_argument(parameters_of(Fn)[2]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(Fn)[2]));
|
||||
static_assert(!has_ellipsis_parameter(Fn));
|
||||
@@ -199,12 +198,12 @@ static_assert(parameters_of(^^fn).size() == 2);
|
||||
static_assert(parameters_of(type_of(^^fn)) == std::vector {^^int, ^^bool});
|
||||
static_assert(type_of(parameters_of(^^fn)[0]) == ^^int);
|
||||
static_assert(identifier_of(parameters_of(^^fn)[0]) == "a");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[0]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[0]));
|
||||
static_assert(!has_default_argument(parameters_of(^^fn)[0]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[0]));
|
||||
static_assert(type_of(parameters_of(^^fn)[1]) == ^^bool);
|
||||
static_assert(identifier_of(parameters_of(^^fn)[1]) == "b");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[1]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[1]));
|
||||
static_assert(has_default_argument(parameters_of(^^fn)[1]));
|
||||
static_assert(!is_explicit_object_parameter(parameters_of(^^fn)[1]));
|
||||
static_assert(!has_ellipsis_parameter(^^fn));
|
||||
@@ -217,7 +216,7 @@ static_assert(!has_ellipsis_parameter(type_of(^^fn)));
|
||||
|
||||
namespace with_ambiguous_names {
|
||||
void fn(int a1, bool b, char c1);
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[2]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[2]));
|
||||
|
||||
void fn(int a2, bool, char c2);
|
||||
constexpr auto r_a2 = parameters_of(^^fn)[0];
|
||||
@@ -230,16 +229,10 @@ constexpr auto r_a3 = parameters_of(^^fn)[0];
|
||||
static_assert(parameters_of(^^fn).size() == 3);
|
||||
static_assert(parameters_of(type_of(^^fn)) ==
|
||||
std::vector {^^int, ^^bool, ^^char});
|
||||
static_assert(any_identifier_of(parameters_of(^^fn)[0]) == "a1" ||
|
||||
any_identifier_of(parameters_of(^^fn)[0]) == "a2" ||
|
||||
any_identifier_of(parameters_of(^^fn)[0]) == "a3");
|
||||
static_assert(!has_consistent_identifier(parameters_of(^^fn)[0]));
|
||||
static_assert(any_identifier_of(parameters_of(^^fn)[1]) == "b");
|
||||
static_assert(!has_identifier(parameters_of(^^fn)[0]));
|
||||
static_assert(identifier_of(parameters_of(^^fn)[1]) == "b");
|
||||
static_assert(has_consistent_identifier(parameters_of(^^fn)[1]));
|
||||
static_assert(any_identifier_of(parameters_of(^^fn)[2]) == "c1" ||
|
||||
any_identifier_of(parameters_of(^^fn)[2]) == "c2");
|
||||
static_assert(!has_consistent_identifier(parameters_of(^^fn)[2]));
|
||||
static_assert(has_identifier(parameters_of(^^fn)[1]));
|
||||
static_assert(!has_identifier(parameters_of(^^fn)[2]));
|
||||
|
||||
static_assert(r_a2 == r_a3);
|
||||
} // namespace with_ambiguous_names
|
||||
@@ -289,4 +282,25 @@ void user(int) {
|
||||
}
|
||||
} // namespace mangle_reflection_of_function_parameter
|
||||
|
||||
// =================
|
||||
// variable_of_tests
|
||||
// =================
|
||||
|
||||
namespace variable_of_tests {
|
||||
consteval int fn(int p) {
|
||||
constexpr auto rp = parameters_of(^^fn)[0];
|
||||
constexpr auto rv = variable_of(rp);
|
||||
static_assert(is_function_parameter(rp));
|
||||
static_assert(!is_function_parameter(rv));
|
||||
static_assert(!is_variable(rp));
|
||||
static_assert(is_variable(rv));
|
||||
static_assert(^^p == rv);
|
||||
|
||||
return [:variable_of(parameters_of(^^fn)[0]):];
|
||||
}
|
||||
|
||||
static_assert(fn(42) == 42);
|
||||
|
||||
} // namespace variable_of_tests
|
||||
|
||||
int main() { }
|
||||
|
||||
Reference in New Issue
Block a user