Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -3024,8 +3024,7 @@ private: ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, unsigned BasePathLength, ExprValueKind VK) - : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { - } + : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { } /// Construct an empty implicit cast. explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize) @@ -3068,8 +3067,13 @@ inline Expr *Expr::IgnoreImpCasts() { Expr *e = this; - while (ImplicitCastExpr *ice = dyn_cast(e)) - e = ice->getSubExpr(); + while (true) + if (ImplicitCastExpr *ice = dyn_cast(e)) + e = ice->getSubExpr(); + else if (ConstantExpr *ce = dyn_cast(e)) + e = ce->getSubExpr(); + else + break; return e; } Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -1574,6 +1574,18 @@ UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; +/// Matches a constant expression wrapper. +/// +/// Example matches the constant in the case statement: +/// (matcher = constantExpr()) +/// \code +/// switch (a) { +/// case 37: break; +/// } +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher + constantExpr; + /// Matches parentheses used in expressions. /// /// Example matches (foo() + 1) Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -579,6 +579,7 @@ ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E); ExpectedStmt VisitAtomicExpr(AtomicExpr *E); ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E); + ExpectedStmt VisitConstantExpr(ConstantExpr *E); ExpectedStmt VisitParenExpr(ParenExpr *E); ExpectedStmt VisitParenListExpr(ParenListExpr *E); ExpectedStmt VisitStmtExpr(StmtExpr *E); @@ -6362,6 +6363,17 @@ ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType); } +ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) { + auto Imp = importSeq(E->getSubExpr()); + if (!Imp) + return Imp.takeError(); + + Expr *ToSubExpr; + std::tie(ToSubExpr) = *Imp; + + return new (Importer.getToContext()) ConstantExpr(ToSubExpr); +} + ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) { auto Imp = importSeq(E->getLParen(), E->getRParen(), E->getSubExpr()); if (!Imp) Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -2590,6 +2590,10 @@ E = NTTP->getReplacement(); continue; } + if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); + continue; + } return E; } } @@ -2611,6 +2615,10 @@ E = NTTP->getReplacement(); continue; } + if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); + continue; + } return E; } } @@ -2636,6 +2644,9 @@ = dyn_cast(E)) { E = NTTP->getReplacement(); continue; + } else if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); + continue; } break; } @@ -2677,6 +2688,10 @@ E = NTTP->getReplacement(); continue; } + if (ConstantExpr *CE = dyn_cast(E)) { + E = CE->getSubExpr(); + continue; + } return E; } } Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -4718,6 +4718,8 @@ return Error(E); } + bool VisitConstantExpr(const ConstantExpr *E) + { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitParenExpr(const ParenExpr *E) { return StmtVisitorTy::Visit(E->getSubExpr()); } bool VisitUnaryExtension(const UnaryOperator *E) Index: lib/ASTMatchers/ASTMatchersInternal.cpp =================================================================== --- lib/ASTMatchers/ASTMatchersInternal.cpp +++ lib/ASTMatchers/ASTMatchersInternal.cpp @@ -666,6 +666,7 @@ unresolvedUsingValueDecl; const internal::VariadicDynCastAllOfMatcher unresolvedUsingTypenameDecl; +const internal::VariadicDynCastAllOfMatcher constantExpr; const internal::VariadicDynCastAllOfMatcher parenExpr; const internal::VariadicDynCastAllOfMatcher cxxConstructExpr; Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -153,6 +153,7 @@ REGISTER_MATCHER(compoundStmt); REGISTER_MATCHER(conditionalOperator); REGISTER_MATCHER(constantArrayType); + REGISTER_MATCHER(constantExpr); REGISTER_MATCHER(containsDeclaration); REGISTER_MATCHER(continueStmt); REGISTER_MATCHER(cStyleCastExpr); @@ -433,6 +434,7 @@ REGISTER_MATCHER(onImplicitObjectArgument); REGISTER_MATCHER(opaqueValueExpr); REGISTER_MATCHER(parameterCountIs); + REGISTER_MATCHER(constantExpr); REGISTER_MATCHER(parenExpr); REGISTER_MATCHER(parenListExpr); REGISTER_MATCHER(parenType); Index: lib/Analysis/CFG.cpp =================================================================== --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -551,6 +551,7 @@ CFGBlock *VisitGotoStmt(GotoStmt *G); CFGBlock *VisitIfStmt(IfStmt *I); CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc); + CFGBlock *VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc); CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I); CFGBlock *VisitLabelStmt(LabelStmt *L); CFGBlock *VisitBlockExpr(BlockExpr *E, AddStmtChoice asc); @@ -2099,6 +2100,9 @@ case Stmt::ImplicitCastExprClass: return VisitImplicitCastExpr(cast(S), asc); + case Stmt::ConstantExprClass: + return VisitConstantExpr(cast(S), asc); + case Stmt::IndirectGotoStmtClass: return VisitIndirectGotoStmt(cast(S)); @@ -4376,6 +4380,10 @@ return Visit(E->getSubExpr(), AddStmtChoice()); } +CFGBlock *CFGBuilder::VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc) { + return Visit(E->getSubExpr(), AddStmtChoice()); +} + CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { // Lazily create the indirect-goto dispatch block if there isn't one already. CFGBlock *IBlock = cfg->getIndirectGotoBlock(); @@ -4432,6 +4440,10 @@ E = cast(E)->getSubExpr(); goto tryAgain; + case Stmt::ConstantExprClass: + E = cast(E)->getSubExpr(); + goto tryAgain; + case Stmt::ParenExprClass: E = cast(E)->getSubExpr(); goto tryAgain; Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1260,6 +1260,8 @@ return EmitVAArgExprLValue(cast(E)); case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast(E)); + case Expr::ConstantExprClass: + return EmitLValue(cast(E)->getSubExpr()); case Expr::ParenExprClass: return EmitLValue(cast(E)->getSubExpr()); case Expr::GenericSelectionExprClass: Index: lib/CodeGen/CGExprAgg.cpp =================================================================== --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -125,6 +125,10 @@ return Visit(E->getReplacement()); } + void VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } + // l-values. void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); } void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); } Index: lib/CodeGen/CGExprComplex.cpp =================================================================== --- lib/CodeGen/CGExprComplex.cpp +++ lib/CodeGen/CGExprComplex.cpp @@ -101,6 +101,9 @@ llvm_unreachable("Stmt can't have complex result type!"); } ComplexPairTy VisitExpr(Expr *S); + ComplexPairTy VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { return Visit(GE->getResultExpr()); Index: lib/CodeGen/CGExprConstant.cpp =================================================================== --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -723,6 +723,10 @@ return nullptr; } + llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) { + return Visit(CE->getSubExpr(), T); + } + llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) { return Visit(PE->getSubExpr(), T); } @@ -1601,6 +1605,7 @@ ConstantLValue tryEmitBase(const APValue::LValueBase &base); ConstantLValue VisitStmt(const Stmt *S) { return nullptr; } + ConstantLValue VisitConstantExpr(const ConstantExpr *E); ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); ConstantLValue VisitStringLiteral(const StringLiteral *E); ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E); @@ -1755,6 +1760,11 @@ return Visit(base.get()); } +ConstantLValue +ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) { + return Visit(E->getSubExpr()); +} + ConstantLValue ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E); Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -398,6 +398,9 @@ } Value *VisitExpr(Expr *S); + Value *VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -16417,9 +16417,7 @@ // Null EnumConstantDecl means a previous diagnostic has been emitted for // this constant. Skip this enum since it may be ill-formed. - if (!ECD) { - return; - } + if (!ECD) return; // Constants with initalizers are handled in the next loop. if (ECD->getInitExpr()) Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -5745,21 +5745,6 @@ LiteralExpr = Result.get(); bool isFileScope = !CurContext->isFunctionOrMethod(); - if (isFileScope) { - if (!LiteralExpr->isTypeDependent() && - !LiteralExpr->isValueDependent() && - !literalType->isDependentType()) // C99 6.5.2.5p3 - if (CheckForConstantInitializer(LiteralExpr, literalType)) - return ExprError(); - } else if (literalType.getAddressSpace() != LangAS::opencl_private && - literalType.getAddressSpace() != LangAS::Default) { - // Embedded-C extensions to C99 6.5.2.5: - // "If the compound literal occurs inside the body of a function, the - // type name shall not be qualified by an address-space qualifier." - Diag(LParenLoc, diag::err_compound_literal_with_address_space) - << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); - return ExprError(); - } // In C, compound literals are l-values for some reason. // For GCC compatibility, in C++, file-scope array compound literals with @@ -5784,9 +5769,26 @@ ? VK_RValue : VK_LValue; - return MaybeBindToTemporary( - new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - VK, LiteralExpr, isFileScope)); + Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + VK, LiteralExpr, isFileScope); + if (isFileScope) { + if (!LiteralExpr->isTypeDependent() && + !LiteralExpr->isValueDependent() && + !literalType->isDependentType()) // C99 6.5.2.5p3 + if (CheckForConstantInitializer(LiteralExpr, literalType)) + return ExprError(); + E = new (Context) ConstantExpr(E); + } else if (literalType.getAddressSpace() != LangAS::opencl_private && + literalType.getAddressSpace() != LangAS::Default) { + // Embedded-C extensions to C99 6.5.2.5: + // "If the compound literal occurs inside the body of a function, the + // type name shall not be qualified by an address-space qualifier." + Diag(LParenLoc, diag::err_compound_literal_with_address_space) + << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); + return ExprError(); + } + + return MaybeBindToTemporary(E); } ExprResult @@ -14144,7 +14146,7 @@ if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) *Result = E->EvaluateKnownConstIntCheckOverflow(Context); - return E; + return new (Context) ConstantExpr(E); } Expr::EvalResult EvalResult; @@ -14162,7 +14164,7 @@ if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) { if (Result) *Result = EvalResult.Val.getInt(); - return E; + return new (Context) ConstantExpr(E); } // If our only note is the usual "invalid subexpression" note, just point @@ -14190,7 +14192,7 @@ if (Result) *Result = EvalResult.Val.getInt(); - return E; + return new (Context) ConstantExpr(E); } namespace { @@ -16631,4 +16633,4 @@ return new (Context) ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy); -} \ No newline at end of file +} Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -5503,7 +5503,8 @@ // array from a compound literal that creates an array of the same // type, so long as the initializer has no side effects. if (!S.getLangOpts().CPlusPlus && Initializer && - isa(Initializer->IgnoreParens()) && + (isa(Initializer->IgnoreParens()) || + isa(Initializer->IgnoreParens())) && Initializer->getType()->isArrayType()) { const ArrayType *SourceAT = Context.getAsArrayType(Initializer->getType()); Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5444,7 +5444,7 @@ if (Notes.empty()) { // It's a constant expression. - return Result; + return new (S.Context) ConstantExpr(Result.get()); } } Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -2233,6 +2233,10 @@ T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); } + if (ArraySize && !CurContext->isFunctionOrMethod()) + // A file-scoped array must have a constant array size. + ArraySize = new (Context) ConstantExpr(ArraySize); + // OpenCL v1.2 s6.9.d: variable length arrays are not supported. if (getLangOpts().OpenCL && T->isVariableArrayType()) { Diag(Loc, diag::err_opencl_vla); Index: lib/StaticAnalyzer/Core/Environment.cpp =================================================================== --- lib/StaticAnalyzer/Core/Environment.cpp +++ lib/StaticAnalyzer/Core/Environment.cpp @@ -92,6 +92,7 @@ case Stmt::ExprWithCleanupsClass: case Stmt::GenericSelectionExprClass: case Stmt::OpaqueValueExprClass: + case Stmt::ConstantExprClass: case Stmt::ParenExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: llvm_unreachable("Should have been handled by ignoreTransparentExprs"); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1267,9 +1267,6 @@ case Stmt::ObjCPropertyRefExprClass: llvm_unreachable("These are handled by PseudoObjectExpr"); - case Expr::ConstantExprClass: - return Visit(cast(S)->getSubExpr(), Pred, DstTop); - case Stmt::GNUNullExprClass: { // GNU __null is a pointer-width integer, not an actual pointer. ProgramStateRef state = Pred->getState(); @@ -1285,6 +1282,10 @@ Bldr.addNodes(Dst); break; + case Expr::ConstantExprClass: + // Handled due to it being a wrapper class. + break; + case Stmt::ExprWithCleanupsClass: // Handled due to fully linearised CFG. break; Index: test/Import/switch-stmt/test.cpp =================================================================== --- test/Import/switch-stmt/test.cpp +++ test/Import/switch-stmt/test.cpp @@ -4,15 +4,21 @@ // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt @@ -23,13 +29,17 @@ // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt Index: test/Misc/ast-dump-attr.cpp =================================================================== --- test/Misc/ast-dump-attr.cpp +++ test/Misc/ast-dump-attr.cpp @@ -35,7 +35,8 @@ int TestAlignedExpr __attribute__((aligned(4))); // CHECK: VarDecl{{.*}}TestAlignedExpr // CHECK-NEXT: AlignedAttr {{.*}} aligned -// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral int TestEnum __attribute__((visibility("default"))); // CHECK: VarDecl{{.*}}TestEnum Index: test/Misc/ast-dump-c-attr.c =================================================================== --- test/Misc/ast-dump-c-attr.c +++ test/Misc/ast-dump-c-attr.c @@ -23,7 +23,8 @@ // CHECK-NEXT: FieldDecl{{.*}}Test6 // CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} "Frobble" "" // CHECK-NEXT: FieldDecl{{.*}}Test7 -// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12 +// CHECK-NEXT: Constant{{.*}}'int' +// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12 // CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} "" "" struct [[deprecated]] Test8; Index: test/Misc/ast-dump-color.cpp =================================================================== --- test/Misc/ast-dump-color.cpp +++ test/Misc/ast-dump-color.cpp @@ -49,12 +49,14 @@ //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} Index: test/Misc/ast-dump-decl.c =================================================================== --- test/Misc/ast-dump-decl.c +++ test/Misc/ast-dump-decl.c @@ -96,7 +96,8 @@ }; // CHECK: EnumConstantDecl{{.*}} TestEnumConstantDecl 'int' // CHECK: EnumConstantDecl{{.*}} TestEnumConstantDeclInit 'int' -// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral struct testIndirectFieldDecl { struct { @@ -140,7 +141,8 @@ }; // CHECK: FieldDecl{{.*}} TestFieldDecl 'int' // CHECK: FieldDecl{{.*}} TestFieldDeclWidth 'int' -// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral // CHECK-MODULE: FieldDecl{{.*}} TestFieldDeclPrivate 'int' __module_private__ int TestVarDecl; Index: test/Misc/ast-dump-decl.cpp =================================================================== --- test/Misc/ast-dump-decl.cpp +++ test/Misc/ast-dump-decl.cpp @@ -381,7 +381,8 @@ // CHECK-NEXT: FunctionTemplateDecl // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I // CHECK-NEXT: TemplateArgument expr -// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 +// CHECK-NEXT: ConstantExpr{{.*}} 'int' +// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J namespace TestTemplateTemplateParmDecl { Index: test/SemaCXX/compound-literal.cpp =================================================================== --- test/SemaCXX/compound-literal.cpp +++ test/SemaCXX/compound-literal.cpp @@ -34,9 +34,18 @@ ~HasCtorDtor(); }; + POD p = (POD){1, 2}; + // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' + // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} + void test() { (void)(POD){1, 2}; // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' + // CHECK-NOT: ConstantExpr {{.*}} 'brace_initializers::POD' // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} @@ -52,6 +61,7 @@ #if __cplusplus >= 201103L (void)(HasCtor){1, 2}; // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtor' + // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtor' // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} @@ -59,7 +69,8 @@ (void)(HasCtorDtor){1, 2}; // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtorDtor' - // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor' + // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtorDtor' + // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtorDtor' // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} Index: test/Tooling/clang-check-ast-dump.cpp =================================================================== --- test/Tooling/clang-check-ast-dump.cpp +++ test/Tooling/clang-check-ast-dump.cpp @@ -32,7 +32,8 @@ // CHECK-ATTR: test_namespace // CHECK-ATTR-NEXT: FieldDecl{{.*}}n // CHECK-ATTR-NEXT: AlignedAttr -// CHECK-ATTR-NEXT: BinaryOperator +// CHECK-ATTR-NEXT: ConstantExpr +// CHECK-ATTR-NEXT: BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s // CHECK-AFTER-NULL: class AfterNullNode Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -140,6 +140,7 @@ if (!Imported) return testing::AssertionFailure() << "Import failed, nullptr returned!"; + return Verifier.match(Imported, WrapperMatcher); } @@ -502,7 +503,6 @@ EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2)); } - TEST_P(ImportExpr, ImportStringLiteral) { MatchVerifier Verifier; testImport( @@ -719,19 +719,18 @@ initListExpr( has(designatedInitExpr( designatorCountIs(2), - has(floatLiteral(equals(1.0))), - has(integerLiteral(equals(2))))), + hasDescendant(floatLiteral(equals(1.0))), + hasDescendant(integerLiteral(equals(2))))), has(designatedInitExpr( designatorCountIs(2), - has(floatLiteral(equals(2.0))), - has(integerLiteral(equals(2))))), + hasDescendant(floatLiteral(equals(2.0))), + hasDescendant(integerLiteral(equals(2))))), has(designatedInitExpr( designatorCountIs(2), - has(floatLiteral(equals(1.0))), - has(integerLiteral(equals(0))))))))); + hasDescendant(floatLiteral(equals(1.0))), + hasDescendant(integerLiteral(equals(0))))))))); } - TEST_P(ImportExpr, ImportPredefinedExpr) { MatchVerifier Verifier; // __func__ expands as StringLiteral("declToImport") Index: unittests/ASTMatchers/ASTMatchersNodeTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -760,23 +760,23 @@ has( designatedInitExpr( designatorCountIs(2), - has(floatLiteral( + hasDescendant(floatLiteral( equals(1.0))), - has(integerLiteral( + hasDescendant(integerLiteral( equals(2))))), has( designatedInitExpr( designatorCountIs(2), - has(floatLiteral( + hasDescendant(floatLiteral( equals(2.0))), - has(integerLiteral( + hasDescendant(integerLiteral( equals(2))))), has( designatedInitExpr( designatorCountIs(2), - has(floatLiteral( + hasDescendant(floatLiteral( equals(1.0))), - has(integerLiteral( + hasDescendant(integerLiteral( equals(0))))) ))))); } Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1574,13 +1574,16 @@ ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt())))))); EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }", switchStmt(forEachSwitchCase( - caseStmt(hasCaseConstant(integerLiteral())))))); + caseStmt(hasCaseConstant( + constantExpr(has(integerLiteral())))))))); EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }", switchStmt(forEachSwitchCase( - caseStmt(hasCaseConstant(integerLiteral())))))); + caseStmt(hasCaseConstant( + constantExpr(has(integerLiteral())))))))); EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }", switchStmt(forEachSwitchCase( - caseStmt(hasCaseConstant(integerLiteral())))))); + caseStmt(hasCaseConstant( + constantExpr(has(integerLiteral())))))))); EXPECT_TRUE(matchAndVerifyResultTrue( "void x() { switch (42) { case 1: case 2: case 3: default:; } }", switchStmt(forEachSwitchCase(caseStmt().bind("x"))),