ANNOTATION(non_type_dependent) // annotation for an assumed non-type member of
// a dependent base class
ANNOTATION(primary_expr) // annotation for a primary expression
+ANNOTATION(
+ uneval_primary_expr) // annotation for a primary expression which should be
+ // transformed to potentially evaluated
ANNOTATION(decltype) // annotation for a decltype expression,
// e.g., "decltype(foo.bar())"
Diag(Tok, diag::warn_cxx98_compat_nullptr);
return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
+ case tok::annot_uneval_primary_expr:
case tok::annot_primary_expr:
Res = getExprAnnotation(Tok);
+ if (SavedKind == tok::annot_uneval_primary_expr) {
+ if (Expr *E = Res.get()) {
+ if (!E->isTypeDependent() && !E->containsErrors()) {
+ // TransformToPotentiallyEvaluated expects that it will still be in a
+ // (temporary) unevaluated context and then looks through that context
+ // to build it in the surrounding context. So we need to push an
+ // unevaluated context to balance things out.
+ EnterExpressionEvaluationContext Unevaluated(
+ Actions, Sema::ExpressionEvaluationContext::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
+ Res = Actions.TransformToPotentiallyEvaluated(Res.get());
+ }
+ }
+ }
ConsumeAnnotationToken();
if (!Res.isInvalid() && Tok.is(tok::less))
checkPotentialAngleBracket(Res);
// this is ambiguous. Typo-correct to type and expression keywords and
// to types and identifiers, in order to try to recover from errors.
TentativeParseCCC CCC(Next);
+ // Tentative parsing may not be done in the right evaluation context
+ // for the ultimate expression. Enter an unevaluated context to prevent
+ // Sema from immediately e.g. treating this lookup as a potential ODR-use.
+ // If we generate an expression annotation token and the parser actually
+ // claims it as an expression, we'll transform the expression to a
+ // potentially-evaluated one then.
+ EnterExpressionEvaluationContext Unevaluated(
+ Actions, Sema::ExpressionEvaluationContext::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
switch (TryAnnotateName(&CCC)) {
case ANK_Error:
return TPResult::Error;
}
case Sema::NC_ContextIndependentExpr:
- Tok.setKind(tok::annot_primary_expr);
+ Tok.setKind(Actions.isUnevaluatedContext() ? tok::annot_uneval_primary_expr
+ : tok::annot_primary_expr);
setExprAnnotation(Tok, Classification.getExpression());
Tok.setAnnotationEndLoc(NameLoc);
if (SS.isNotEmpty())
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only %s -ast-dump | FileCheck %s
+
+struct FOO {
+ static const int vec_align_bytes = 32;
+ void foo() {
+ double a alignas(vec_align_bytes);
+ ;
+ }
+};
+
+// CHECK: AlignedAttr {{.*}} alignas
+// CHECK: ConstantExpr {{.+}} 'int' Int: 32
+// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue>
+// CHECK: DeclRefExpr {{.*}} 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant
+// CHECK: NullStmt