diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index de33d79eeb484..bf4d26c723d2e 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -327,11 +327,12 @@ void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl, Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy); } - Out << "("; - if (!BMInitializer->getInit()) { - // Nothing to print - } else { - Expr *Init = BMInitializer->getInit(); + if (Expr *Init = BMInitializer->getInit()) { + bool OutParens = !isa(Init); + + if (OutParens) + Out << "("; + if (ExprWithCleanups *Tmp = dyn_cast(Init)) Init = Tmp->getSubExpr(); @@ -365,8 +366,13 @@ void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl, &Context); } } + + if (OutParens) + Out << ")"; + } else { + Out << "()"; } - Out << ")"; + if (BMInitializer->isPackExpansion()) Out << "..."; } diff --git a/clang/test/AST/ast-print-method-decl.cpp b/clang/test/AST/ast-print-method-decl.cpp index 4a3f5440fe158..505e07dde1a86 100644 --- a/clang/test/AST/ast-print-method-decl.cpp +++ b/clang/test/AST/ast-print-method-decl.cpp @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -ast-print %s -o - -std=c++20 | FileCheck %s -// CHECK: struct A { -struct A { - // CHECK-NEXT: A(); - A(); +// CHECK: struct DelegatingCtor1 { +struct DelegatingCtor1 { + // CHECK-NEXT: DelegatingCtor1(); + DelegatingCtor1(); - // CHECK-NEXT: A(int) : A() { - A(int) : A() { + // CHECK-NEXT: DelegatingCtor1(int) : DelegatingCtor1() { + DelegatingCtor1(int) : DelegatingCtor1() { // CHECK-NEXT: } } @@ -14,33 +14,72 @@ struct A { }; -// CHECK: struct B { -struct B { - // CHECK-NEXT: template B(Ty); - template B(Ty); +// CHECK: struct DelegatingCtor2 { +struct DelegatingCtor2 { + // CHECK-NEXT: template DelegatingCtor2(Ty); + template DelegatingCtor2(Ty); // FIXME: Implicitly specialized method should not be output - // CHECK-NEXT: template<> B(float); + // CHECK-NEXT: template<> DelegatingCtor2(float); - // CHECK-NEXT: B(int X) : B((float)X) { - B(int X) : B((float)X) { + // CHECK-NEXT: DelegatingCtor2(int X) : DelegatingCtor2((float)X) { + DelegatingCtor2(int X) : DelegatingCtor2((float)X) { // CHECK-NEXT: } } // CHECK-NEXT: }; }; -// CHECK: struct C { -struct C { +// CHECK: struct DelegatingCtor3 { +struct DelegatingCtor3 { // FIXME: template <> should not be output - // CHECK: template <> C(auto); - C(auto); + // CHECK: template <> DelegatingCtor3(auto); + DelegatingCtor3(auto); // FIXME: Implicitly specialized method should not be output - // CHECK: template<> C(const char *); + // CHECK: template<> DelegatingCtor3(const char *); - // CHECK: C(int) : C("") { - C(int) : C("") { + // CHECK: DelegatingCtor3(int) : DelegatingCtor3("") { + DelegatingCtor3(int) : DelegatingCtor3("") { + // CHECK-NEXT: } + } + + // CHECK-NEXT: }; +}; + +// CHECK: struct CurlyCtorInit { +struct CurlyCtorInit { + // CHECK-NEXT: struct A { + struct A { + // CHECK-NEXT: int x; + int x; + // CHECK-NEXT: }; + }; + + // CHECK-NEXT: A a; + A a; + // CHECK-NEXT: int i; + int i; + + // FIXME: /*implicit*/(int)0 should not be output + // CHECK-NEXT: CurlyCtorInit(int *) : a(), i(/*implicit*/(int)0) { + CurlyCtorInit(int *) : a(), i() { + // CHECK-NEXT: } + } + + // CHECK-NEXT: CurlyCtorInit(int **) : a{}, i{} { + CurlyCtorInit(int **) : a{}, i{} { + // CHECK-NEXT: } + } + + // CHECK-NEXT: CurlyCtorInit(int ***) : a({}), i(0) { + CurlyCtorInit(int ***) : a({}), i(0) { + // CHECK-NEXT: } + } + + // FIXME: Implicit this should not be output + // CHECK-NEXT: CurlyCtorInit(int ****) : a({.x = 0}), i(this->a.x) { + CurlyCtorInit(int ****) : a({.x = 0}), i(a.x) { // CHECK-NEXT: } }