[clang] 82507b4 - [clang] Add visibility to AST dump (#218113)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 26 03:18:48 PDT 2026
Author: Vlad Serebrennikov
Date: 2026-08-26T14:18:43+04:00
New Revision: 82507b433507e06e795fa13afb7cb2b20402c1da
URL: https://github.com/llvm/llvm-project/commit/82507b433507e06e795fa13afb7cb2b20402c1da
DIFF: https://github.com/llvm/llvm-project/commit/82507b433507e06e795fa13afb7cb2b20402c1da.diff
LOG: [clang] Add visibility to AST dump (#218113)
Similarly to https://github.com/llvm/llvm-project/pull/194600, this PR
adds visibility information (default/hidden/protected) to AST dump in
exactly the same places where linkage is printed. As with no linkage,
default visibility is assumed and not printed, as it's so common that I
didn't have to update any of the existing tests.
Added:
clang/test/AST/ast-dump-visibility.cpp
Modified:
clang/include/clang/AST/TextNodeDumper.h
clang/lib/AST/TextNodeDumper.cpp
clang/lib/AST/Type.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index 1cdd8c37c7fc6..7219a0d3f8e50 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -208,7 +208,7 @@ class TextNodeDumper
void dumpType(QualType T);
void dumpBareDeclRef(const Decl *D);
void dumpName(const NamedDecl *ND);
- void dumpFormalLinkage(const NamedDecl *ND);
+ void dumpLinkageAndVisibility(const NamedDecl *ND);
void dumpAccessSpecifier(AccessSpecifier AS);
void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);
void dumpTemplateSpecializationKind(TemplateSpecializationKind TSK);
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index f58cc4f5761b7..f10753fe675d8 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1456,7 +1456,7 @@ static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
OS << ')';
}
-void TextNodeDumper::dumpFormalLinkage(const NamedDecl *ND) {
+void TextNodeDumper::dumpLinkageAndVisibility(const NamedDecl *ND) {
switch (ND->getFormalLinkage()) {
case Linkage::None:
// A lot of declarations have no linkage, so we only dump linkage if there
@@ -1477,6 +1477,19 @@ void TextNodeDumper::dumpFormalLinkage(const NamedDecl *ND) {
case Linkage::VisibleNone:
llvm_unreachable("Not a formal linkage!");
}
+
+ switch (ND->getVisibility()) {
+ case Visibility::DefaultVisibility:
+ // A lot of declarations have default visibility, so we only dump other
+ // kinds of visibility.
+ break;
+ case Visibility::HiddenVisibility:
+ OS << " hidden-visibility";
+ break;
+ case Visibility::ProtectedVisibility:
+ OS << " protected-visibility";
+ break;
+ }
}
void TextNodeDumper::VisitLoopControlStmt(const LoopControlStmt *Node) {
@@ -2382,7 +2395,7 @@ void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
const TagDecl *TD = D->getUnderlyingType()->getAsTagDecl();
if (TD && TD->getTypedefNameForAnonDecl()) {
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
}
@@ -2404,7 +2417,7 @@ void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
dumpPointer(Instance);
}
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
@@ -2416,7 +2429,7 @@ void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
OS << " definition";
if (!D->isImplicit() && !D->getDescribedTemplate()) {
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
}
@@ -2517,7 +2530,7 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
}
if (!isa<CXXDeductionGuideDecl>(D) && !D->getDescribedTemplate()) {
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
}
@@ -2621,7 +2634,7 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
}
if (!D->getDescribedVarTemplate()) {
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
}
@@ -2740,7 +2753,7 @@ void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
if (!D->isFirstDecl())
dumpDeclRef(D->getFirstDecl(), "original");
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
@@ -2759,14 +2772,14 @@ void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
const TagDecl *TD = D->getUnderlyingType()->getAsTagDecl();
if (TD && TD->getTypedefNameForAnonDecl()) {
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
}
void TextNodeDumper::VisitTypeAliasTemplateDecl(
const TypeAliasTemplateDecl *D) {
dumpName(D);
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
@@ -2927,17 +2940,17 @@ void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
dumpName(D);
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
dumpName(D);
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
dumpName(D);
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
@@ -3248,7 +3261,7 @@ void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
dumpName(D);
- dumpFormalLinkage(D);
+ dumpLinkageAndVisibility(D);
}
void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index b92dec99613f7..48da2451dc40f 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -5150,9 +5150,8 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
return computeTypeLinkageInfo(
cast<OverflowBehaviorType>(T)->getUnderlyingType());
case Type::HLSLAttributedResource:
- return computeTypeLinkageInfo(cast<HLSLAttributedResourceType>(T)
- ->getContainedType()
- ->getCanonicalTypeInternal());
+ return computeTypeLinkageInfo(
+ cast<HLSLAttributedResourceType>(T)->getWrappedType());
case Type::HLSLInlineSpirv:
return LinkageInfo::external();
}
diff --git a/clang/test/AST/ast-dump-visibility.cpp b/clang/test/AST/ast-dump-visibility.cpp
new file mode 100644
index 0000000000000..59ba3c23c4cad
--- /dev/null
+++ b/clang/test/AST/ast-dump-visibility.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -ast-dump -std=c++2c -triple x86_64-unknown-linux-gnu -fms-extensions %s | FileCheck --match-full-lines --check-prefix=CHECK %s
+
+int a1;
+// CHECK: |-VarDecl {{.*}} a1 'int' external-linkage
+
+[[gnu::visibility("default")]] int a2;
+// CHECK: |-VarDecl {{.*}} a2 'int' external-linkage
+
+__declspec(dllexport) int a3;
+// CHECK: |-VarDecl {{.*}} a3 'int' external-linkage
+
+[[gnu::visibility("hidden")]] int b;
+// CHECK: |-VarDecl {{.*}} b 'int' external-linkage hidden-visibility
+
+[[gnu::visibility("protected")]] int c;
+// CHECK: `-VarDecl {{.*}} c 'int' external-linkage protected-visibility
More information about the cfe-commits
mailing list