@@ -970,11 +970,32 @@ void NamedDecl::verifyLinkage() const {
970
970
971
971
Optional<Visibility>
972
972
NamedDecl::getExplicitVisibility (ExplicitVisibilityKind kind) const {
973
- // Use the most recent declaration of a variable.
974
- if (const VarDecl *Var = dyn_cast<VarDecl>(this )) {
975
- if (Optional<Visibility> V = getVisibilityOf (Var, kind))
976
- return V;
973
+ // Check the declaration itself first.
974
+ if (Optional<Visibility> V = getVisibilityOf (this , kind))
975
+ return V;
976
+
977
+ // If this is a member class of a specialization of a class template
978
+ // and the corresponding decl has explicit visibility, use that.
979
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(this )) {
980
+ CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass ();
981
+ if (InstantiatedFrom)
982
+ return getVisibilityOf (InstantiatedFrom, kind);
983
+ }
977
984
985
+ // If there wasn't explicit visibility there, and this is a
986
+ // specialization of a class template, check for visibility
987
+ // on the pattern.
988
+ if (const ClassTemplateSpecializationDecl *spec
989
+ = dyn_cast<ClassTemplateSpecializationDecl>(this ))
990
+ return getVisibilityOf (spec->getSpecializedTemplate ()->getTemplatedDecl (),
991
+ kind);
992
+
993
+ // Use the most recent declaration.
994
+ const NamedDecl *MostRecent = cast<NamedDecl>(this ->getMostRecentDecl ());
995
+ if (MostRecent != this )
996
+ return MostRecent->getExplicitVisibility (kind);
997
+
998
+ if (const VarDecl *Var = dyn_cast<VarDecl>(this )) {
978
999
if (Var->isStaticDataMember ()) {
979
1000
VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember ();
980
1001
if (InstantiatedFrom)
@@ -983,12 +1004,8 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
983
1004
984
1005
return None;
985
1006
}
986
- // Use the most recent declaration of a function, and also handle
987
- // function template specializations.
1007
+ // Also handle function template specializations.
988
1008
if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(this )) {
989
- if (Optional<Visibility> V = getVisibilityOf (fn, kind))
990
- return V;
991
-
992
1009
// If the function is a specialization of a template with an
993
1010
// explicit visibility attribute, use that.
994
1011
if (FunctionTemplateSpecializationInfo *templateInfo
@@ -1005,30 +1022,10 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
1005
1022
return None;
1006
1023
}
1007
1024
1008
- // Otherwise, just check the declaration itself first.
1009
- if (Optional<Visibility> V = getVisibilityOf (this , kind))
1010
- return V;
1011
-
1012
1025
// The visibility of a template is stored in the templated decl.
1013
1026
if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(this ))
1014
1027
return getVisibilityOf (TD->getTemplatedDecl (), kind);
1015
1028
1016
- // If there wasn't explicit visibility there, and this is a
1017
- // specialization of a class template, check for visibility
1018
- // on the pattern.
1019
- if (const ClassTemplateSpecializationDecl *spec
1020
- = dyn_cast<ClassTemplateSpecializationDecl>(this ))
1021
- return getVisibilityOf (spec->getSpecializedTemplate ()->getTemplatedDecl (),
1022
- kind);
1023
-
1024
- // If this is a member class of a specialization of a class template
1025
- // and the corresponding decl has explicit visibility, use that.
1026
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(this )) {
1027
- CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass ();
1028
- if (InstantiatedFrom)
1029
- return getVisibilityOf (InstantiatedFrom, kind);
1030
- }
1031
-
1032
1029
return None;
1033
1030
}
1034
1031
0 commit comments