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)
inline Expr *Expr::IgnoreImpCasts() {
Expr *e = this;
- while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
+ while (true)
+ if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
+ e = ice->getSubExpr();
+ else if (ConstantExpr *ce = dyn_cast<ConstantExpr>(e))
+ e = ce->getSubExpr();
+ else
+ break;
return e;
}
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<Stmt, ConstantExpr>
+ constantExpr;
+
/// Matches parentheses used in expressions.
///
/// Example matches (foo() + 1)
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);
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)
E = NTTP->getReplacement();
continue;
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
E = NTTP->getReplacement();
continue;
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
}
break;
}
E = NTTP->getReplacement();
continue;
}
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ E = CE->getSubExpr();
+ continue;
+ }
return E;
}
}
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)
unresolvedUsingValueDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
unresolvedUsingTypenameDecl;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
cxxConstructExpr;
REGISTER_MATCHER(compoundStmt);
REGISTER_MATCHER(conditionalOperator);
REGISTER_MATCHER(constantArrayType);
+ REGISTER_MATCHER(constantExpr);
REGISTER_MATCHER(containsDeclaration);
REGISTER_MATCHER(continueStmt);
REGISTER_MATCHER(cStyleCastExpr);
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);
case Stmt::ImplicitCastExprClass:
return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc);
+ case Stmt::ConstantExprClass:
+ return VisitConstantExpr(cast<ConstantExpr>(S), asc);
+
case Stmt::IndirectGotoStmtClass:
return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
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();
E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
goto tryAgain;
+ case Stmt::ConstantExprClass:
+ E = cast<ConstantExpr>(E)->getSubExpr();
+ goto tryAgain;
+
case Stmt::ParenExprClass:
E = cast<ParenExpr>(E)->getSubExpr();
goto tryAgain;
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
case Expr::DeclRefExprClass:
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
+ case Expr::ConstantExprClass:
+ return EmitLValue(cast<ConstantExpr>(E)->getSubExpr());
case Expr::ParenExprClass:
return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
case Expr::GenericSelectionExprClass:
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); }
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());
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);
}
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);
return Visit(base.get<const Expr*>());
}
+ConstantLValue
+ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) {
+ return Visit(E->getSubExpr());
+}
+
ConstantLValue
ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);
}
Value *VisitExpr(Expr *S);
+ Value *VisitConstantExpr(ConstantExpr *E) {
+ return Visit(E->getSubExpr());
+ }
Value *VisitParenExpr(ParenExpr *PE) {
return Visit(PE->getSubExpr());
}
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
? 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
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
if (Result)
*Result = E->EvaluateKnownConstIntCheckOverflow(Context);
- return E;
+ return new (Context) ConstantExpr(E);
}
Expr::EvalResult EvalResult;
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
if (Result)
*Result = EvalResult.Val.getInt();
- return E;
+ return new (Context) ConstantExpr(E);
}
namespace {
return new (Context)
ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
-}
\ No newline at end of file
+}
// 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<CompoundLiteralExpr>(Initializer->IgnoreParens()) &&
+ (isa<ConstantExpr>(Initializer->IgnoreParens()) ||
+ isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) &&
Initializer->getType()->isArrayType()) {
const ArrayType *SourceAT
= Context.getAsArrayType(Initializer->getType());
if (Notes.empty()) {
// It's a constant expression.
- return Result;
+ return new (S.Context) ConstantExpr(Result.get());
}
}
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);
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");
case Stmt::ObjCPropertyRefExprClass:
llvm_unreachable("These are handled by PseudoObjectExpr");
- case Expr::ConstantExprClass:
- return Visit(cast<ConstantExpr>(S)->getSubExpr(), Pred, DstTop);
-
case Stmt::GNUNullExprClass: {
// GNU __null is a pointer-width integer, not an actual pointer.
ProgramStateRef state = Pred->getState();
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;
// 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
// 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
int TestAlignedExpr __attribute__((aligned(4)));\r
// CHECK: VarDecl{{.*}}TestAlignedExpr\r
// CHECK-NEXT: AlignedAttr {{.*}} aligned\r
-// CHECK-NEXT: IntegerLiteral\r
+// CHECK-NEXT: ConstantExpr\r
+// CHECK-NEXT: IntegerLiteral\r
\r
int TestEnum __attribute__((visibility("default")));\r
// CHECK: VarDecl{{.*}}TestEnum\r
// CHECK-NEXT: FieldDecl{{.*}}Test6\r
// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" ""\r
// CHECK-NEXT: FieldDecl{{.*}}Test7\r
-// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12\r
+// CHECK-NEXT: Constant{{.*}}'int'\r
+// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12\r
// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" ""\r
\r
struct [[deprecated]] Test8;\r
//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]]>{{$}}
};
// CHECK: EnumConstantDecl{{.*}} TestEnumConstantDecl 'int'
// CHECK: EnumConstantDecl{{.*}} TestEnumConstantDeclInit 'int'
-// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: ConstantExpr
+// CHECK-NEXT: IntegerLiteral
struct testIndirectFieldDecl {
struct {
};
// 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;
// CHECK-NEXT: FunctionTemplateDecl\r
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I\r
// CHECK-NEXT: TemplateArgument expr\r
-// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1\r
+// CHECK-NEXT: ConstantExpr{{.*}} 'int'\r
+// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1\r
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J\r
\r
namespace TestTemplateTemplateParmDecl {\r
~HasCtorDtor();\r
};\r
\r
+ POD p = (POD){1, 2};\r
+ // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'\r
+ // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD'\r
+ // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD'\r
+ // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD'\r
+ // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}\r
+ // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}\r
+\r
void test() {\r
(void)(POD){1, 2};\r
// CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'\r
+ // CHECK-NOT: ConstantExpr {{.*}} 'brace_initializers::POD'\r
// CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD'\r
// CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD'\r
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}\r
#if __cplusplus >= 201103L\r
(void)(HasCtor){1, 2};\r
// CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtor'\r
+ // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtor'\r
// CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor'\r
// CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtor'\r
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}\r
\r
(void)(HasCtorDtor){1, 2};\r
// CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtorDtor'\r
- // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor'\r
+ // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'brace_initializers::HasCtorDtor'\r
+ // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor'\r
// CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtorDtor'\r
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}\r
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}\r
// 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
if (!Imported)
return testing::AssertionFailure() << "Import failed, nullptr returned!";
+
return Verifier.match(Imported, WrapperMatcher);
}
EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2));
}
-
TEST_P(ImportExpr, ImportStringLiteral) {
MatchVerifier<Decl> Verifier;
testImport(
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<Decl> Verifier;
// __func__ expands as StringLiteral("declToImport")
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)))))
)))));
}
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"))),