Skip to content

Commit 7c44da2

Browse files
committed
Create ConstantExpr class
A ConstantExpr class represents a full expression that's in a context where a constant expression is required. This class reflects the path the evaluator took to reach the expression rather than the syntactic context in which the expression occurs. In the future, the class will be expanded to cache the result of the evaluated expression so that it's not needlessly re-evaluated Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D53475 llvm-svn: 345692
1 parent 4ff6697 commit 7c44da2

40 files changed

+187
-73
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,64 @@ class Expr : public Stmt {
868868
}
869869
};
870870

871+
//===----------------------------------------------------------------------===//
872+
// Wrapper Expressions.
873+
//===----------------------------------------------------------------------===//
874+
875+
/// FullExpr - Represents a "full-expression" node.
876+
class FullExpr : public Expr {
877+
protected:
878+
Stmt *SubExpr;
879+
880+
FullExpr(StmtClass SC, Expr *subexpr)
881+
: Expr(SC, subexpr->getType(),
882+
subexpr->getValueKind(), subexpr->getObjectKind(),
883+
subexpr->isTypeDependent(), subexpr->isValueDependent(),
884+
subexpr->isInstantiationDependent(),
885+
subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {}
886+
FullExpr(StmtClass SC, EmptyShell Empty)
887+
: Expr(SC, Empty) {}
888+
public:
889+
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
890+
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
891+
892+
/// As with any mutator of the AST, be very careful when modifying an
893+
/// existing AST to preserve its invariants.
894+
void setSubExpr(Expr *E) { SubExpr = E; }
895+
896+
static bool classof(const Stmt *T) {
897+
return T->getStmtClass() >= firstFullExprConstant &&
898+
T->getStmtClass() <= lastFullExprConstant;
899+
}
900+
};
901+
902+
/// ConstantExpr - An expression that occurs in a constant context.
903+
struct ConstantExpr : public FullExpr {
904+
ConstantExpr(Expr *subexpr)
905+
: FullExpr(ConstantExprClass, subexpr) {}
906+
907+
/// Build an empty constant expression wrapper.
908+
explicit ConstantExpr(EmptyShell Empty)
909+
: FullExpr(ConstantExprClass, Empty) {}
910+
911+
SourceLocation getBeginLoc() const LLVM_READONLY {
912+
return SubExpr->getBeginLoc();
913+
}
914+
SourceLocation getEndLoc() const LLVM_READONLY {
915+
return SubExpr->getEndLoc();
916+
}
917+
918+
static bool classof(const Stmt *T) {
919+
return T->getStmtClass() == ConstantExprClass;
920+
}
921+
922+
// Iterators
923+
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
924+
const_child_range children() const {
925+
return const_child_range(&SubExpr, &SubExpr + 1);
926+
}
927+
};
928+
871929
//===----------------------------------------------------------------------===//
872930
// Primary Expressions.
873931
//===----------------------------------------------------------------------===//

clang/include/clang/AST/ExprCXX.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,7 +3031,7 @@ class DependentScopeDeclRefExpr final
30313031
/// potentially-evaluated block literal. The lifetime of a block
30323032
/// literal is the extent of the enclosing scope.
30333033
class ExprWithCleanups final
3034-
: public Expr,
3034+
: public FullExpr,
30353035
private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
30363036
public:
30373037
/// The type of objects that are kept in the cleanup.
@@ -3044,8 +3044,6 @@ class ExprWithCleanups final
30443044
friend class ASTStmtReader;
30453045
friend TrailingObjects;
30463046

3047-
Stmt *SubExpr;
3048-
30493047
ExprWithCleanups(EmptyShell, unsigned NumObjects);
30503048
ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
30513049
ArrayRef<CleanupObject> Objects);
@@ -3070,17 +3068,10 @@ class ExprWithCleanups final
30703068
return getObjects()[i];
30713069
}
30723070

3073-
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
3074-
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
3075-
30763071
bool cleanupsHaveSideEffects() const {
30773072
return ExprWithCleanupsBits.CleanupsHaveSideEffects;
30783073
}
30793074

3080-
/// As with any mutator of the AST, be very careful
3081-
/// when modifying an existing AST to preserve its invariants.
3082-
void setSubExpr(Expr *E) { SubExpr = E; }
3083-
30843075
SourceLocation getBeginLoc() const LLVM_READONLY {
30853076
return SubExpr->getBeginLoc();
30863077
}

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,8 @@ DEF_TRAVERSE_STMT(ReturnStmt, {})
21992199
DEF_TRAVERSE_STMT(SwitchStmt, {})
22002200
DEF_TRAVERSE_STMT(WhileStmt, {})
22012201

