Skip to content

Commit 41fbdfa

Browse files
committed
Reland "[AST] Add RParen loc for decltype AutoTypeloc."
Reland 55d96ac and 37ec65e with a clang-tidy fix.
1 parent 0b48d0f commit 41fbdfa

File tree

13 files changed

+45
-26
lines changed

13 files changed

+45
-26
lines changed

clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,15 +285,12 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
285285
return {};
286286
}
287287

288-
// If the return type is a constrained 'auto' or 'decltype(auto)', we need to
289-
// include the tokens after the concept. Unfortunately, the source range of an
290-
// AutoTypeLoc, if it is constrained, does not include the 'auto' or
291-
// 'decltype(auto)'. If the return type is a plain 'decltype(...)', the
292-
// source range only contains the first 'decltype' token.
288+
// If the return type is a constrained 'auto', we need to include the token
289+
// after the concept. Unfortunately, the source range of an AutoTypeLoc, if it
290+
// is constrained, does not include the 'auto'.
291+
// FIXME: fix the AutoTypeLoc location in clang.
293292
auto ATL = ReturnLoc.getAs<AutoTypeLoc>();
294-
if ((ATL && (ATL.isConstrained() ||
295-
ATL.getAutoKeyword() == AutoTypeKeyword::DecltypeAuto)) ||
296-
ReturnLoc.getAs<DecltypeTypeLoc>()) {
293+
if (ATL && ATL.isConstrained() && !ATL.isDecltypeAuto()) {
297294
SourceLocation End =
298295
expandIfMacroId(ReturnLoc.getSourceRange().getEnd(), SM);
299296
SourceLocation BeginNameF = expandIfMacroId(F.getLocation(), SM);

clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ bool ExpandAutoType::prepare(const Selection& Inputs) {
9696
if (auto *Node = Inputs.ASTSelection.commonAncestor()) {
9797
if (auto *TypeNode = Node->ASTNode.get<TypeLoc>()) {
9898
if (const AutoTypeLoc Result = TypeNode->getAs<AutoTypeLoc>()) {
99-
// Code in apply() does handle 'decltype(auto)' yet.
100-
if (!Result.getTypePtr()->isDecltypeAuto() &&
101-
!isStructuredBindingType(Node) &&
99+
if (!isStructuredBindingType(Node) &&
102100
!isDeducedAsLambda(Node, Result.getBeginLoc()) &&
103101
!isTemplateParam(Node))
104102
CachedLocation = Result;

clang-tools-extra/clangd/unittests/SelectionTests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ TEST(SelectionTest, CommonAncestor) {
391391
)cpp",
392392
"DeclRefExpr"},
393393
{"[[decltype^(1)]] b;", "DecltypeTypeLoc"}, // Not the VarDecl.
394+
// decltype(auto) is an AutoTypeLoc!
395+
{"[[de^cltype(a^uto)]] a = 1;", "AutoTypeLoc"},
394396

395397
// Objective-C nullability attributes.
396398
{

clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ TEST_F(ExpandAutoTypeTest, Test) {
7171
apply("void ns::Func() { au^to x = new ns::Class::Nested{}; }"),
7272
"void ns::Func() { ns::Class::Nested * x = new ns::Class::Nested{}; }");
7373

74-
EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
74+
EXPECT_EQ(apply("dec^ltype(auto) x = 10;"), "int x = 10;");
75+
EXPECT_EQ(apply("decltype(au^to) x = 10;"), "int x = 10;");
7576
// expanding types in structured bindings is syntactically invalid.
7677
EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
7778

clang/include/clang/AST/TypeLoc.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,6 +2081,9 @@ struct AutoTypeLocInfo : TypeSpecLocInfo {
20812081
NamedDecl *FoundDecl;
20822082
SourceLocation LAngleLoc;
20832083
SourceLocation RAngleLoc;
2084+
2085+
// For decltype(auto).
2086+
SourceLocation RParenLoc;
20842087
};
20852088

20862089
class AutoTypeLoc
@@ -2093,6 +2096,10 @@ class AutoTypeLoc
20932096
return getTypePtr()->getKeyword();
20942097
}
20952098

2099+
bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
2100+
SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2101+
void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2102+
20962103
bool isConstrained() const {
20972104
return getTypePtr()->isConstrained();
20982105
}
@@ -2173,16 +2180,13 @@ class AutoTypeLoc
21732180
}
21742181

21752182
SourceRange getLocalSourceRange() const {
2176-
return{
2177-
isConstrained()
2178-
? (getNestedNameSpecifierLoc()
2179-
? getNestedNameSpecifierLoc().getBeginLoc()
2180-
: (getTemplateKWLoc().isValid()
2181-
? getTemplateKWLoc()
2182-
: getConceptNameLoc()))
2183-
: getNameLoc(),
2184-
getNameLoc()
2185-
};
2183+
return {isConstrained()
2184+
? (getNestedNameSpecifierLoc()
2185+
? getNestedNameSpecifierLoc().getBeginLoc()
2186+
: (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
2187+
: getConceptNameLoc()))
2188+
: getNameLoc(),
2189+
isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
21862190
}
21872191

21882192
void copy(AutoTypeLoc Loc) {

clang/lib/AST/TypeLoc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) {
622622
setFoundDecl(nullptr);
623623
setRAngleLoc(Loc);
624624
setLAngleLoc(Loc);
625+
setRParenLoc(Loc);
625626
TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
626627
getTypePtr()->getArgs(),
627628
getArgInfos(), Loc);

clang/lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3576,6 +3576,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
35763576
}
35773577
}
35783578
ConsumedEnd = Tok.getLocation();
3579+
DS.setTypeofParensRange(Tracker.getRange());
35793580
// Even if something went wrong above, continue as if we've seen
35803581
// `decltype(auto)`.
35813582
isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,

clang/lib/Sema/SemaType.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/AST/TypeLoc.h"
2323
#include "clang/AST/TypeLocVisitor.h"
2424
#include "clang/Basic/PartialDiagnostic.h"
25+
#include "clang/Basic/Specifiers.h"
2526
#include "clang/Basic/TargetInfo.h"
2627
#include "clang/Lex/Preprocessor.h"
2728
#include "clang/Sema/DeclSpec.h"
@@ -6041,6 +6042,8 @@ namespace {
60416042
DS.getTypeSpecType() == TST_auto_type ||
60426043
DS.getTypeSpecType() == TST_unspecified);
60436044
TL.setNameLoc(DS.getTypeSpecTypeLoc());
6045+
if (DS.getTypeSpecType() == TST_decltype_auto)
6046+
TL.setRParenLoc(DS.getTypeofParensRange().getEnd());
60446047
if (!DS.isConstrainedAuto())
60456048
return;
60466049
TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId();

clang/lib/Serialization/ASTReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6652,6 +6652,8 @@ void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
66526652
TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo(
66536653
TL.getTypePtr()->getArg(i).getKind()));
66546654
}
6655+
if (Reader.readBool())
6656+
TL.setRParenLoc(readSourceLocation());
66556657
}
66566658

66576659
void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc(

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,9 @@ void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
452452
Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
453453
TL.getArgLocInfo(I));
454454
}
455+
Record.push_back(TL.isDecltypeAuto());
456+
if (TL.isDecltypeAuto())
457+
Record.AddSourceLocation(TL.getRParenLoc());
455458
}
456459

