Skip to content

Commit

Permalink
Initial support for importing reflections between modules.
Browse files Browse the repository at this point in the history
Some work remains: In particular, if this is going to "work" (i.e.,
supported by P2996), we need to think carefully about reachability,
TU-local entities, etc. There probably need to be some constraints
around use of imported reflections, and possibly some 'is_reachable'
metafunction. Not entirely sure - need to experiment further.

Closes issue #4.
  • Loading branch information
katzdm committed Aug 15, 2024
1 parent 78a4192 commit dcc8c34
Show file tree
Hide file tree
Showing 13 changed files with 585 additions and 108 deletions.
149 changes: 79 additions & 70 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -5323,6 +5323,7 @@ class BuiltinBitCastExpr final
/// is either a type, an expression, a template-name, or a namespace.
class CXXReflectExpr : public Expr {
enum class OperandKind {
Unset,
Reflection,
DependentExpr
};
Expand All @@ -5337,12 +5338,14 @@ class CXXReflectExpr : public Expr {

CXXReflectExpr(const ASTContext &C, QualType ExprTy, APValue RV);
CXXReflectExpr(const ASTContext &C, QualType ExprTy, Expr *DepSubExpr);
CXXReflectExpr(EmptyShell Empty);

public:
static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc,
SourceRange OperandRange, APValue RV);
static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc,
Expr *DepSubExpr);
static CXXReflectExpr *CreateEmpty(const ASTContext &C);