2202+
DEF_TRAVERSE_STMT(ConstantExpr, {})
2203+
22022204
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
22032205
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
22042206
TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));

clang/include/clang/Basic/StmtNodes.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ def VAArgExpr : DStmt<Expr>;
9393
def GenericSelectionExpr : DStmt<Expr>;
9494
def PseudoObjectExpr : DStmt<Expr>;
9595

96+
// Wrapper expressions
97+
def FullExpr : DStmt<Expr, 1>;
98+
def ConstantExpr : DStmt<FullExpr>;
99+
96100
// Atomic expressions
97101
def AtomicExpr : DStmt<Expr>;
98102

@@ -131,7 +135,7 @@ def DependentScopeDeclRefExpr : DStmt<Expr>;
131135
def CXXConstructExpr : DStmt<Expr>;
132136
def CXXInheritedCtorInitExpr : DStmt<Expr>;
133137
def CXXBindTemporaryExpr : DStmt<Expr>;
134-
def ExprWithCleanups : DStmt<Expr>;
138+
def ExprWithCleanups : DStmt<FullExpr>;
135139
def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
136140
def CXXUnresolvedConstructExpr : DStmt<Expr>;
137141
def CXXDependentScopeMemberExpr : DStmt<Expr>;

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,9 @@ namespace serialization {
16181618
/// A MS-style AsmStmt record.
16191619
STMT_MSASM,
16201620

1621+
/// A constant expression context.
1622+
EXPR_CONSTANT,
1623+
16211624
/// A PredefinedExpr record.
16221625
EXPR_PREDEFINED,
16231626

clang/lib/ARCMigrate/TransAutoreleasePool.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ class AutoreleasePoolRewriter
403403
return cast<Expr>(getEssential((Stmt*)E));
404404
}
405405
static Stmt *getEssential(Stmt *S) {
406-
if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S))
407-
S = EWC->getSubExpr();
406+
if (FullExpr *FE = dyn_cast<FullExpr>(S))
407+
S = FE->getSubExpr();
408408
if (Expr *E = dyn_cast<Expr>(S))
409409
S = E->IgnoreParenCasts();
410410
return S;

clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class RetainReleaseDeallocRemover :
253253
}
254254
while (OuterS && (isa<ParenExpr>(OuterS) ||
255255
isa<CastExpr>(OuterS) ||
256-
isa<ExprWithCleanups>(OuterS)));
256+
isa<FullExpr>(OuterS)));
257257

258258
if (!OuterS)
259259
return std::make_pair(prevStmt, nextStmt);
@@ -376,8 +376,8 @@ class RetainReleaseDeallocRemover :
376376

377377
RecContainer = StmtE;
378378
Rec = Init->IgnoreParenImpCasts();
379-
if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Rec))
380-
Rec = EWC->getSubExpr()->IgnoreParenImpCasts();
379+
if (FullExpr *FE = dyn_cast<FullExpr>(Rec))
380+
Rec = FE->getSubExpr()->IgnoreParenImpCasts();
381381
RecRange = Rec->getSourceRange();
382382
if (SM.isMacroArgExpansion(RecRange.getBegin()))
383383
RecRange.setBegin(SM.getImmediateSpellingLoc(RecRange.getBegin()));

clang/lib/ARCMigrate/TransUnbridgedCasts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{
372372
Stmt *parent = E;
373373
do {
374374
parent = StmtMap->getParentIgnoreParenImpCasts(parent);
375-
} while (parent && isa<ExprWithCleanups>(parent));
375+
} while (parent && isa<FullExpr>(parent));
376376

377377
if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) {
378378
std::string note = "remove the cast and change return type of function "

clang/lib/ARCMigrate/Transforms.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ bool trans::isPlusOneAssign(const BinaryOperator *E) {
7474
bool trans::isPlusOne(const Expr *E) {
7575
if (!E)
7676
return false;
77-
if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E))
78-
E = EWC->getSubExpr();
77+
if (const FullExpr *FE = dyn_cast<FullExpr>(E))
78+
E = FE->getSubExpr();
7979

8080
if (const ObjCMessageExpr *
8181
ME = dyn_cast<ObjCMessageExpr>(E->IgnoreParenCasts()))

clang/lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2576,7 +2576,7 @@ Expr *ParmVarDecl::getDefaultArg() {
25762576
"Default argument is not yet instantiated!");
25772577

25782578
Expr *Arg = getInit();
2579-
if (auto *E = dyn_cast_or_null<ExprWithCleanups>(Arg))
2579+
if (auto *E = dyn_cast_or_null<FullExpr>(Arg))
25802580
return E->getSubExpr();
25812581

25822582
return Arg;

0 commit comments

Comments
 (0)