[AST] Fix the incorrect auto-keyword loc for constrained auto type loc.

E.g.  `Concept auto Func();`

The nameLoc for the constained auto type loc pointed to the concept name
loc, it should be the auto token loc. This patch fixes it, and remove
a relevant hack in clang-tidy check.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D117009
This commit is contained in:
Haojian Wu 2022-01-19 13:55:07 +01:00
parent 73cc8dd2d7
commit 6c78703e3a
3 changed files with 9 additions and 26 deletions

View File

@ -285,31 +285,6 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
return {};
}
// If the return type is a constrained 'auto', we need to include the token
// after the concept. Unfortunately, the source range of an AutoTypeLoc, if it
// is constrained, does not include the 'auto'.
// FIXME: fix the AutoTypeLoc location in clang.
auto ATL = ReturnLoc.getAs<AutoTypeLoc>();
if (ATL && ATL.isConstrained() && !ATL.isDecltypeAuto()) {
SourceLocation End =
expandIfMacroId(ReturnLoc.getSourceRange().getEnd(), SM);
SourceLocation BeginNameF = expandIfMacroId(F.getLocation(), SM);
// Extend the ReturnTypeRange until the last token before the function
// name.
std::pair<FileID, unsigned> Loc = SM.getDecomposedLoc(End);
StringRef File = SM.getBufferData(Loc.first);
const char *TokenBegin = File.data() + Loc.second;
Lexer Lexer(SM.getLocForStartOfFile(Loc.first), LangOpts, File.begin(),
TokenBegin, File.end());
Token T;
SourceLocation LastTLoc = End;
while (!Lexer.LexFromRawLexer(T) &&
SM.isBeforeInTranslationUnit(T.getLocation(), BeginNameF)) {
LastTLoc = T.getLocation();
}
ReturnTypeRange.setEnd(LastTLoc);
}
// If the return type has no local qualifiers, it's source range is accurate.
if (!hasAnyNestedLocalQualifiers(F.getReturnType()))

View File

@ -3582,7 +3582,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,
DiagID, TemplateId, Policy);
} else {
isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID,
isInvalid = DS.SetTypeSpecType(TST_auto, AutoLoc, PrevSpec, DiagID,
TemplateId, Policy);
}
break;

View File

@ -247,6 +247,14 @@ TEST(TypeLoc, AutoTypeLocRange) {
Verifier.expectRange(1, 1, 1, 14);
EXPECT_TRUE(Verifier.match("decltype(auto) a = 1;", typeLoc(loc(autoType())),
Lang_CXX14));
const char *Code =
R"cpp(template <typename T> concept C = true;
C auto abc();
)cpp";
// Should include "C auto" tokens.
Verifier.expectRange(2, 1, 2, 3); // token range.
EXPECT_TRUE(Verifier.match(Code, typeLoc(loc(autoType())), Lang_CXX20));
}
TEST(TypeLoc, LongDoubleRange) {