Skip to content

Commit

Permalink
[NFC, Scoped Enum] Convert Sema::ExpressionEvaluationContext into a s…
Browse files Browse the repository at this point in the history
…coped Enum

- also replace direct equality checks against the ConstantEvaluated enumerator  with isConstantEvaluted(), in anticipation of adding finer granularity to the various ConstantEvaluated contexts and reinstating certain restrictions on where lambda expressions can occur in C++17.

- update the clang tablegen backend that uses these Enumerators, and add the relevant scope where needed.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299316 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
faisalv committed Apr 1, 2017
1 parent d11ae8a commit 919ac41
Show file tree
Hide file tree
Showing 25 changed files with 257 additions and 181 deletions.
18 changes: 12 additions & 6 deletions include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,8 @@ class Sema {
: S(S), SavedContext(S, DC)
{
S.PushFunctionScope();
S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
S.PushExpressionEvaluationContext(
Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
}

~SynthesizedFunctionScope() {
Expand Down Expand Up @@ -802,7 +803,7 @@ class Sema {

/// \brief Describes how the expressions currently being parsed are
/// evaluated at run-time, if at all.
enum ExpressionEvaluationContext {
enum class ExpressionEvaluationContext {
/// \brief The current expression and its subexpressions occur within an
/// unevaluated operand (C++11 [expr]p7), such as the subexpression of
/// \c sizeof, where the type of the expression may be significant but
Expand Down Expand Up @@ -908,8 +909,12 @@ class Sema {
MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);

bool isUnevaluated() const {
return Context == Unevaluated || Context == UnevaluatedAbstract ||
Context == UnevaluatedList;
return Context == ExpressionEvaluationContext::Unevaluated ||
Context == ExpressionEvaluationContext::UnevaluatedAbstract ||
Context == ExpressionEvaluationContext::UnevaluatedList;
}
bool isConstantEvaluated() const {
return Context == ExpressionEvaluationContext::ConstantEvaluated;
}
};

Expand Down Expand Up @@ -10315,6 +10320,7 @@ class EnterExpressionEvaluationContext {
bool Entered = true;

public:

EnterExpressionEvaluationContext(Sema &Actions,
Sema::ExpressionEvaluationContext NewContext,
Decl *LambdaContextDecl = nullptr,
Expand Down Expand Up @@ -10345,8 +10351,8 @@ class EnterExpressionEvaluationContext {
// a context.
if (ShouldEnter && Actions.isUnevaluatedContext() &&
Actions.getLangOpts().CPlusPlus11) {
Actions.PushExpressionEvaluationContext(Sema::UnevaluatedList, nullptr,
false);
Actions.PushExpressionEvaluationContext(
Sema::ExpressionEvaluationContext::UnevaluatedList, nullptr, false);
Entered = true;
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Parse/ParseCXXInlineMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,9 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {

// The argument isn't actually potentially evaluated unless it is
// used.
EnterExpressionEvaluationContext Eval(Actions,
Sema::PotentiallyEvaluatedIfUsed,
Param);
EnterExpressionEvaluationContext Eval(
Actions,
Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, Param);

ExprResult DefArgResult;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Expand Down
24 changes: 14 additions & 10 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ unsigned Parser::ParseAttributeArgsCommon(
do {
bool Uneval = attributeParsedArgsUnevaluated(*AttrName);
EnterExpressionEvaluationContext Unevaluated(
Actions, Uneval ? Sema::Unevaluated : Sema::ConstantEvaluated,
Actions,
Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
: Sema::ExpressionEvaluationContext::ConstantEvaluated,
/*LambdaContextDecl=*/nullptr,
/*IsDecltype=*/false);

Expand Down Expand Up @@ -4093,8 +4095,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// anything that's a simple-type-specifier followed by '(' as an
// expression. This suffices because function types are not valid
// underlying types anyway.
EnterExpressionEvaluationContext Unevaluated(Actions,
Sema::ConstantEvaluated);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
// If the next token starts an expression, we know we're parsing a
// bit-field. This is the common case.
Expand Down Expand Up @@ -6270,9 +6272,10 @@ void Parser::ParseParameterDeclarationClause(

// The argument isn't actually potentially evaluated unless it is
// used.
EnterExpressionEvaluationContext Eval(Actions,
Sema::PotentiallyEvaluatedIfUsed,
Param);
EnterExpressionEvaluationContext Eval(
Actions,
Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed,
Param);

ExprResult DefArgResult;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Expand Down Expand Up @@ -6422,8 +6425,8 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
if (getLangOpts().CPlusPlus) {
NumElements = ParseConstantExpression();
} else {
EnterExpressionEvaluationContext Unevaluated(Actions,
Sema::ConstantEvaluated);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
NumElements =
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
}
Expand Down Expand Up @@ -6558,8 +6561,9 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {

const bool hasParens = Tok.is(tok::l_paren);

EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
Sema::ReuseLambdaContextDecl);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
Sema::ReuseLambdaContextDecl);

bool isCastExpr;
ParsedType CastTy;
Expand Down
10 changes: 5 additions & 5 deletions lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,8 +935,9 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {

// C++11 [dcl.type.simple]p4:
// The operand of the decltype specifier is an unevaluated operand.
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
nullptr,/*IsDecltype=*/true);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
/*IsDecltype=*/true);
Result =
Actions.CorrectDelayedTyposInExpr(ParseExpression(), [](Expr *E) {
return E->hasPlaceholderType() ? ExprError() : E;
Expand Down Expand Up @@ -2897,9 +2898,8 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
assert(Tok.isOneOf(tok::equal, tok::l_brace)
&& "Data member initializer not starting with '=' or '{'");

EnterExpressionEvaluationContext Context(Actions,
Sema::PotentiallyEvaluated,
D);
EnterExpressionEvaluationContext Context(
Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, D);
if (TryConsumeToken(tok::equal, EqualLoc)) {
if (Tok.is(tok::kw_delete)) {
// In principle, an initializer of '= delete p;' is legal, but it will
Expand Down
22 changes: 13 additions & 9 deletions lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
// An expression is potentially evaluated unless it appears where an
// integral constant expression is required (see 5.19) [...].
// C++98 and C++11 have no such rule, but this is only a defect in C++98.
EnterExpressionEvaluationContext ConstantEvaluated(Actions,
Sema::ConstantEvaluated);
EnterExpressionEvaluationContext ConstantEvaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);

ExprResult LHS(ParseCastExpression(false, false, isTypeCast));
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
Expand Down Expand Up @@ -1313,7 +1313,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// C++11 [expr.unary.noexcept]p1:
// The noexcept operator determines whether the evaluation of its operand,
// which is an unevaluated operand, can throw an exception.
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
ExprResult Result = ParseExpression();

T.consumeClose();
Expand Down Expand Up @@ -1882,9 +1883,10 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {

if (!Name)
return ExprError();

EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
Sema::ReuseLambdaContextDecl);

EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
Sema::ReuseLambdaContextDecl);

return Actions.ActOnSizeofParameterPackExpr(getCurScope(),
OpTok.getLocation(),
Expand All @@ -1895,8 +1897,9 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
if (OpTok.isOneOf(tok::kw_alignof, tok::kw__Alignof))
Diag(OpTok, diag::warn_cxx98_compat_alignof);

EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
Sema::ReuseLambdaContextDecl);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
Sema::ReuseLambdaContextDecl);

bool isCastExpr;
ParsedType CastTy;
Expand Down Expand Up @@ -2569,7 +2572,8 @@ ExprResult Parser::ParseGenericSelectionExpression() {
{
// C11 6.5.1.1p3 "The controlling expression of a generic selection is
// not evaluated."
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
ControllingExpr =
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (ControllingExpr.isInvalid()) {
Expand Down
12 changes: 7 additions & 5 deletions lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,8 +866,8 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
// Each lambda init-capture forms its own full expression, which clears
// Actions.MaybeODRUseExprs. So create an expression evaluation context
// to save the necessary state, and restore it later.
EnterExpressionEvaluationContext EC(Actions,
Sema::PotentiallyEvaluated);
EnterExpressionEvaluationContext EC(
Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);

if (TryConsumeToken(tok::equal))
InitKind = LambdaCaptureInitKind::CopyInit;
Expand Down Expand Up @@ -1405,8 +1405,9 @@ ExprResult Parser::ParseCXXTypeid() {
// We enter the unevaluated context before trying to determine whether we
// have a type-id, because the tentative parse logic will try to resolve
// names, and must treat them as unevaluated.
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
Sema::ReuseLambdaContextDecl);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated,
Sema::ReuseLambdaContextDecl);

if (isTypeIdInParens()) {
TypeResult Ty = ParseTypeName();
Expand Down Expand Up @@ -1469,7 +1470,8 @@ ExprResult Parser::ParseCXXUuidof() {
Ty.get().getAsOpaquePtr(),
T.getCloseLocation());
} else {
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
Result = ParseExpression();

// Match the ')'.
Expand Down
6 changes: 4 additions & 2 deletions lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
StmtResult ThenStmt;
{
EnterExpressionEvaluationContext PotentiallyDiscarded(
Actions, Sema::DiscardedStatement, nullptr, false,
Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr,
false,
/*ShouldEnter=*/ConstexprCondition && !*ConstexprCondition);
ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc);
}
Expand Down Expand Up @@ -1212,7 +1213,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
Tok.is(tok::l_brace));

EnterExpressionEvaluationContext PotentiallyDiscarded(
Actions, Sema::DiscardedStatement, nullptr, false,
Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr,
false,
/*ShouldEnter=*/ConstexprCondition && *ConstexprCondition);
ElseStmt = ParseStatement();

Expand Down
7 changes: 4 additions & 3 deletions lib/Parse/ParseTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,8 +701,8 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
// end of the template-parameter-list rather than a greater-than
// operator.
GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
EnterExpressionEvaluationContext ConstantEvaluated(Actions,
Sema::ConstantEvaluated);
EnterExpressionEvaluationContext ConstantEvaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);

DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (DefaultArg.isInvalid())
Expand Down Expand Up @@ -1275,7 +1275,8 @@ bool Parser::IsTemplateArgumentList(unsigned Skip) {
bool
Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
// Template argument lists are constant-evaluation contexts.
EnterExpressionEvaluationContext EvalContext(Actions,Sema::ConstantEvaluated);
EnterExpressionEvaluationContext EvalContext(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ColonProtectionRAIIObject ColonProtection(*this, false);

do {
Expand Down
5 changes: 3 additions & 2 deletions lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
// Tell diagnostics how to render things from the AST library.
Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context);

ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, CleanupInfo{}, nullptr,
false);
ExprEvalContexts.emplace_back(
ExpressionEvaluationContext::PotentiallyEvaluated, 0, CleanupInfo{},
nullptr, false);

FunctionScopes.push_back(new FunctionScopeInfo(Diags));

Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10850,7 +10850,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
// Regardless, we don't want to ignore array nesting when
// constructing this copy.
if (type->isStructureOrClassType()) {
EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated);
EnterExpressionEvaluationContext scope(
*this, ExpressionEvaluationContext::PotentiallyEvaluated);
SourceLocation poi = var->getLocation();
Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi);
ExprResult result
Expand Down
9 changes: 6 additions & 3 deletions lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,8 @@ namespace { enum class IsTupleLike { TupleLike, NotTupleLike, Error }; }

static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T,
llvm::APSInt &Size) {
EnterExpressionEvaluationContext ContextRAII(S, Sema::ConstantEvaluated);
EnterExpressionEvaluationContext ContextRAII(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);

DeclarationName Value = S.PP.getIdentifierInfo("value");
LookupResult R(S, Value, Loc, Sema::LookupOrdinaryName);
Expand Down Expand Up @@ -13117,7 +13118,8 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
if (!Invalid && !ExDeclType->isDependentType()) {
if (const RecordType *recordType = ExDeclType->getAs<RecordType>()) {
// Insulate this from anything else we might currently be parsing.
EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated);
EnterExpressionEvaluationContext scope(
*this, ExpressionEvaluationContext::PotentiallyEvaluated);

// C++ [except.handle]p16:
// The object declared in an exception-declaration or, if the
Expand Down Expand Up @@ -14201,7 +14203,8 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
// new expression evaluation context that is associated with this static
// data member.
if (isStaticDataMember(D))
PushExpressionEvaluationContext(PotentiallyEvaluated, D);
PushExpressionEvaluationContext(
ExpressionEvaluationContext::PotentiallyEvaluated, D);
}

/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
Expand Down
Loading

0 comments on commit 919ac41

Please sign in to comment.