/// Returns the operand of the reflection expression.
APValue getReflection() const {
Expand All @@ -5369,6 +5372,20 @@ class CXXReflectExpr : public Expr {
SourceLocation getOperatorLoc() const { return OperatorLoc; }
SourceRange getOperandRange() const { return OperandRange; }

/// Sets the APValue operand.
void setAPValue(APValue RV) {
assert(Kind == OperandKind::Unset || Kind == OperandKind::Reflection);
Kind = OperandKind::Reflection;
new ((void *)(char *)&Operand) APValue(RV);
}

/// Sets the dependent subexpression operand.
void setDependentSubExpr(Expr *E) {
assert(Kind == OperandKind::Unset || Kind == OperandKind::DependentExpr);
Kind = OperandKind::DependentExpr;
new ((void *)(char *)&Operand) Expr *(E);
}

/// Sets the location of the '^'-operator.
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
void setOperandRange(SourceRange R) { OperandRange = R; }
Expand Down Expand Up @@ -5412,7 +5429,7 @@ class CXXMetafunctionExpr : public Expr {

// An unowned reference to a callback for executing the metafunction at
// constant evaluation time.
const ImplFn &Impl;
const ImplFn *Impl;

// Result type.
QualType ResultType;
Expand All @@ -5430,6 +5447,9 @@ class CXXMetafunctionExpr : public Expr {
QualType ResultType, ExprValueKind VK, Expr ** Args,
unsigned NumArgs, SourceLocation KwLoc,
SourceLocation LParenLoc, SourceLocation RParenLoc);

CXXMetafunctionExpr(EmptyShell Empty);

public:
static CXXMetafunctionExpr *Create(ASTContext &C, unsigned MetaFnID,
const ImplFn &Impl,
Expand All @@ -5439,46 +5459,40 @@ class CXXMetafunctionExpr : public Expr {
SourceLocation LParenLoc,
SourceLocation RParenLoc);

unsigned getMetaFnID() const {
return MetaFnID;
}
static CXXMetafunctionExpr *CreateEmpty(ASTContext &C);

const ImplFn &getImpl() const {
return Impl;
}
unsigned getMetaFnID() const { return MetaFnID; }
void setMetaFnID(unsigned ID) { MetaFnID = ID; }

QualType getResultType() const {
return ResultType;
}
const ImplFn &getImpl() const { return *Impl; }
void setImpl(const ImplFn &Fn) { Impl = &Fn; }

unsigned getNumArgs() const {
return NumArgs;
}
QualType getResultType() const { return ResultType; }
void setResultType(QualType QT) { ResultType = QT; }

// TODO(P2996): Consider implementing this with trailing objects.
unsigned getNumArgs() const { return NumArgs; }

Expr *getArg(unsigned I) const {
assert(I < NumArgs && "argument out-of-range");
return cast<Expr>(Args[I]);
}

SourceLocation getKwLoc() const {
return KwLoc;
void setArgs(Expr **NewArgs, unsigned Count) {
Args = NewArgs;
NumArgs = Count;
}

SourceLocation getLParenLoc() const {
return LParenLoc;
}
SourceLocation getKwLoc() const { return KwLoc; }
void setKwLoc(SourceLocation Loc) { KwLoc = Loc; }

SourceLocation getRParenLoc() const {
return RParenLoc;
}
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

SourceLocation getBeginLoc() const {
return KwLoc;
}
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }

SourceLocation getEndLoc() const {
return RParenLoc;
}
SourceLocation getBeginLoc() const { return KwLoc; }
SourceLocation getEndLoc() const { return RParenLoc; }

SourceRange getSourceRange() const {
return SourceRange(getBeginLoc(), getEndLoc());
Expand Down Expand Up @@ -5511,28 +5525,28 @@ class CXXSpliceSpecifierExpr : public Expr {
SourceLocation LSpliceLoc, Expr *Operand,
SourceLocation RSpliceLoc);

CXXSpliceSpecifierExpr(EmptyShell Empty);

public:
static CXXSpliceSpecifierExpr *Create(ASTContext &C,
SourceLocation TemplateKWLoc,
SourceLocation LSpliceLoc,
Expr *Operand,
SourceLocation RSpliceLoc);

Expr *getOperand() const {
return Operand;
}
static CXXSpliceSpecifierExpr *CreateEmpty(ASTContext &C);

SourceLocation getTemplateKWLoc() const {
return TemplateKWLoc;
}
Expr *getOperand() const { return Operand; }
void setOperand(Expr *E) { Operand = E; }

SourceLocation getLSpliceLoc() const {
return LSpliceLoc;
}
SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
void setTemplateKWLoc(SourceLocation Loc) { TemplateKWLoc = Loc; }

SourceLocation getRSpliceLoc() const {
return RSpliceLoc;
}
SourceLocation getLSpliceLoc() const { return LSpliceLoc; }
void setLSpliceLoc(SourceLocation Loc) { LSpliceLoc = Loc; }

SourceLocation getRSpliceLoc() const { return RSpliceLoc; }
void setRSpliceLoc(SourceLocation Loc) { RSpliceLoc = Loc; }

SourceLocation getBeginLoc() const {
if (TemplateKWLoc.isValid())
Expand Down Expand Up @@ -5659,6 +5673,8 @@ class CXXSpliceExpr final
const TemplateArgumentListInfo *TemplateArgs,
bool AllowMemberReference);

CXXSpliceExpr(EmptyShell Empty);

inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() {
return getTrailingObjects<ASTTemplateKWAndArgsInfo>();
}
Expand Down Expand Up @@ -5696,13 +5712,13 @@ class CXXSpliceExpr final
const TemplateArgumentListInfo *TemplateArgs,
bool AllowMemberReference);

Expr *getOperand() const {
return Operand;
}
static CXXSpliceExpr *CreateEmpty(ASTContext &C);

bool allowMemberReference() const {
return AllowMemberReference;
}
Expr *getOperand() const { return Operand; }
void setOperand(Expr *E) { Operand = E; }

bool allowMemberReference() const { return AllowMemberReference; }
void setAllowMemberReference(bool Allow) { AllowMemberReference = Allow; }

/// Determines whether the splice was preceded by the template keyword.
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
Expand Down Expand Up @@ -5755,13 +5771,11 @@ class CXXSpliceExpr final
return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
}

SourceLocation getLSpliceLoc() const {
return LSpliceLoc;
}
SourceLocation getLSpliceLoc() const { return LSpliceLoc; }
void setLSpliceLoc(SourceLocation Loc) { LSpliceLoc = Loc; }

SourceLocation getRSpliceLoc() const {
return RSpliceLoc;
}
SourceLocation getRSpliceLoc() const { return RSpliceLoc; }
void setRSpliceLoc(SourceLocation Loc) { RSpliceLoc = Loc; }

SourceLocation getBeginLoc() const {
if (SourceLocation KWLoc = getTemplateKeywordLoc(); KWLoc.isValid())
Expand Down Expand Up @@ -5807,34 +5821,29 @@ class CXXDependentMemberSpliceExpr : public Expr {
SourceLocation OpLoc, bool IsArrow,
CXXSpliceExpr *RHS);

CXXDependentMemberSpliceExpr(EmptyShell Empty);

public:
static CXXDependentMemberSpliceExpr *Create(ASTContext &C, Expr *Base,
SourceLocation OpLoc,
bool IsArrow, CXXSpliceExpr *RHS);

Expr *getBase() const {
return cast<Expr>(SubExprs[0]);
}
static CXXDependentMemberSpliceExpr *CreateEmpty(ASTContext &C);

SourceLocation getOpLoc() const {
return OpLoc;
}
Expr *getBase() const { return cast<Expr>(SubExprs[0]); }
void setBase(Expr *E) { SubExprs[0] = E; }

bool isArrow() const {
return IsArrow;
}
SourceLocation getOpLoc() const { return OpLoc; }
void setOpLoc(SourceLocation Loc) { OpLoc = Loc; }

CXXSpliceExpr *getRHS() const {
return cast<CXXSpliceExpr>(SubExprs[1]);
}
bool isArrow() const { return IsArrow; }
void setIsArrow(bool Arrow) { IsArrow = Arrow; }

SourceLocation getBeginLoc() const {
return getBase()->getBeginLoc();
}
CXXSpliceExpr *getRHS() const { return cast<CXXSpliceExpr>(SubExprs[1]); }
void setRHS(CXXSpliceExpr *E) { SubExprs[1] = E; }

SourceLocation getEndLoc() const {
return getRHS()->getEndLoc();
}
SourceLocation getBeginLoc() const { return getBase()->getBeginLoc(); }
SourceLocation getEndLoc() const { return getRHS()->getEndLoc(); }

child_range children() {
return child_range(SubExprs, SubExprs + 2);
Expand Down
Loading

0 comments on commit dcc8c34

Please sign in to comment.