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(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(T)->getUnderlyingType()); case Type::HLSLAttributedResource: - return computeTypeLinkageInfo(cast(T) - ->getContainedType() - ->getCanonicalTypeInternal()); + return computeTypeLinkageInfo( + cast(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