diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2022-01-10 15:19:05 +0100 |
---|---|---|
committer | Haojian Wu <hokein.wu@gmail.com> | 2022-01-11 12:06:18 +0100 |
commit | 41fbdfa4d5601cccbcdc0ded8ef35190d502f7f3 (patch) | |
tree | fdeb27c9cd7959a14c8f3b98b90299a01cbbcba4 | |
parent | 0b48d0fe1292929f0cd61a2ca8114d794e245daa (diff) | |
download | llvm-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.cpp | 13 | ||||
-rw-r--r-- | clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp | 4 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/SelectionTests.cpp | 2 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/tweaks/ExpandAutoTypeTests.cpp | 3 | ||||
-rw-r--r-- | clang/include/clang/AST/TypeLoc.h | 24 | ||||
-rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 3 | ||||
-rw-r--r-- | clang/test/AST/ast-dump-template-decls-json.cpp | 6 | ||||
-rw-r--r-- | clang/test/AST/ast-dump-template-decls.cpp | 2 | ||||
-rw-r--r-- | clang/unittests/AST/SourceLocationTest.cpp | 7 |
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); |