Skip to content

Commit

Permalink
Null reflections.
Browse files Browse the repository at this point in the history
Closes issue #46.
  • Loading branch information
katzdm committed Jun 7, 2024
1 parent b9b286b commit 1e43294
Show file tree
Hide file tree
Showing 19 changed files with 162 additions and 1 deletion.
3 changes: 3 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -5329,6 +5329,7 @@ class CXXReflectExpr : public Expr {
SourceLocation OpLoc;
SourceLocation ArgLoc;

CXXReflectExpr(const ASTContext &C, QualType T);
CXXReflectExpr(const ASTContext &C, QualType T, QualType Arg);
CXXReflectExpr(const ASTContext &C, QualType T, Expr *Arg);
CXXReflectExpr(const ASTContext &C, QualType T, Decl *Arg, bool IsNamespace);
Expand All @@ -5337,6 +5338,8 @@ class CXXReflectExpr : public Expr {
CXXReflectExpr(const ASTContext &C, QualType T, TagDataMemberSpec *Arg);

public:
static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc,
SourceLocation OperandLoc);
static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc,
SourceLocation ArgLoc, QualType Operand);
static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/PropertiesBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ class PropertyTypeCase<PropertyType type, string name> : HasProperties {
// Type cases for ReflectionValue.
def : PropertyTypeKind<ReflectionValue, ReflectionKind,
"node.getKind()">;
let Class = PropertyTypeCase<ReflectionValue, "RK_null"> in {
def : Creator<[{
return ReflectionValue();
}]>;
}
let Class = PropertyTypeCase<ReflectionValue, "RK_type"> in {
def : Property<"value", QualType> {
let Read = [{ node.getAsType() }];
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 @@ -2970,6 +2970,7 @@ DEF_TRAVERSE_STMT(CXXReflectExpr, {
TRY_TO(TraverseDecl(Op.getAsNamespace()));
break;
}
case ReflectionValue::RK_null:
case ReflectionValue::RK_base_specifier:
case ReflectionValue::RK_data_member_spec:
break;
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/AST/Reflection.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class ReflectionValue {
public:
/// \brief The kind of construct reflected.
enum ReflectionKind {
/// \brief A null reflection. Corresponds to no object.
RK_null = 0,

/// \brief A reflection of a type. Corresponds to an object of type
/// QualType.
RK_type = 1,
Expand Down Expand Up @@ -86,7 +89,7 @@ class ReflectionValue {
void *Entity;

public:
ReflectionValue() = default;
ReflectionValue();
ReflectionValue(ReflectionValue const&Rhs);
ReflectionValue(ReflectionKind ReflKind, void *Entity);
ReflectionValue &operator=(ReflectionValue const& Rhs);
Expand All @@ -98,6 +101,9 @@ class ReflectionValue {
return Entity;
}

/// Returns whether this is a null reflection.
bool isNull() const;

/// Returns this as a type operand.
QualType getAsType() const;

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/APValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
const ReflectionValue& Refl = getReflection();
std::string Repr("...");
switch (Refl.getKind()) {
case ReflectionValue::RK_null:
Repr = "null";
break;
case ReflectionValue::RK_type:
Repr = "type";
break;
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 @@ -965,6 +965,7 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E,
D |= ExprDependence::UnexpandedPack;
return D | computeDeclDependence(VD, Ctx);
}
case ReflectionValue::RK_null:
case ReflectionValue::RK_namespace:
case ReflectionValue::RK_base_specifier:
case ReflectionValue::RK_data_member_spec:
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,11 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C,
return new (Mem) TypeTraitExpr(EmptyShell());
}

CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType T)
: Expr(CXXReflectExprClass, T, VK_PRValue, OK_Ordinary), Ref() {
setDependence(computeDependence(this, C));
}

CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType T,
QualType Operand)
: Expr(CXXReflectExprClass, T, VK_PRValue, OK_Ordinary),
Expand Down Expand Up @@ -1885,6 +1890,15 @@ CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType T,
setDependence(computeDependence(this, C));
}

CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C,
SourceLocation OperatorLoc,
SourceLocation OperandLoc) {
CXXReflectExpr *E = new (C) CXXReflectExpr(C, C.MetaInfoTy);
E->setOperatorLoc(OperatorLoc);
E->setArgLoc(OperandLoc);
return E;
}

CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C,
SourceLocation OperatorLoc,
SourceLocation OperandLoc,
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15777,6 +15777,15 @@ class ReflectionEvaluator
return true;
}

bool ZeroInitialization(const Expr *E) {
Result = APValue(ReflectionValue::RK_null, nullptr);
return true;
}

bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
return ZeroInitialization(E);
}

bool VisitCXXReflectExpr(const CXXReflectExpr *E);
bool VisitCXXMetafunctionExpr(const CXXMetafunctionExpr *E);
bool VisitCXXIndeterminateSpliceExpr(const CXXIndeterminateSpliceExpr *E);
Expand All @@ -15786,6 +15795,10 @@ class ReflectionEvaluator
bool ReflectionEvaluator::VisitCXXReflectExpr(const CXXReflectExpr *E) {
const ReflectionValue &Ref = E->getOperand();
switch (Ref.getKind()) {
case ReflectionValue::RK_null: {
APValue Result(ReflectionValue::RK_null, nullptr);
return Success(Result, E);
}
case ReflectionValue::RK_type: {
APValue Result(ReflectionValue::RK_type, Ref.getAsType().getAsOpaquePtr());
return Success(Result, E);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4672,6 +4672,9 @@ void CXXNameMangler::mangleReflection(const ReflectionValue &R) {
Out << 'M';

switch (R.getKind()) {
case ReflectionValue::RK_null:
Out << '0';
break;
case ReflectionValue::RK_type: {
Out << 't';
QualType QT = R.getAsType();
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2031,6 +2031,9 @@ void MicrosoftCXXNameMangler::mangleReflection(const ReflectionValue &R) {

const void *opaque = R.getOpaqueValue();
switch (R.getKind()) {
case ReflectionValue::RK_null:
Out << '0';
break;
case ReflectionValue::RK_type: {
Out << 't';
QualType QT = QualType::getFromOpaquePtr(opaque);
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/Reflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

namespace clang {

ReflectionValue::ReflectionValue() : Kind(RK_null), Entity(nullptr) { }

ReflectionValue::ReflectionValue(ReflectionKind Kind, void *Entity)
: Kind(Kind), Entity(Entity) {
}
Expand All @@ -37,6 +39,8 @@ ReflectionValue &ReflectionValue::operator=(ReflectionValue const&Rhs) {
return *this;
}

bool ReflectionValue::isNull() const { return Kind == RK_null; }

QualType ReflectionValue::getAsType() const {
assert(getKind() == RK_type && "not a type");

Expand Down Expand Up @@ -68,6 +72,8 @@ QualType ReflectionValue::getAsType() const {
void ReflectionValue::Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddInteger(Kind);
switch (Kind) {
case RK_null:
break;
case RK_type: {
QualType QT = getAsType();
QT.Profile(ID);
Expand Down Expand Up @@ -115,6 +121,8 @@ bool ReflectionValue::operator==(ReflectionValue const& Rhs) const {
return false;

switch (getKind()) {
case RK_null:
return true;
case RK_type: {
QualType LQT = getAsType(), RQT = Rhs.getAsType();
if (LQT.getQualifiers() != RQT.getQualifiers())
Expand Down
Loading

0 comments on commit 1e43294

Please sign in to comment.