diff options
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 77 |
1 files changed, 62 insertions, 15 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 13c156b..74b9f4e 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2238,6 +2238,9 @@ maybe_emit_vtables (tree ctype) enum { VISIBILITY_ANON = VISIBILITY_INTERNAL+1 }; +static int expr_visibility (tree); +static int type_visibility (tree); + /* walk_tree helper function for type_visibility. */ static tree @@ -2257,9 +2260,55 @@ min_vis_r (tree *tp, int *walk_subtrees, void *data) else if (CLASS_TYPE_P (*tp) && CLASSTYPE_VISIBILITY (*tp) > *vis_p) *vis_p = CLASSTYPE_VISIBILITY (*tp); + else if (TREE_CODE (*tp) == ARRAY_TYPE + && uses_template_parms (TYPE_DOMAIN (*tp))) + { + int evis = expr_visibility (TYPE_MAX_VALUE (TYPE_DOMAIN (*tp))); + if (evis > *vis_p) + *vis_p = evis; + } return NULL; } +/* walk_tree helper function for expr_visibility. */ + +static tree +min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data) +{ + int *vis_p = (int *)data; + int tpvis = VISIBILITY_DEFAULT; + + switch (TREE_CODE (*tp)) + { + case CAST_EXPR: + case IMPLICIT_CONV_EXPR: + case STATIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: + case CONST_CAST_EXPR: + case DYNAMIC_CAST_EXPR: + case NEW_EXPR: + case CONSTRUCTOR: + tpvis = type_visibility (TREE_TYPE (*tp)); + break; + + case VAR_DECL: + case FUNCTION_DECL: + if (! TREE_PUBLIC (*tp)) + tpvis = VISIBILITY_ANON; + else + tpvis = DECL_VISIBILITY (*tp); + break; + + default: + break; + } + + if (tpvis > *vis_p) + *vis_p = tpvis; + + return NULL_TREE; +} + /* Returns the visibility of TYPE, which is the minimum visibility of its component types. */ @@ -2271,6 +2320,18 @@ type_visibility (tree type) return vis; } +/* Returns the visibility of an expression EXPR that appears in the signature + of a function template, which is the minimum visibility of names that appear + in its mangling. */ + +static int +expr_visibility (tree expr) +{ + int vis = VISIBILITY_DEFAULT; + cp_walk_tree_without_duplicates (&expr, min_vis_expr_r, &vis); + return vis; +} + /* Limit the visibility of DECL to VISIBILITY, if not explicitly specified (or if VISIBILITY is static). If TMPL is true, this constraint is for a template argument, and takes precedence @@ -2329,21 +2390,7 @@ constrain_visibility_for_template (tree decl, tree targs) if (TYPE_P (arg)) vis = type_visibility (arg); else - { - if (REFERENCE_REF_P (arg)) - arg = TREE_OPERAND (arg, 0); - if (TREE_TYPE (arg)) - STRIP_NOPS (arg); - if (TREE_CODE (arg) == ADDR_EXPR) - arg = TREE_OPERAND (arg, 0); - if (VAR_OR_FUNCTION_DECL_P (arg)) - { - if (! TREE_PUBLIC (arg)) - vis = VISIBILITY_ANON; - else - vis = DECL_VISIBILITY (arg); - } - } + vis = expr_visibility (arg); if (vis) constrain_visibility (decl, vis, true); } |