Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P3385 #102

Draft
wants to merge 18 commits into
base: p2996
Choose a base branch
from
6 changes: 6 additions & 0 deletions clang/include/clang/AST/APValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ template <typename T> class BasicReaderBase;

class AddrLabelExpr;
class ASTContext;
class AttributeCommonInfo;
class CharUnits;
class CXX26AnnotationAttr;
class CXXRecordDecl;
Expand Down Expand Up @@ -489,6 +490,10 @@ class APValue {
return isReflection() && getReflectionKind() == ReflectionKind::Annotation;
}

bool isReflectedAttribute() const {
return isReflection() && getReflectionKind() == ReflectionKind::Attribute;
}

void dump() const;
void dump(raw_ostream &OS, const ASTContext &Context) const;

Expand Down Expand Up @@ -678,6 +683,7 @@ class APValue {
CXXBaseSpecifier *getReflectedBaseSpecifier() const;
TagDataMemberSpec *getReflectedDataMemberSpec() const;
CXX26AnnotationAttr *getReflectedAnnotation() const;
AttributeCommonInfo *getReflectedAttribute() const;

void setInt(APSInt I) {
assert(isInt() && "Invalid accessor");
Expand Down
7 changes: 4 additions & 3 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -5321,7 +5321,8 @@ class BuiltinBitCastExpr final
};

/// Represents a C++2c reflect expression (P2996). The operand of the expression
/// is either a type, an expression, a template-name, or a namespace.
/// is either a type, an expression, a template-name, an attribute or a
/// namespace.
class CXXReflectExpr : public Expr {
enum class OperandKind {
Unset,
Expand Down Expand Up @@ -5408,12 +5409,12 @@ class CXXReflectExpr : public Expr {
/// reflections (P2996). Arguments vary by function.
class CXXMetafunctionExpr : public Expr {
public:
// Type of callback provided to executing metafunctinons to help evaluate an
// Type of callback provided to executing metafunctions to help evaluate an
// expression in the current constant evaluation context.
using EvaluateFn = std::function<bool(APValue &, const Expr *,
bool ConvertToRValue)>;

// Type of callback provided to report a diagnistc to the evaluation context.
// Type of callback provided to report a diagnostic to the evaluation context.
using DiagnoseFn = std::function<PartialDiagnostic &(SourceLocation,
unsigned)>;

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2991,6 +2991,7 @@ DEF_TRAVERSE_STMT(CXXReflectExpr, {
case ReflectionKind::Namespace:
case ReflectionKind::BaseSpecifier:
case ReflectionKind::DataMemberSpec:
case ReflectionKind::Attribute: // TODO P3385 ?
break;
}
}
Expand Down
6 changes: 4 additions & 2 deletions clang/include/clang/AST/Reflection.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ enum class ReflectionKind {
///
/// Corresponds to an APValue (plus a QualType).
Object,

/// \brief A reflection of a value (i.e., the result of a prvalue).
///
/// Corresponds to an APValue (plus a QualType).
Expand Down Expand Up @@ -102,8 +102,10 @@ enum class ReflectionKind {

/// \brief A reflection of an annotation (P2996 ext).
Annotation,
};

/// \brief A reflection of a standard attribute (P3385).
Attribute,
};

/// \brief Representation of a hypothetical data member, which could be used to
/// complete an incomplete class definition using the 'std::meta::define_class'
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Basic/DiagnosticMetafnKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def metafn_no_associated_property : Note<
"%0 has no %select{type|parent}1">;
def metafn_cannot_query_property : Note<"cannot query the "
"%select{type|object|value|size|alignment|parameters|return type|"
"annotations}0 of %1">;
"annotations|attributes}0 of %1">;

// Ranges of entities.
def metafn_cannot_introspect_type : Note<
Expand Down Expand Up @@ -88,6 +88,10 @@ def metafn_value_not_structural_type : Note<
"values of non-structural type %0 cannot be represented as reflections">;
def metafn_result_not_representable : Note<
"provided %select{value|object}0 cannot be represented by a reflection">;
def metafn_p3385_trace_execution_checkpoint : Note<
"(p3385-metafn) trace_execution_checkpoint %0">;
def metafn_p3385_non_standard_attribute : Warning<
"(p3385-metafn) Non standard attribute discovered %0">;

// Class definition.
def metafn_name_invalid_identifier : Note<
Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1746,6 +1746,19 @@ def err_annotation_with_using : Error<
"annotations are not permitted following an attribute-using-prefix">;
}

let CategoryName = "P3385" in {

def p3385_trace_attribute_parsed : Warning<
"(p3385) found attribute to parse following caret operator">;
def p3385_trace_empty_attributes_list : Warning<
"(p3385) reflection of an empty attribute list">;
def p3385_trace_execution_checkpoint : Warning<
"(p3385) trace_execution_checkpoint %0">;
def p3385_err_attributes_list : Error<
"(p3385) reflection of attribute list is not supported, found %0 attributes">;

}

let CategoryName = "Generics Issue" in {

def err_objc_expected_type_parameter : Error<
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3173,6 +3173,9 @@ def note_dependent_splice_explicit_this_may_fix : Note<
def err_cannot_expand_over_type : Error<
"cannot expand over an expression of type %0">;

def p3385_trace_building_attribute_reflection : Warning<
"(p3385) building a CXX reflection on attribute %0">;

// C++11 char16_t/char32_t
def warn_cxx98_compat_unicode_type : Warning<
"'%0' type specifier is incompatible with C++98">,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/Cuda.h"
Expand Down Expand Up @@ -15173,6 +15174,7 @@ class Sema final : public SemaBase {
ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc,
ParsedTemplateArgument Template);
ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, CXXSpliceExpr *E);
ExprResult ActOnCXXReflectExpr(SourceLocation OpLoc, ParsedAttr *a);

ExprResult ActOnCXXMetafunction(SourceLocation KwLoc,
SourceLocation LParenLoc,
Expand Down Expand Up @@ -15222,6 +15224,7 @@ class Sema final : public SemaBase {
ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc,
SourceLocation OperandLoc,
TemplateName Template);
ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, ParsedAttr *A);

// Reflection of expression operands.
ExprResult BuildCXXReflectExpr(SourceLocation OperatorLoc, Expr *E);
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/AST/APValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/LocInfoType.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
Expand Down Expand Up @@ -547,6 +548,7 @@ static void profileReflection(llvm::FoldingSetNodeID &ID, APValue V) {
case ReflectionKind::Namespace:
case ReflectionKind::BaseSpecifier:
case ReflectionKind::Annotation:
case ReflectionKind::Attribute:
ID.AddPointer(V.getOpaqueReflectionData());
return;
case ReflectionKind::DataMemberSpec: {
Expand Down Expand Up @@ -942,6 +944,13 @@ CXX26AnnotationAttr *APValue::getReflectedAnnotation() const {
const_cast<void *>(getOpaqueReflectionData()));
}

AttributeCommonInfo *APValue::getReflectedAttribute() const {
assert(getReflectionKind() == ReflectionKind::Attribute &&
"not a reflection of an attribute");
return reinterpret_cast<AttributeCommonInfo *>(
const_cast<void *>(getOpaqueReflectionData()));
}

static double GetApproxValue(const llvm::APFloat &F) {
llvm::APFloat V = F;
bool ignored;
Expand Down Expand Up @@ -1295,6 +1304,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
case ReflectionKind::Annotation:
Repr = "annotation";
break;
case ReflectionKind::Attribute:
Repr = "attribute";
break;
}
Out << "^^(" << Repr << ")";
return;
Expand Down Expand Up @@ -1635,6 +1647,7 @@ void APValue::setReflection(ReflectionKind RK, const void *Ptr) {
case ReflectionKind::BaseSpecifier:
case ReflectionKind::DataMemberSpec:
case ReflectionKind::Annotation:
case ReflectionKind::Attribute:
SelfData.Kind = RK;
SelfData.Data = Ptr;
return;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ComputeDependence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,7 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E,
case ReflectionKind::Namespace:
case ReflectionKind::BaseSpecifier:
case ReflectionKind::DataMemberSpec:
case ReflectionKind::Attribute:
return ExprDependence::None;
}
llvm_unreachable("unknown reflection kind while computing dependence");
Expand Down
Loading