diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 555aa5c050ffd..591457b1d66b4 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1790,7 +1790,9 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS, else OS << *ND; } else if (const auto *RD = dyn_cast(DC)) { - if (!RD->getIdentifier()) + if (TypedefNameDecl *TD = RD->getTypedefNameForAnonDecl()) + OS << *TD; + else if (!RD->getIdentifier()) OS << "(anonymous " << RD->getKindName() << ')'; else OS << *RD; diff --git a/clang/unittests/AST/TypePrinterTest.cpp b/clang/unittests/AST/TypePrinterTest.cpp index 410ec021d6e72..3cadf9b265bd1 100644 --- a/clang/unittests/AST/TypePrinterTest.cpp +++ b/clang/unittests/AST/TypePrinterTest.cpp @@ -341,3 +341,22 @@ TEST(TypePrinter, NestedNameSpecifiers) { Policy.AnonymousTagLocations = false; })); } + +TEST(TypePrinter, NestedNameSpecifiersTypedef) { + constexpr char Code[] = R"cpp( + typedef union { + struct { + struct { + unsigned int baz; + } bar; + }; + } foo; + )cpp"; + + ASSERT_TRUE(PrintedTypeMatches( + Code, {}, fieldDecl(hasName("bar"), hasType(qualType().bind("id"))), + "struct foo::(anonymous struct)::(unnamed)", [](PrintingPolicy &Policy) { + Policy.FullyQualifiedName = true; + Policy.AnonymousTagLocations = false; + })); +}