summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaojian Wu <hokein.wu@gmail.com>2022-01-10 15:19:05 +0100
committerHaojian Wu <hokein.wu@gmail.com>2022-01-11 12:06:18 +0100
commit41fbdfa4d5601cccbcdc0ded8ef35190d502f7f3 (patch)
treefdeb27c9cd7959a14c8f3b98b90299a01cbbcba4
parent0b48d0fe1292929f0cd61a2ca8114d794e245daa (diff)
downloadllvm-41fbdfa4d5601cccbcdc0ded8ef35190d502f7f3.tar.gz
Reland "[AST] Add RParen loc for decltype AutoTypeloc."
Reland 55d96ac and 37ec65e with a clang-tidy fix.
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp13
-rw-r--r--clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp4
-rw-r--r--clang-tools-extra/clangd/unittests/SelectionTests.cpp2
-rw-r--r--clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp3
-rw-r--r--clang/include/clang/AST/TypeLoc.h24
-rw-r--r--clang/lib/AST/TypeLoc.cpp1
-rw-r--r--clang/lib/Parse/ParseDecl.cpp1
-rw-r--r--clang/lib/Sema/SemaType.cpp3
-rw-r--r--clang/lib/Serialization/ASTReader.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp3
-rw-r--r--clang/test/AST/ast-dump-template-decls-json.cpp6
-rw-r--r--clang/test/AST/ast-dump-template-decls.cpp2
-rw-r--r--clang/unittests/AST/SourceLocationTest.cpp7
13 files changed, 45 insertions, 26 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
index d5c9fa7de811..2b9907d16266 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
@@ -285,15 +285,12 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
return {};
}
- // If the return type is a constrained 'auto' or 'decltype(auto)', we need to
- // include the tokens after the concept. Unfortunately, the source range of an
- // AutoTypeLoc, if it is constrained, does not include the 'auto' or
- // 'decltype(auto)'. If the return type is a plain 'decltype(...)', the
- // source range only contains the first 'decltype' token.
+ // 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.getAutoKeyword() == AutoTypeKeyword::DecltypeAuto)) ||
- ReturnLoc.getAs<DecltypeTypeLoc>()) {
+ if (ATL && ATL.isConstrained() && !ATL.isDecltypeAuto()) {
SourceLocation End =
expandIfMacroId(ReturnLoc.getSourceRange().getEnd(), SM);
SourceLocation BeginNameF = expandIfMacroId(F.getLocation(), SM);
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
index 3776e1c3505d..914564e9ae21 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
@@ -96,9 +96,7 @@ bool ExpandAutoType::prepare(const Selection& Inputs) {
if (auto *Node = Inputs.ASTSelection.commonAncestor()) {
if (auto *TypeNode = Node->ASTNode.get<TypeLoc>()) {
if (const AutoTypeLoc Result = TypeNode->getAs<AutoTypeLoc>()) {
- // Code in apply() does handle 'decltype(auto)' yet.
- if (!Result.getTypePtr()->isDecltypeAuto() &&
- !isStructuredBindingType(Node) &&
+ if (!isStructuredBindingType(Node) &&
!isDeducedAsLambda(Node, Result.getBeginLoc()) &&
!isTemplateParam(Node))
CachedLocation = Result;
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 7e19f07a2215..0f4464122c8f 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -391,6 +391,8 @@ TEST(SelectionTest, CommonAncestor) {
)cpp",
"DeclRefExpr"},
{"[[decltype^(1)]] b;", "DecltypeTypeLoc"}, // Not the VarDecl.
+ // decltype(auto) is an AutoTypeLoc!
+ {"[[de^cltype(a^uto)]] a = 1;", "AutoTypeLoc"},
// Objective-C nullability attributes.
{
diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp
index 96574a67b5a4..6d9d4362be7a 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp
@@ -71,7 +71,8 @@ TEST_F(ExpandAutoTypeTest, Test) {
apply("void ns::Func() { au^to x = new ns::Class::Nested{}; }"),
"void ns::Func() { ns::Class::Nested * x = new ns::Class::Nested{}; }");
- EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
+ EXPECT_EQ(apply("dec^ltype(auto) x = 10;"), "int x = 10;");
+ EXPECT_EQ(apply("decltype(au^to) x = 10;"), "int x = 10;");
// expanding types in structured bindings is syntactically invalid.
EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 9a43d34a9ec3..9c7ab4e8ddb7 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -2081,6 +2081,9 @@ struct AutoTypeLocInfo : TypeSpecLocInfo {
NamedDecl *FoundDecl;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
+
+ // For decltype(auto).
+ SourceLocation RParenLoc;
};
class AutoTypeLoc
@@ -2093,6 +2096,10 @@ public:
return getTypePtr()->getKeyword();
}
+ bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
+ SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
+ void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
+
bool isConstrained() const {
return getTypePtr()->isConstrained();
}
@@ -2173,16 +2180,13 @@ public:
}
SourceRange getLocalSourceRange() const {
- return{
- isConstrained()
- ? (getNestedNameSpecifierLoc()
- ? getNestedNameSpecifierLoc().getBeginLoc()
- : (getTemplateKWLoc().isValid()
- ? getTemplateKWLoc()
- : getConceptNameLoc()))
- : getNameLoc(),
- getNameLoc()
- };
+ return {isConstrained()
+ ? (getNestedNameSpecifierLoc()
+ ? getNestedNameSpecifierLoc().getBeginLoc()
+ : (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
+ : getConceptNameLoc()))
+ : getNameLoc(),
+ isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
}
void copy(AutoTypeLoc Loc) {
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index c3ed08d5a8b3..13aa54c48f66 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -622,6 +622,7 @@ void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
setFoundDecl(nullptr);
setRAngleLoc(Loc);
setLAngleLoc(Loc);
+ setRParenLoc(Loc);
TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
getTypePtr()->getArgs(),
getArgInfos(), Loc);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index e1074f78c062..cff8c76183f6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3576,6 +3576,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
}
}
ConsumedEnd = Tok.getLocation();
+ DS.setTypeofParensRange(Tracker.getRange());
// Even if something went wrong above, continue as if we've seen
// `decltype(auto)`.
isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f0bbbcf59c75..959f4903b030 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
@@ -6041,6 +6042,8 @@ namespace {
DS.getTypeSpecType() == TST_auto_type ||
DS.getTypeSpecType() == TST_unspecified);
TL.setNameLoc(DS.getTypeSpecTypeLoc());
+ if (DS.getTypeSpecType() == TST_decltype_auto)
+ TL.setRParenLoc(DS.getTypeofParensRange().getEnd());
if (!DS.isConstrainedAuto())
return;
TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index b8ec5b2722a9..9056f00978c8 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -6652,6 +6652,8 @@ void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo(
TL.getTypePtr()->getArg(i).getKind()));
}
+ if (Reader.readBool())
+ TL.setRParenLoc(readSourceLocation());
}
void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc(
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 40772bb7dd7f..c2bee93b077e 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -452,6 +452,9 @@ void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
TL.getArgLocInfo(I));
}
+ Record.push_back(TL.isDecltypeAuto());
+ if (TL.isDecltypeAuto())
+ Record.AddSourceLocation(TL.getRParenLoc());
}
void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
diff --git a/clang/test/AST/ast-dump-template-decls-json.cpp b/clang/test/AST/ast-dump-template-decls-json.cpp
index fc1b883f5dac..5fc466bd9908 100644
--- a/clang/test/AST/ast-dump-template-decls-json.cpp
+++ b/clang/test/AST/ast-dump-template-decls-json.cpp
@@ -2130,9 +2130,9 @@ void i();
// CHECK-NEXT: "tokLen": 8
// CHECK-NEXT: },
// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 705,
-// CHECK-NEXT: "col": 11,
-// CHECK-NEXT: "tokLen": 8
+// CHECK-NEXT: "offset": 718,
+// CHECK-NEXT: "col": 24,
+// CHECK-NEXT: "tokLen": 1
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp
index e58731ae6d51..51ec673ab8f3 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -90,7 +90,7 @@ struct T {};
template <decltype(auto)>
// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 U
-// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11> col:25 'decltype(auto)' depth 0 index 0
+// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:24> col:25 'decltype(auto)' depth 0 index 0
struct U {};
template <typename Ty>
diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp
index 832d3751362f..a798f6b2225b 100644
--- a/clang/unittests/AST/SourceLocationTest.cpp
+++ b/clang/unittests/AST/SourceLocationTest.cpp
@@ -242,6 +242,13 @@ TEST(TypeLoc, DecltypeTypeLocRange) {
verify(Target2->getSourceRange(), Code.range("full2"));
}
+TEST(TypeLoc, AutoTypeLocRange) {
+ RangeVerifier<TypeLoc> Verifier;
+ Verifier.expectRange(1, 1, 1, 14);
+ EXPECT_TRUE(Verifier.match("decltype(auto) a = 1;", typeLoc(loc(autoType())),
+ Lang_CXX14));
+}
+
TEST(TypeLoc, LongDoubleRange) {
RangeVerifier<TypeLoc> Verifier;
Verifier.expectRange(1, 1, 1, 6);