llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: mygitljf <details> <summary>Changes</summary> I updated DeclRefExpr printing so fully-qualified printing consistently uses declaration ownership rather than only the written qualifier. This also preserves existing behavior for local names and cleaned parameter names. The added tests cover both the direct expression printer behavior and the original type-printing scenario that exposed the missing qualification. Fixes #<!-- -->205925 --- Full diff: https://github.com/llvm/llvm-project/pull/206041.diff 3 Files Affected: - (modified) clang/lib/AST/StmtPrinter.cpp (+40-33) - (modified) clang/unittests/AST/StmtPrinterTest.cpp (+43) - (modified) clang/unittests/AST/TypePrinterTest.cpp (+24) ``````````diff diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 6c3294573e9d4..e4dc41cf2c043 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1330,42 +1330,49 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { TPOD->printAsExpr(OS, Policy); return; } - Node->getQualifier().print(OS, Policy); - if (Node->hasTemplateKeyword()) - OS << "template "; - bool ForceAnonymous = Policy.PrintAsCanonical && VD->getKind() == Decl::NonTypeTemplateParm; - DeclarationNameInfo NameInfo = Node->getNameInfo(); - if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo(); - !ForceAnonymous && - (ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier)) { - if (Policy.CleanUglifiedParameters && - isa<ParmVarDecl, NonTypeTemplateParmDecl>(VD) && ID) - OS << ID->deuglifiedName(); - else - NameInfo.printName(OS, Policy); + bool CleanUglifiedParameter = Policy.CleanUglifiedParameters && + isa<ParmVarDecl, NonTypeTemplateParmDecl>(VD); + + if (Policy.FullyQualifiedName && !ForceAnonymous && !CleanUglifiedParameter) { + VD->printQualifiedName(OS, Policy); } else { - switch (VD->getKind()) { - case Decl::NonTypeTemplateParm: { - auto *TD = cast<NonTypeTemplateParmDecl>(VD); - OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << ""; - break; - } - case Decl::ParmVar: { - auto *PD = cast<ParmVarDecl>(VD); - OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-' - << PD->getFunctionScopeIndex(); - break; - } - case Decl::Decomposition: - OS << "decomposition"; - for (const auto &I : cast<DecompositionDecl>(VD)->bindings()) - OS << '-' << I->getName(); - break; - default: - OS << "unhandled-anonymous-" << VD->getDeclKindName(); - break; + Node->getQualifier().print(OS, Policy); + if (Node->hasTemplateKeyword()) + OS << "template "; + + DeclarationNameInfo NameInfo = Node->getNameInfo(); + if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo(); + !ForceAnonymous && (ID || NameInfo.getName().getNameKind() != + DeclarationName::Identifier)) { + if (CleanUglifiedParameter && ID) + OS << ID->deuglifiedName(); + else + NameInfo.printName(OS, Policy); + } else { + switch (VD->getKind()) { + case Decl::NonTypeTemplateParm: { + auto *TD = cast<NonTypeTemplateParmDecl>(VD); + OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() + << ""; + break; + } + case Decl::ParmVar: { + auto *PD = cast<ParmVarDecl>(VD); + OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-' + << PD->getFunctionScopeIndex(); + break; + } + case Decl::Decomposition: + OS << "decomposition"; + for (const auto &I : cast<DecompositionDecl>(VD)->bindings()) + OS << '-' << I->getName(); + break; + default: + OS << "unhandled-anonymous-" << VD->getDeclKindName(); + break; + } } } if (Node->hasExplicitTemplateArgs()) { diff --git a/clang/unittests/AST/StmtPrinterTest.cpp b/clang/unittests/AST/StmtPrinterTest.cpp index 24ad5f30d9480..2b75253fa6698 100644 --- a/clang/unittests/AST/StmtPrinterTest.cpp +++ b/clang/unittests/AST/StmtPrinterTest.cpp @@ -297,6 +297,42 @@ TEST(StmtPrinter, TerseOutputWithLambdas) { [](PrintingPolicy &PP) { PP.TerseOutput = true; })); } +TEST(StmtPrinter, FullyQualifiedDeclRefExpr) { + auto FullyQualified = [](PrintingPolicy &Policy) { + Policy.FullyQualifiedName = true; + }; + + ASSERT_TRUE(PrintedStmtCXXMatches( + StdVer::CXX17, + R"cpp( + namespace ns { int value; } + using namespace ns; + void A() { (void)value; } + )cpp", + declRefExpr(to(varDecl(hasName("::ns::value")))).bind("id"), "ns::value", + FullyQualified)); + + ASSERT_TRUE(PrintedStmtCXXMatches( + StdVer::CXX17, + R"cpp( + namespace ns { template <class T> void func(); } + using namespace ns; + void A() { func<int>(); } + )cpp", + declRefExpr(to(functionDecl(hasName("::ns::func")))).bind("id"), + "ns::func<int>", FullyQualified)); + + ASSERT_TRUE(PrintedStmtCXXMatches( + StdVer::CXX17, "void A(int param) { (void)param; }", + declRefExpr(to(parmVarDecl(hasName("param")))).bind("id"), "param", + FullyQualified)); + + ASSERT_TRUE(PrintedStmtCXXMatches( + StdVer::CXX17, "void A() { int local = 0; (void)local; }", + declRefExpr(to(varDecl(hasName("local")))).bind("id"), "local", + FullyQualified)); +} + TEST(StmtPrinter, ParamsUglified) { llvm::StringLiteral Code = R"cpp( template <typename _T, int _I, template <typename> class _C> @@ -307,6 +343,10 @@ TEST(StmtPrinter, ParamsUglified) { auto Clean = [](PrintingPolicy &Policy) { Policy.CleanUglifiedParameters = true; }; + auto CleanFullyQualified = [](PrintingPolicy &Policy) { + Policy.CleanUglifiedParameters = true; + Policy.FullyQualifiedName = true; + }; ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX14, Code, returnStmt().bind("id"), @@ -314,4 +354,7 @@ TEST(StmtPrinter, ParamsUglified) { ASSERT_TRUE( PrintedStmtCXXMatches(StdVer::CXX14, Code, returnStmt().bind("id"), "return typename C<T>::_F(I, j);\n", Clean)); + ASSERT_TRUE(PrintedStmtCXXMatches( + StdVer::CXX14, Code, returnStmt().bind("id"), + "return typename _C<T>::_F(I, j);\n", CleanFullyQualified)); } diff --git a/clang/unittests/AST/TypePrinterTest.cpp b/clang/unittests/AST/TypePrinterTest.cpp index 5023b5e093ec3..79f75909c57b5 100644 --- a/clang/unittests/AST/TypePrinterTest.cpp +++ b/clang/unittests/AST/TypePrinterTest.cpp @@ -121,6 +121,30 @@ TEST(TypePrinter, TemplateSpecializationFullyQualified) { [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; })); } +TEST(TypePrinter, TemplateArgumentExpressionFullyQualified) { + llvm::StringLiteral Code = R"cpp( + namespace ns { + template <class T> inline constexpr bool pred_v = sizeof(T) > 0; + template <bool, class T> struct ei {}; + template <class T> struct ei<true, T> { using type = T; }; + template <bool B, class T> using enable_if_t = typename ei<B, T>::type; + struct Ret {}; + template <class T> enable_if_t<pred_v<T>, Ret> f() { return {}; } + } + inline auto *ns_f_int = &ns::f<int>; + )cpp"; + + auto Matcher = functionDecl(hasName("::ns::f"), isTemplateInstantiation(), + returns(qualType().bind("id"))); + ASSERT_TRUE(PrintedTypeMatches( + Code, {"-std=c++17"}, Matcher, "enable_if_t<pred_v<int>, Ret>", + [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; })); + ASSERT_TRUE(PrintedTypeMatches( + Code, {"-std=c++17"}, Matcher, + "ns::enable_if_t<ns::pred_v<int>, ns::Ret>", + [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; })); +} + TEST(TypePrinter, TemplateIdWithNTTP) { constexpr char Code[] = R"cpp( template <int N> `````````` </details> https://github.com/llvm/llvm-project/pull/206041 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