457460
void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(

clang/test/AST/ast-dump-template-decls-json.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,9 +2130,9 @@ void i();
21302130
// CHECK-NEXT: "tokLen": 8
21312131
// CHECK-NEXT: },
21322132
// CHECK-NEXT: "end": {
2133-
// CHECK-NEXT: "offset": 705,
2134-
// CHECK-NEXT: "col": 11,
2135-
// CHECK-NEXT: "tokLen": 8
2133+
// CHECK-NEXT: "offset": 718,
2134+
// CHECK-NEXT: "col": 24,
2135+
// CHECK-NEXT: "tokLen": 1
21362136
// CHECK-NEXT: }
21372137
// CHECK-NEXT: },
21382138
// CHECK-NEXT: "type": {

clang/test/AST/ast-dump-template-decls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ struct T {};
9090

9191
template <decltype(auto)>
9292
// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 U
93-
// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11> col:25 'decltype(auto)' depth 0 index 0
93+
// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:24> col:25 'decltype(auto)' depth 0 index 0
9494
struct U {};
9595

9696
template <typename Ty>

clang/unittests/AST/SourceLocationTest.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ TEST(TypeLoc, DecltypeTypeLocRange) {
242242
verify(Target2->getSourceRange(), Code.range("full2"));
243243
}
244244

245+
TEST(TypeLoc, AutoTypeLocRange) {
246+
RangeVerifier<TypeLoc> Verifier;
247+
Verifier.expectRange(1, 1, 1, 14);
248+
EXPECT_TRUE(Verifier.match("decltype(auto) a = 1;", typeLoc(loc(autoType())),
249+
Lang_CXX14));
250+
}
251+
245252
TEST(TypeLoc, LongDoubleRange) {
246253
RangeVerifier<TypeLoc> Verifier;
247254
Verifier.expectRange(1, 1, 1, 6);

0 commit comments

Comments
 (0)