@@ -281,49 +281,67 @@ 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 (auto *E : llvm::reverse (CE.arguments ())) {
297+ if (isa<CXXDefaultArgExpr>(E))
298+ continue ;
299+ return Lexer::getLocForEndOfToken (E->getEndLoc (), 0 , SM, LangOpts);
300+ }
301+ return {};
302+ }
303+
304+ // Returns the range of the source between the call's parentheses/braces.
305+ CharSourceRange getCallArgumentsRange (const MatchResult &Result,
306+ const CallExpr &CE) {
307+ const SourceLocation RLoc = CE.getRParenLoc ();
312308 return CharSourceRange::getCharRange (
313309 findArgStartDelimiter (CE, RLoc, *Result.SourceManager ,
314310 Result.Context ->getLangOpts ())
315311 .getLocWithOffset (1 ),
316312 RLoc);
317313}
314+
315+ // Returns the range of the source between the construct expr's
316+ // parentheses/braces.
317+ CharSourceRange getConstructArgumentsRange (const MatchResult &Result,
318+ const CXXConstructExpr &CE) {
319+ if (SourceRange R = CE.getParenOrBraceRange (); R.isValid ()) {
320+ return CharSourceRange::getCharRange (
321+ Lexer::getLocForEndOfToken (R.getBegin (), 0 , *Result.SourceManager ,
322+ Result.Context ->getLangOpts ()),
323+ R.getEnd ());
324+ }
325+
326+ if (CE.getNumArgs () > 0 ) {
327+ return CharSourceRange::getCharRange (
328+ CE.getArg (0 )->getBeginLoc (),
329+ findLastArgEnd (CE, *Result.SourceManager ,
330+ Result.Context ->getLangOpts ()));
331+ }
332+
333+ return {};
334+ }
335+
318336} // namespace
319337
320338RangeSelector transformer::callArgs (std::string ID) {
321- return RelativeSelector<CallExpr, getArgumentsRange<CallExpr> >(std::move (ID));
339+ return RelativeSelector<CallExpr, getCallArgumentsRange >(std::move (ID));
322340}
323341
324342RangeSelector transformer::constructExprArgs (std::string ID) {
325- return RelativeSelector<CXXConstructExpr,
326- getArgumentsRange<CXXConstructExpr>>( std::move (ID));
343+ return RelativeSelector<CXXConstructExpr, getConstructArgumentsRange>(
344+ std::move (ID));
327345}
328346
329347namespace {
0 commit comments