diff options
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 078ca99e6f8..41af32faec4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -991,11 +991,8 @@ is_late_template_attribute (tree attr, tree decl) /* Unknown attribute. */ return false; - /* Attribute vector_size handling wants to dive into the back end array - building code, which breaks during template processing. */ - if (is_attribute_p ("vector_size", name) - /* Attribute weak handling wants to write out assembly right away. */ - || is_attribute_p ("weak", name)) + /* Attribute weak handling wants to write out assembly right away. */ + if (is_attribute_p ("weak", name)) return true; /* If any of the arguments are dependent expressions, we can't evaluate @@ -1120,6 +1117,62 @@ save_template_attributes (tree *attr_p, tree *decl_p) } } +/* Like reconstruct_complex_type, but handle also template trees. */ + +tree +cp_reconstruct_complex_type (tree type, tree bottom) +{ + tree inner, outer; + + if (TREE_CODE (type) == POINTER_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_pointer_type_for_mode (inner, TYPE_MODE (type), + TYPE_REF_CAN_ALIAS_ALL (type)); + } + else if (TREE_CODE (type) == REFERENCE_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_reference_type_for_mode (inner, TYPE_MODE (type), + TYPE_REF_CAN_ALIAS_ALL (type)); + } + else if (TREE_CODE (type) == ARRAY_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_cplus_array_type (inner, TYPE_DOMAIN (type)); + /* Don't call cp_build_qualified_type on ARRAY_TYPEs, the + element type qualification will be handled by the recursive + cp_reconstruct_complex_type call and cp_build_qualified_type + for ARRAY_TYPEs changes the element type. */ + return outer; + } + else if (TREE_CODE (type) == FUNCTION_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_function_type (inner, TYPE_ARG_TYPES (type)); + } + else if (TREE_CODE (type) == METHOD_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + /* The build_method_type_directly() routine prepends 'this' to argument list, + so we must compensate by getting rid of it. */ + outer + = build_method_type_directly + (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))), + inner, + TREE_CHAIN (TYPE_ARG_TYPES (type))); + } + else if (TREE_CODE (type) == OFFSET_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner); + } + else + return bottom; + + return cp_build_qualified_type (outer, TYPE_QUALS (type)); +} + /* Like decl_attributes, but handle C++ complexity. */ void |