diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3470,43 +3470,43 @@ bool isListInitialization() const { return LParenLoc.isInvalid(); } /// Retrieve the number of arguments. - unsigned arg_size() const { return CXXUnresolvedConstructExprBits.NumArgs; } + unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; } using arg_iterator = Expr **; using arg_range = llvm::iterator_range; arg_iterator arg_begin() { return getTrailingObjects(); } - arg_iterator arg_end() { return arg_begin() + arg_size(); } + arg_iterator arg_end() { return arg_begin() + getNumArgs(); } arg_range arguments() { return arg_range(arg_begin(), arg_end()); } using const_arg_iterator = const Expr* const *; using const_arg_range = llvm::iterator_range; const_arg_iterator arg_begin() const { return getTrailingObjects(); } - const_arg_iterator arg_end() const { return arg_begin() + arg_size(); } + const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); } const_arg_range arguments() const { return const_arg_range(arg_begin(), arg_end()); } Expr *getArg(unsigned I) { - assert(I < arg_size() && "Argument index out-of-range"); + assert(I < getNumArgs() && "Argument index out-of-range"); return arg_begin()[I]; } const Expr *getArg(unsigned I) const { - assert(I < arg_size() && "Argument index out-of-range"); + assert(I < getNumArgs() && "Argument index out-of-range"); return arg_begin()[I]; } void setArg(unsigned I, Expr *E) { - assert(I < arg_size() && "Argument index out-of-range"); + assert(I < getNumArgs() && "Argument index out-of-range"); arg_begin()[I] = E; } SourceLocation getBeginLoc() const LLVM_READONLY; SourceLocation getEndLoc() const LLVM_READONLY { - if (!RParenLoc.isValid() && arg_size() > 0) - return getArg(arg_size() - 1)->getEndLoc(); + if (!RParenLoc.isValid() && getNumArgs() > 0) + return getArg(getNumArgs() - 1)->getEndLoc(); return RParenLoc; } @@ -3517,13 +3517,13 @@ // Iterators child_range children() { auto **begin = reinterpret_cast(arg_begin()); - return child_range(begin, begin + arg_size()); + return child_range(begin, begin + getNumArgs()); } const_child_range children() const { auto **begin = reinterpret_cast( const_cast(this)->arg_begin()); - return const_child_range(begin, begin + arg_size()); + return const_child_range(begin, begin + getNumArgs()); } }; diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3965,9 +3965,9 @@ /// f(0, 0); /// \endcode AST_POLYMORPHIC_MATCHER_P(argumentCountIs, - AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, - CXXConstructExpr, - ObjCMessageExpr), + AST_POLYMORPHIC_SUPPORTED_TYPES( + CallExpr, CXXConstructExpr, + CXXUnresolvedConstructExpr, ObjCMessageExpr), unsigned, N) { return Node.getNumArgs() == N; } @@ -3981,9 +3981,9 @@ /// void x(int) { int y; x(y); } /// \endcode AST_POLYMORPHIC_MATCHER_P2(hasArgument, - AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, - CXXConstructExpr, - ObjCMessageExpr), + AST_POLYMORPHIC_SUPPORTED_TYPES( + CallExpr, CXXConstructExpr, + CXXUnresolvedConstructExpr, ObjCMessageExpr), unsigned, N, internal::Matcher, InnerMatcher) { return (N < Node.getNumArgs() && InnerMatcher.matches( diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -7539,7 +7539,7 @@ if (Err) return std::move(Err); - SmallVector ToArgs(E->arg_size()); + SmallVector ToArgs(E->getNumArgs()); if (Error Err = ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin())) return std::move(Err); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4175,7 +4175,7 @@ case Expr::CXXUnresolvedConstructExprClass: { const CXXUnresolvedConstructExpr *CE = cast(E); - unsigned N = CE->arg_size(); + unsigned N = CE->getNumArgs(); if (CE->isListInitialization()) { assert(N == 1 && "unexpected form for list initialization"); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12745,12 +12745,12 @@ bool ArgumentChanged = false; SmallVector Args; - Args.reserve(E->arg_size()); + Args.reserve(E->getNumArgs()); { EnterExpressionEvaluationContext Context( getSema(), EnterExpressionEvaluationContext::InitList, E->isListInitialization()); - if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args, + if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args, &ArgumentChanged)) return ExprError(); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1990,10 +1990,10 @@ void ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { VisitExpr(E); - assert(Record.peekInt() == E->arg_size() && + assert(Record.peekInt() == E->getNumArgs() && "Read wrong record during creation ?"); Record.skipInts(1); - for (unsigned I = 0, N = E->arg_size(); I != N; ++I) + for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) E->setArg(I, Record.readSubExpr()); E->TSI = readTypeSourceInfo(); E->setLParenLoc(readSourceLocation()); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1900,7 +1900,7 @@ void ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { VisitExpr(E); - Record.push_back(E->arg_size()); + Record.push_back(E->getNumArgs()); for (CXXUnresolvedConstructExpr::arg_iterator ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI) Record.AddStmt(*ArgI); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1613,6 +1613,24 @@ Constructor1Arg)); } +TEST(ASTMatchersTest, ArgumentCountIs_CXXUnresolvedConstructExpr) { + auto Code = "template struct S{}; template void " + "x() { auto s = S(); }"; + + EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(argumentCountIs(0)))); + EXPECT_TRUE(notMatches(Code, cxxUnresolvedConstructExpr(argumentCountIs(1)))); +} + +TEST(ASTMatchersTest, HasArgument_CXXUnresolvedConstructExpr) { + auto Code = "template struct S{ S(int){} }; template void x() { int y; auto s = S(y); }"; + EXPECT_TRUE(matches(Code, cxxUnresolvedConstructExpr(hasArgument( + 0, declRefExpr(to(varDecl(hasName("y")))))))); + EXPECT_TRUE( + notMatches(Code, cxxUnresolvedConstructExpr(hasArgument( + 0, declRefExpr(to(varDecl(hasName("x")))))))); +} + TEST_P(ASTMatchersTest, IsListInitialization) { if (!GetParam().isCXX11OrLater()) { return;