[AST] Fix the incorrect auto-keyword loc for constrained auto type loc.
authorHaojian Wu <hokein.wu@gmail.com>
Wed, 19 Jan 2022 12:55:07 +0000 (13:55 +0100)
committerHaojian Wu <hokein.wu@gmail.com>
Wed, 19 Jan 2022 13:18:38 +0000 (14:18 +0100)
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

clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
clang/lib/Parse/ParseDecl.cpp
clang/unittests/AST/SourceLocationTest.cpp

index 2b9907d..60b80af 100644 (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()))
index cff8c76..f21938c 100644 (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;
index a798f6b..28205c2 100644 (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) {