-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[clang] fix regression printing constructor/destructor names #155688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This makes the type printer not qualify constructor and destructor names. These are represented as canonical types and the type printer is used, but unlike canonical types which we normally print as fully qualified, the expected behaviour for declaration names is for them to be unqualified. Note that this restores the behaviour pre #147835, but that is still broken for the constructor names of class templates, since in that case the injected class name type is used, but here the type printer is configured to also print the implicit template arguments. No release notes since this regression was never released. Fixes #155537
@llvm/pr-subscribers-hlsl @llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) ChangesThis makes the type printer not qualify constructor and destructor names. These are represented as canonical types and the type printer is used, but unlike canonical types which we normally print as fully qualified, the expected behaviour for declaration names is for them to be unqualified. Note that this restores the behaviour pre #147835, but that is still broken for the constructor names of class templates, since in that case the injected class name type is used, but here the type printer is configured to also print the implicit template arguments. No release notes since this regression was never released. Fixes #155537 Full diff: https://github.com/llvm/llvm-project/pull/155688.diff 10 Files Affected:
diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp
index 74f2eec69461a..55f5a994d788b 100644
--- a/clang/lib/AST/DeclarationName.cpp
+++ b/clang/lib/AST/DeclarationName.cpp
@@ -113,6 +113,7 @@ static void printCXXConstructorDestructorName(QualType ClassType,
PrintingPolicy Policy) {
// We know we're printing C++ here. Ensure we print types properly.
Policy.adjustForCPlusPlus();
+ Policy.SuppressScope = true;
if (const RecordType *ClassRec = ClassType->getAsCanonical<RecordType>()) {
ClassRec->getOriginalDecl()->printName(OS, Policy);
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index 76de39ca4b60e..6ee7145c7e538 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -91,7 +91,7 @@ RESOURCE<float> Buffer;
// Default constructor
-// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void ()' inline
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void ()' inline
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
@@ -105,7 +105,7 @@ RESOURCE<float> Buffer;
// Constructor from binding
-// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
@@ -129,7 +129,7 @@ RESOURCE<float> Buffer;
// Constructor from implicit binding
-// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int'
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index 936a060a305cd..e7f000e9c1b70 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -66,7 +66,7 @@ RESOURCE<float> Buffer;
// Default constructor
-// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void ()' inline
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void ()' inline
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
@@ -80,7 +80,7 @@ RESOURCE<float> Buffer;
// Constructor from binding
-// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
@@ -104,7 +104,7 @@ RESOURCE<float> Buffer;
// Constructor from implicit binding
-// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int'
diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp
index 6cada93c8b93b..849bfbee2ab21 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -330,8 +330,8 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | | `-Destructor irrelevant non_trivial user_declared{{$}}
// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:24, col:30> col:30 implicit referenced class TestClassTemplate{{$}}
// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-50]]:3, col:9> col:3 public{{$}}
-// CHECK-NEXT: | |-CXXConstructorDecl 0x[[#%x,TEMPLATE_CONSTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:23> col:5 testClassTemplateDecl::TestClassTemplate<T> 'void ()'{{$}}
-// CHECK-NEXT: | |-CXXDestructorDecl 0x[[#%x,TEMPLATE_DESTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:24> col:5 ~testClassTemplateDecl::TestClassTemplate<T> 'void ()' not_selected{{$}}
+// CHECK-NEXT: | |-CXXConstructorDecl 0x[[#%x,TEMPLATE_CONSTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:23> col:5 TestClassTemplate<T> 'void ()'{{$}}
+// CHECK-NEXT: | |-CXXDestructorDecl 0x[[#%x,TEMPLATE_DESTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:24> col:5 ~TestClassTemplate<T> 'void ()' not_selected{{$}}
// CHECK-NEXT: | |-CXXMethodDecl 0x[[#%x,TEMPLATE_METHOD_DECL:]] <line:[[@LINE-50]]:5, col:11> col:9 j 'int ()'{{$}}
// CHECK-NEXT: | `-FieldDecl 0x{{.+}} <line:[[@LINE-50]]:5, col:9> col:9 i 'int'{{$}}
// CHECK-NEXT: |-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-56]]:3, line:[[@LINE-50]]:3> line:[[@LINE-56]]:30 class TestClassTemplate definition implicit_instantiation{{$}}
diff --git a/clang/test/AST/ast-dump-templates.cpp b/clang/test/AST/ast-dump-templates.cpp
index a842eabf6962f..e43fe6b1dda25 100644
--- a/clang/test/AST/ast-dump-templates.cpp
+++ b/clang/test/AST/ast-dump-templates.cpp
@@ -8170,7 +8170,7 @@ namespace GH153540 {
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
// JSON-NEXT: },
-// JSON-NEXT: "name": "GH153540::N::S<T>",
+// JSON-NEXT: "name": "S<T>",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "void (T)"
// JSON-NEXT: },
diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp
index 659fa499a2f49..11eb0bf3a27b2 100644
--- a/clang/test/CXX/drs/cwg6xx.cpp
+++ b/clang/test/CXX/drs/cwg6xx.cpp
@@ -383,7 +383,7 @@ namespace cwg635 { // cwg635: 2.7
template<typename T> template<typename U> D<T>::D() {}
template<typename T> D<T>::D<T>() {} // #cwg635-D-T
// expected-error@#cwg635-D-T {{out-of-line constructor for 'D' cannot have template arguments}}
- // expected-error@#cwg635-D-T {{redefinition of 'cwg635::D<T>'}}
+ // expected-error@#cwg635-D-T {{redefinition of 'D<T>'}}
// expected-note@#cwg635-D {{previous definition is here}}
} // namespace cwg635
diff --git a/clang/test/Index/recursive-cxx-member-calls.cpp b/clang/test/Index/recursive-cxx-member-calls.cpp
index b378975b5a763..c7f0053500c60 100644
--- a/clang/test/Index/recursive-cxx-member-calls.cpp
+++ b/clang/test/Index/recursive-cxx-member-calls.cpp
@@ -823,18 +823,18 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Punctuation: ";" [85:18 - 85:19] ClassTemplate=StringSwitch:83:47 (Definition)
// CHECK-tokens: Keyword: "public" [86:1 - 86:7] CXXAccessSpecifier=:86:1 (Definition)
// CHECK-tokens: Punctuation: ":" [86:7 - 86:8] CXXAccessSpecifier=:86:1 (Definition)
-// CHECK-tokens: Keyword: "explicit" [87:3 - 87:11] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
-// CHECK-tokens: Identifier: "StringSwitch" [87:12 - 87:24] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition) (explicit)
-// CHECK-tokens: Punctuation: "(" [87:24 - 87:25] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Keyword: "explicit" [87:3 - 87:11] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Identifier: "StringSwitch" [87:12 - 87:24] CXXConstructor=StringSwitch<T, R>:87:12 (Definition) (explicit)
+// CHECK-tokens: Punctuation: "(" [87:24 - 87:25] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
// CHECK-tokens: Identifier: "StringRef" [87:25 - 87:34] TypeRef=class llvm::StringRef:38:7
// CHECK-tokens: Identifier: "Str" [87:35 - 87:38] ParmDecl=Str:87:35 (Definition)
-// CHECK-tokens: Punctuation: ")" [87:38 - 87:39] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
-// CHECK-tokens: Punctuation: ":" [87:40 - 87:41] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Punctuation: ")" [87:38 - 87:39] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Punctuation: ":" [87:40 - 87:41] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
// CHECK-tokens: Identifier: "Str" [87:42 - 87:45] MemberRef=Str:84:13
// CHECK-tokens: Punctuation: "(" [87:45 - 87:46] CallExpr=StringRef:38:7
// CHECK-tokens: Identifier: "Str" [87:46 - 87:49] DeclRefExpr=Str:87:35
// CHECK-tokens: Punctuation: ")" [87:49 - 87:50] CallExpr=StringRef:38:7
-// CHECK-tokens: Punctuation: "," [87:50 - 87:51] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Punctuation: "," [87:50 - 87:51] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
// CHECK-tokens: Identifier: "Result" [87:52 - 87:58] MemberRef=Result:85:12
// CHECK-tokens: Punctuation: "(" [87:58 - 87:59] UnexposedExpr=
// CHECK-tokens: Literal: "0" [87:59 - 87:60] IntegerLiteral=
@@ -1839,7 +1839,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 84:3: TypeRef=class llvm::StringRef:38:7 Extent=[84:3 - 84:12]
// CHECK: 85:12: FieldDecl=Result:85:12 (Definition) Extent=[85:3 - 85:18]
// CHECK: 86:1: CXXAccessSpecifier=:86:1 (Definition) Extent=[86:1 - 86:8]
-// CHECK: 87:12: CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition) (explicit) Extent=[87:3 - 87:64]
+// CHECK: 87:12: CXXConstructor=StringSwitch<T, R>:87:12 (Definition) (explicit) Extent=[87:3 - 87:64]
// CHECK: 87:35: ParmDecl=Str:87:35 (Definition) Extent=[87:25 - 87:38]
// CHECK: 87:25: TypeRef=class llvm::StringRef:38:7 Extent=[87:25 - 87:34]
// CHECK: 87:42: MemberRef=Str:84:13 Extent=[87:42 - 87:45]
diff --git a/clang/test/PCH/cxx-explicit-specifier.cpp b/clang/test/PCH/cxx-explicit-specifier.cpp
index a30c669fddb47..c7cd2c5002405 100644
--- a/clang/test/PCH/cxx-explicit-specifier.cpp
+++ b/clang/test/PCH/cxx-explicit-specifier.cpp
@@ -85,7 +85,7 @@ B<false> b_false;
//expected-note@-8+ {{explicit conversion function is not a candidate (explicit specifier}}
//expected-note@-11 {{explicit constructor is not a candidate (explicit specifier}}
-//CHECK: explicit(b){{ +}}templ::A<b>(B<b>)
+//CHECK: explicit(b){{ +}}A
//CHECK: explicit(b{{ +}}^{{ +}}T::value){{ +}}operator
A a = { b_true }; //expected-error {{class template argument deduction}}
diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp
index 60accbde9d701..796c9ae91dedc 100644
--- a/clang/test/SemaCXX/return.cpp
+++ b/clang/test/SemaCXX/return.cpp
@@ -115,9 +115,9 @@ namespace ctor_returns_void {
};
template <typename T> struct ST {
- ST() { return f(); } // expected-error {{constructor 'ctor_returns_void::ST<T>' must not return void expression}}
+ ST() { return f(); } // expected-error {{constructor 'ST<T>' must not return void expression}}
// expected-error@-1 {{constructor 'ST' must not return void expression}}
- ~ST() { return f(); } // expected-error {{destructor '~ctor_returns_void::ST<T>' must not return void expression}}
+ ~ST() { return f(); } // expected-error {{destructor '~ST<T>' must not return void expression}}
// expected-error@-1 {{destructor '~ST' must not return void expression}}
};
diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index 6b443918ec137..4c83ff9142e87 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -570,3 +570,19 @@ void instantiate_template() {
EXPECT_EQ(GetNameInfoRange(Matches[1]), "<input.cc:6:14, col:15>");
EXPECT_EQ(GetNameInfoRange(Matches[2]), "<input.cc:6:14, col:15>");
}
+
+TEST(Decl, getQualifiedNameAsString) {
+ llvm::Annotations Code(R"cpp(
+namespace x::y {
+ template <class T> class Foo { Foo() {} };
+}
+)cpp");
+
+ auto AST = tooling::buildASTFromCode(Code.code());
+ ASTContext &Ctx = AST->getASTContext();
+
+ auto const *FD = selectFirst<CXXConstructorDecl>(
+ "ctor", match(cxxConstructorDecl().bind("ctor"), Ctx));
+ ASSERT_NE(FD, nullptr);
+ ASSERT_EQ(FD->getQualifiedNameAsString(), "x::y::Foo::Foo<T>");
+}
|
Should this be a new issue? |
I vaguely remember having created such an issue in the past, but I can't find it, so I created a new one in any case: #155709 |
This makes the type printer not qualify constructor and destructor names. These are represented as canonical types and the type printer is used, but unlike canonical types which we normally print as fully qualified, the expected behaviour for declaration names is for them to be unqualified.
Note that this restores the behaviour pre #147835, but that is still broken for the constructor names of class templates, since in that case the injected class name type is used, but here the type printer is configured to also print the implicit template arguments.
No release notes since this regression was never released.
Fixes #155537