@@ -113,7 +113,7 @@ struct UnqualNameVisitor : public RecursiveASTVisitor<UnqualNameVisitor> {
113
113
};
114
114
} // namespace
115
115
116
- constexpr llvm::StringLiteral Message =
116
+ constexpr llvm::StringLiteral ErrorMessageOnFunction =
117
117
" use a trailing return type for this function" ;
118
118
119
119
static SourceLocation expandIfMacroId (SourceLocation Loc,
@@ -125,7 +125,7 @@ static SourceLocation expandIfMacroId(SourceLocation Loc,
125
125
return Loc;
126
126
}
127
127
128
- SourceLocation UseTrailingReturnTypeCheck:: findTrailingReturnTypeSourceLocation (
128
+ static SourceLocation findTrailingReturnTypeSourceLocation (
129
129
const FunctionDecl &F, const FunctionTypeLoc &FTL, const ASTContext &Ctx,
130
130
const SourceManager &SM, const LangOptions &LangOpts) {
131
131
// We start with the location of the closing parenthesis.
@@ -217,10 +217,11 @@ classifyToken(const FunctionDecl &F, Preprocessor &PP, Token Tok) {
217
217
return CT;
218
218
}
219
219
220
- std::optional<SmallVector<ClassifiedToken, 8 >>
221
- UseTrailingReturnTypeCheck::classifyTokensBeforeFunctionName (
222
- const FunctionDecl &F, const ASTContext &Ctx, const SourceManager &SM,
223
- const LangOptions &LangOpts) {
220
+ static std::optional<SmallVector<ClassifiedToken, 8 >>
221
+ classifyTokensBeforeFunctionName (const FunctionDecl &F, const ASTContext &Ctx,
222
+ const SourceManager &SM,
223
+ const LangOptions &LangOpts,
224
+ Preprocessor *PP) {
224
225
SourceLocation BeginF = expandIfMacroId (F.getBeginLoc (), SM);
225
226
SourceLocation BeginNameF = expandIfMacroId (F.getLocation (), SM);
226
227
@@ -242,7 +243,6 @@ UseTrailingReturnTypeCheck::classifyTokensBeforeFunctionName(
242
243
const MacroInfo *MI = PP->getMacroInfo (&Info);
243
244
if (!MI || MI->isFunctionLike ()) {
244
245
// Cannot handle function style macros.
245
- diag (F.getLocation (), Message);
246
246
return std::nullopt;
247
247
}
248
248
}
@@ -253,10 +253,8 @@ UseTrailingReturnTypeCheck::classifyTokensBeforeFunctionName(
253
253
254
254
if (std::optional<ClassifiedToken> CT = classifyToken (F, *PP, T))
255
255
ClassifiedTokens.push_back (*CT);
256
- else {
257
- diag (F.getLocation (), Message);
256
+ else
258
257
return std::nullopt;
259
- }
260
258
}
261
259
262
260
return ClassifiedTokens;
@@ -273,17 +271,17 @@ static bool hasAnyNestedLocalQualifiers(QualType Type) {
273
271
return Result;
274
272
}
275
273
276
- SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange (
277
- const FunctionDecl &F, const TypeLoc &ReturnLoc, const ASTContext &Ctx,
278
- const SourceManager &SM, const LangOptions &LangOpts) {
274
+ static SourceRange
275
+ findReturnTypeAndCVSourceRange (const FunctionDecl &F, const TypeLoc &ReturnLoc,
276
+ const ASTContext &Ctx, const SourceManager &SM,
277
+ const LangOptions &LangOpts, Preprocessor *PP) {
279
278
280
279
// We start with the range of the return type and expand to neighboring
281
280
// qualifiers (const, volatile and restrict).
282
281
SourceRange ReturnTypeRange = F.getReturnTypeSourceRange ();
283
282
if (ReturnTypeRange.isInvalid ()) {
284
283
// Happens if e.g. clang cannot resolve all includes and the return type is
285
284
// unknown.
286
- diag (F.getLocation (), Message);
287
285
return {};
288
286
}
289
287
@@ -294,7 +292,7 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
294
292
295
293
// Include qualifiers to the left and right of the return type.
296
294
std::optional<SmallVector<ClassifiedToken, 8 >> MaybeTokens =
297
- classifyTokensBeforeFunctionName (F, Ctx, SM, LangOpts);
295
+ classifyTokensBeforeFunctionName (F, Ctx, SM, LangOpts, PP );
298
296
if (!MaybeTokens)
299
297
return {};
300
298
const SmallVector<ClassifiedToken, 8 > &Tokens = *MaybeTokens;
@@ -331,10 +329,11 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
331
329
return ReturnTypeRange;
332
330
}
333
331
334
- void UseTrailingReturnTypeCheck::keepSpecifiers (
335
- std::string &ReturnType, std::string &Auto, SourceRange ReturnTypeCVRange,
336
- const FunctionDecl &F, const FriendDecl *Fr, const ASTContext &Ctx,
337
- const SourceManager &SM, const LangOptions &LangOpts) {
332
+ static void keepSpecifiers (std::string &ReturnType, std::string &Auto,
333
+ SourceRange ReturnTypeCVRange, const FunctionDecl &F,
334
+ const FriendDecl *Fr, const ASTContext &Ctx,
335
+ const SourceManager &SM, const LangOptions &LangOpts,
336
+ Preprocessor *PP) {
338
337
// Check if there are specifiers inside the return type. E.g. unsigned
339
338
// inline int.
340
339
const auto *M = dyn_cast<CXXMethodDecl>(&F);
@@ -346,7 +345,7 @@ void UseTrailingReturnTypeCheck::keepSpecifiers(
346
345
// Tokenize return type. If it contains macros which contain a mix of
347
346
// qualifiers, specifiers and types, give up.
348
347
std::optional<SmallVector<ClassifiedToken, 8 >> MaybeTokens =
349
- classifyTokensBeforeFunctionName (F, Ctx, SM, LangOpts);
348
+ classifyTokensBeforeFunctionName (F, Ctx, SM, LangOpts, PP );
350
349
if (!MaybeTokens)
351
350
return ;
352
351
@@ -423,7 +422,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
423
422
if (F->getDeclaredReturnType ()->isFunctionPointerType () ||
424
423
F->getDeclaredReturnType ()->isMemberFunctionPointerType () ||
425
424
F->getDeclaredReturnType ()->isMemberPointerType ()) {
426
- diag (F->getLocation (), Message );
425
+ diag (F->getLocation (), ErrorMessageOnFunction );
427
426
return ;
428
427
}
429
428
@@ -440,24 +439,26 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
440
439
// FIXME: This may happen if we have __attribute__((...)) on the function.
441
440
// We abort for now. Remove this when the function type location gets
442
441
// available in clang.
443
- diag (F->getLocation (), Message );
442
+ diag (F->getLocation (), ErrorMessageOnFunction );
444
443
return ;
445
444
}
446
445
447
446
SourceLocation InsertionLoc =
448
447
findTrailingReturnTypeSourceLocation (*F, FTL, Ctx, SM, LangOpts);
449
448
if (InsertionLoc.isInvalid ()) {
450
- diag (F->getLocation (), Message );
449
+ diag (F->getLocation (), ErrorMessageOnFunction );
451
450
return ;
452
451
}
453
452
454
453
// Using the declared return type via F->getDeclaredReturnType().getAsString()
455
454
// discards user formatting and order of const, volatile, type, whitespace,
456
455
// space before & ... .
457
- SourceRange ReturnTypeCVRange =
458
- findReturnTypeAndCVSourceRange (*F, FTL.getReturnLoc (), Ctx, SM, LangOpts);
459
- if (ReturnTypeCVRange.isInvalid ())
456
+ SourceRange ReturnTypeCVRange = findReturnTypeAndCVSourceRange (
457
+ *F, FTL.getReturnLoc (), Ctx, SM, LangOpts, PP);
458
+ if (ReturnTypeCVRange.isInvalid ()) {
459
+ diag (F->getLocation (), ErrorMessageOnFunction);
460
460
return ;
461
+ }
461
462
462
463
// Check if unqualified names in the return type conflict with other entities
463
464
// after the rewrite.
@@ -470,7 +471,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
470
471
UnqualNameVisitor UNV{*F};
471
472
UNV.TraverseTypeLoc (FTL.getReturnLoc ());
472
473
if (UNV.Collision ) {
473
- diag (F->getLocation (), Message );
474
+ diag (F->getLocation (), ErrorMessageOnFunction );
474
475
return ;
475
476
}
476
477
@@ -486,10 +487,10 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
486
487
std::string Auto = NeedSpaceAfterAuto ? " auto " : " auto" ;
487
488
std::string ReturnType =
488
489
std::string (tooling::fixit::getText (ReturnTypeCVRange, Ctx));
489
- keepSpecifiers (ReturnType, Auto, ReturnTypeCVRange, *F, Fr, Ctx, SM,
490
- LangOpts );
490
+ keepSpecifiers (ReturnType, Auto, ReturnTypeCVRange, *F, Fr, Ctx, SM, LangOpts,
491
+ PP );
491
492
492
- diag (F->getLocation (), Message )
493
+ diag (F->getLocation (), ErrorMessageOnFunction )
493
494
<< FixItHint::CreateReplacement (ReturnTypeCVRange, Auto)
494
495
<< FixItHint::CreateInsertion (InsertionLoc, " -> " + ReturnType);
495
496
}
0 commit comments