@@ -281,49 +281,68 @@ RangeSelector transformer::statements(std::string ID) {
281
281
282
282
namespace {
283
283
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,
301
285
const SourceManager &SM,
302
286
const LangOptions &LangOpts) {
303
287
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 );
305
289
}
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 ();
312
309
return CharSourceRange::getCharRange (
313
310
findArgStartDelimiter (CE, RLoc, *Result.SourceManager ,
314
311
Result.Context ->getLangOpts ())
315
312
.getLocWithOffset (1 ),
316
313
RLoc);
317
314
}
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
+
318
337
} // namespace
319
338
320
339
RangeSelector transformer::callArgs (std::string ID) {
321
- return RelativeSelector<CallExpr, getArgumentsRange<CallExpr> >(std::move (ID));
340
+ return RelativeSelector<CallExpr, getCallArgumentsRange >(std::move (ID));
322
341
}
323
342
324
343
RangeSelector transformer::constructExprArgs (std::string ID) {
325
- return RelativeSelector<CXXConstructExpr,
326
- getArgumentsRange<CXXConstructExpr>>( std::move (ID));
344
+ return RelativeSelector<CXXConstructExpr, getConstructArgumentsRange>(
345
+ std::move (ID));
327
346
}
328
347
329
348
namespace {
0 commit comments