@@ -281,49 +281,68 @@ RangeSelector transformer::statements(std::string ID) {
281281
282282namespace {
283283
284- SourceLocation getRLoc (const CallExpr &E) { return E.getRParenLoc (); }
285-
286- SourceLocation getRLoc (const CXXConstructExpr &E) {
287- return E.getParenOrBraceRange ().getEnd ();
288- }
289-
290- tok::TokenKind getStartToken (const CallExpr &E) {
291- return tok::TokenKind::l_paren;
292- }
293-
294- tok::TokenKind getStartToken (const CXXConstructExpr &E) {
295- return isa<CXXTemporaryObjectExpr>(E) ? tok::TokenKind::l_paren
296- : tok::TokenKind::l_brace;
297- }
298-
299- template <typename ExprWithArgs>
300- SourceLocation findArgStartDelimiter (const ExprWithArgs &E, SourceLocation RLoc,
284+ SourceLocation findArgStartDelimiter (const CallExpr &E, SourceLocation RLoc,
301285 const SourceManager &SM,
302286 const LangOptions &LangOpts) {
303287 SourceLocation Loc = E.getNumArgs () == 0 ? RLoc : E.getArg (0 )->getBeginLoc ();
304- return findPreviousTokenKind (Loc, SM, LangOpts, getStartToken (E) );
288+ return findPreviousTokenKind (Loc, SM, LangOpts, tok::TokenKind::l_paren );
305289}
306- // Returns the range of the source between the call's or construct expr's
307- // parentheses/braces.
308- template <typename ExprWithArgs>
309- CharSourceRange getArgumentsRange (const MatchResult &Result,
310- const ExprWithArgs &CE) {
311- const SourceLocation RLoc = getRLoc (CE);
290+
291+ // Returns the location after the last argument of the construct expr. Returns
292+ // an invalid location if there are no arguments.
293+ SourceLocation findLastArgEnd (const CXXConstructExpr &CE,
294+ const SourceManager &SM,
295+ const LangOptions &LangOpts) {
296+ for (int i = CE.getNumArgs () - 1 ; i >= 0 ; --i) {
297+ const Expr *Arg = CE.getArg (i);
298+ if (isa<CXXDefaultArgExpr>(Arg))
299+ continue ;
300+ return Lexer::getLocForEndOfToken (Arg->getEndLoc (), 0 , SM, LangOpts);
301+ }
302+ return {};
303+ }
304+
305+ // Returns the range of the source between the call's parentheses/braces.
306+ CharSourceRange getCallArgumentsRange (const MatchResult &Result,
307+ const CallExpr &CE) {
308+ const SourceLocation RLoc = CE.getRParenLoc ();
312309 return CharSourceRange::getCharRange (
313310 findArgStartDelimiter (CE, RLoc, *Result.SourceManager ,
314311 Result.Context ->getLangOpts ())
315312 .getLocWithOffset (1 ),
316313 RLoc);
317314}
315+
316+ // Returns the range of the source between the construct expr's
317+ // parentheses/braces.
318+ CharSourceRange getConstructArgumentsRange (const MatchResult &Result,
319+ const CXXConstructExpr &CE) {
320+ if (SourceRange R = CE.getParenOrBraceRange (); R.isValid ()) {
321+ return CharSourceRange::getCharRange (
322+ Lexer::getLocForEndOfToken (R.getBegin (), 0 , *Result.SourceManager ,
323+ Result.Context ->getLangOpts ()),
324+ R.getEnd ());
325+ }
326+
327+ if (CE.getNumArgs () > 0 ) {
328+ return CharSourceRange::getCharRange (
329+ CE.getArg (0 )->getBeginLoc (),
330+ findLastArgEnd (CE, *Result.SourceManager ,
331+ Result.Context ->getLangOpts ()));
332+ }
333+
334+ return {};
335+ }
336+
318337} // namespace
319338
320339RangeSelector transformer::callArgs (std::string ID) {
321- return RelativeSelector<CallExpr, getArgumentsRange<CallExpr> >(std::move (ID));
340+ return RelativeSelector<CallExpr, getCallArgumentsRange >(std::move (ID));
322341}
323342
324343RangeSelector transformer::constructExprArgs (std::string ID) {
325- return RelativeSelector<CXXConstructExpr,
326- getArgumentsRange<CXXConstructExpr>>( std::move (ID));
344+ return RelativeSelector<CXXConstructExpr, getConstructArgumentsRange>(
345+ std::move (ID));
327346}
328347
329348namespace {
0 commit comments