mangle.c revision 90075
190075Sobrien/* Name mangling for the 3.0 C++ ABI. 290075Sobrien Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. 390075Sobrien Written by Alex Samuel <sameul@codesourcery.com> 490075Sobrien 590075Sobrien This file is part of GNU CC. 690075Sobrien 790075Sobrien GNU CC is free software; you can redistribute it and/or modify it 890075Sobrien under the terms of the GNU General Public License as published by 990075Sobrien the Free Software Foundation; either version 2, or (at your option) 1090075Sobrien any later version. 1190075Sobrien 1290075Sobrien GNU CC is distributed in the hope that it will be useful, but 1390075Sobrien WITHOUT ANY WARRANTY; without even the implied warranty of 1490075Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1590075Sobrien General Public License for more details. 1690075Sobrien 1790075Sobrien You should have received a copy of the GNU General Public License 1890075Sobrien along with GNU CC; see the file COPYING. If not, write to the Free 1990075Sobrien Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2090075Sobrien 02111-1307, USA. */ 2190075Sobrien 2290075Sobrien/* This file implements mangling of C++ names according to the IA64 2390075Sobrien C++ ABI specification. A mangled name encodes a function or 2490075Sobrien variable's name, scope, type, and/or template arguments into a text 2590075Sobrien identifier. This identifier is used as the function's or 2690075Sobrien variable's linkage name, to preserve compatibility between C++'s 2790075Sobrien language features (templates, scoping, and overloading) and C 2890075Sobrien linkers. 2990075Sobrien 3090075Sobrien Additionally, g++ uses mangled names internally. To support this, 3190075Sobrien mangling of types is allowed, even though the mangled name of a 3290075Sobrien type should not appear by itself as an exported name. Ditto for 3390075Sobrien uninstantiated templates. 3490075Sobrien 3590075Sobrien The primary entry point for this module is mangle_decl, which 3690075Sobrien returns an identifier containing the mangled name for a decl. 3790075Sobrien Additional entry points are provided to build mangled names of 3890075Sobrien particular constructs when the appropriate decl for that construct 3990075Sobrien is not available. These are: 4090075Sobrien 4190075Sobrien mangle_typeinfo_for_type: typeinfo data 4290075Sobrien mangle_typeinfo_string_for_type: typeinfo type name 4390075Sobrien mangle_vtbl_for_type: virtual table data 4490075Sobrien mangle_vtt_for_type: VTT data 4590075Sobrien mangle_ctor_vtbl_for_type: `C-in-B' constructor virtual table data 4690075Sobrien mangle_thunk: thunk function or entry 4790075Sobrien 4890075Sobrien*/ 4990075Sobrien 5090075Sobrien#include "config.h" 5190075Sobrien#include "system.h" 5290075Sobrien#include "tree.h" 5390075Sobrien#include "cp-tree.h" 5490075Sobrien#include "obstack.h" 5590075Sobrien#include "toplev.h" 5690075Sobrien#include "varray.h" 5790075Sobrien 5890075Sobrien/* Debugging support. */ 5990075Sobrien 6090075Sobrien/* Define DEBUG_MANGLE to enable very verbose trace messages. */ 6190075Sobrien#ifndef DEBUG_MANGLE 6290075Sobrien#define DEBUG_MANGLE 0 6390075Sobrien#endif 6490075Sobrien 6590075Sobrien/* Macros for tracing the write_* functions. */ 6690075Sobrien#if DEBUG_MANGLE 6790075Sobrien# define MANGLE_TRACE(FN, INPUT) \ 6890075Sobrien fprintf (stderr, " %-24s: %-24s\n", (FN), (INPUT)) 6990075Sobrien# define MANGLE_TRACE_TREE(FN, NODE) \ 7090075Sobrien fprintf (stderr, " %-24s: %-24s (%p)\n", \ 7190075Sobrien (FN), tree_code_name[TREE_CODE (NODE)], (void *) (NODE)) 7290075Sobrien#else 7390075Sobrien# define MANGLE_TRACE(FN, INPUT) 7490075Sobrien# define MANGLE_TRACE_TREE(FN, NODE) 7590075Sobrien#endif 7690075Sobrien 7790075Sobrien/* Non-zero if NODE is a class template-id. We can't rely on 7890075Sobrien CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser 7990075Sobrien that hard to distinguish A<T> from A, where A<T> is the type as 8090075Sobrien instantiated outside of the template, and A is the type used 8190075Sobrien without parameters inside the template. */ 8290075Sobrien#define CLASSTYPE_TEMPLATE_ID_P(NODE) \ 8390075Sobrien (TYPE_LANG_SPECIFIC (NODE) != NULL \ 8490075Sobrien && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ 8590075Sobrien && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))) 8690075Sobrien 8790075Sobrien/* Things we only need one of. This module is not reentrant. */ 8890075Sobrienstatic struct globals 8990075Sobrien{ 9090075Sobrien /* The name in which we're building the mangled name. */ 9190075Sobrien struct obstack name_obstack; 9290075Sobrien 9390075Sobrien /* An array of the current substitution candidates, in the order 9490075Sobrien we've seen them. */ 9590075Sobrien varray_type substitutions; 9690075Sobrien} G; 9790075Sobrien 9890075Sobrien/* Indices into subst_identifiers. These are identifiers used in 9990075Sobrien special substitution rules. */ 10090075Sobrientypedef enum 10190075Sobrien{ 10290075Sobrien SUBID_ALLOCATOR, 10390075Sobrien SUBID_BASIC_STRING, 10490075Sobrien SUBID_CHAR_TRAITS, 10590075Sobrien SUBID_BASIC_ISTREAM, 10690075Sobrien SUBID_BASIC_OSTREAM, 10790075Sobrien SUBID_BASIC_IOSTREAM, 10890075Sobrien SUBID_MAX 10990075Sobrien} 11090075Sobriensubstitution_identifier_index_t; 11190075Sobrien 11290075Sobrien/* For quick substitution checks, look up these common identifiers 11390075Sobrien once only. */ 11490075Sobrienstatic tree subst_identifiers[SUBID_MAX]; 11590075Sobrien 11690075Sobrien/* Single-letter codes for builtin integer types, defined in 11790075Sobrien <builtin-type>. These are indexed by integer_type_kind values. */ 11890075Sobrienstatic char 11990075Sobrieninteger_type_codes[itk_none] = 12090075Sobrien{ 12190075Sobrien 'c', /* itk_char */ 12290075Sobrien 'a', /* itk_signed_char */ 12390075Sobrien 'h', /* itk_unsigned_char */ 12490075Sobrien 's', /* itk_short */ 12590075Sobrien 't', /* itk_unsigned_short */ 12690075Sobrien 'i', /* itk_int */ 12790075Sobrien 'j', /* itk_unsigned_int */ 12890075Sobrien 'l', /* itk_long */ 12990075Sobrien 'm', /* itk_unsigned_long */ 13090075Sobrien 'x', /* itk_long_long */ 13190075Sobrien 'y' /* itk_unsigned_long_long */ 13290075Sobrien}; 13390075Sobrien 13490075Sobrienstatic int decl_is_template_id PARAMS ((tree, tree*)); 13590075Sobrien 13690075Sobrien/* Functions for handling substitutions. */ 13790075Sobrien 13890075Sobrienstatic inline tree canonicalize_for_substitution PARAMS ((tree)); 13990075Sobrienstatic void add_substitution PARAMS ((tree)); 14090075Sobrienstatic inline int is_std_substitution PARAMS ((tree, substitution_identifier_index_t)); 14190075Sobrienstatic inline int is_std_substitution_char PARAMS ((tree, substitution_identifier_index_t)); 14290075Sobrienstatic int find_substitution PARAMS ((tree)); 14390075Sobrien 14490075Sobrien/* Functions for emitting mangled representations of things. */ 14590075Sobrien 14690075Sobrienstatic void write_mangled_name PARAMS ((tree)); 14790075Sobrienstatic void write_encoding PARAMS ((tree)); 14890075Sobrienstatic void write_name PARAMS ((tree, int)); 14990075Sobrienstatic void write_unscoped_name PARAMS ((tree)); 15090075Sobrienstatic void write_unscoped_template_name PARAMS ((tree)); 15190075Sobrienstatic void write_nested_name PARAMS ((tree)); 15290075Sobrienstatic void write_prefix PARAMS ((tree)); 15390075Sobrienstatic void write_template_prefix PARAMS ((tree)); 15490075Sobrienstatic void write_unqualified_name PARAMS ((tree)); 15590075Sobrienstatic void write_source_name PARAMS ((tree)); 15690075Sobrienstatic int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned)); 15790075Sobrienstatic void write_number PARAMS ((unsigned HOST_WIDE_INT, int, 15890075Sobrien unsigned int)); 15990075Sobrienstatic void write_integer_cst PARAMS ((tree)); 16090075Sobrienstatic void write_identifier PARAMS ((const char *)); 16190075Sobrienstatic void write_special_name_constructor PARAMS ((tree)); 16290075Sobrienstatic void write_special_name_destructor PARAMS ((tree)); 16390075Sobrienstatic void write_type PARAMS ((tree)); 16490075Sobrienstatic int write_CV_qualifiers_for_type PARAMS ((tree)); 16590075Sobrienstatic void write_builtin_type PARAMS ((tree)); 16690075Sobrienstatic void write_function_type PARAMS ((tree)); 16790075Sobrienstatic void write_bare_function_type PARAMS ((tree, int, tree)); 16890075Sobrienstatic void write_method_parms PARAMS ((tree, int, tree)); 16990075Sobrienstatic void write_class_enum_type PARAMS ((tree)); 17090075Sobrienstatic void write_template_args PARAMS ((tree)); 17190075Sobrienstatic void write_expression PARAMS ((tree)); 17290075Sobrienstatic void write_template_arg_literal PARAMS ((tree)); 17390075Sobrienstatic void write_template_arg PARAMS ((tree)); 17490075Sobrienstatic void write_template_template_arg PARAMS ((tree)); 17590075Sobrienstatic void write_array_type PARAMS ((tree)); 17690075Sobrienstatic void write_pointer_to_member_type PARAMS ((tree)); 17790075Sobrienstatic void write_template_param PARAMS ((tree)); 17890075Sobrienstatic void write_template_template_param PARAMS ((tree)); 17990075Sobrienstatic void write_substitution PARAMS ((int)); 18090075Sobrienstatic int discriminator_for_local_entity PARAMS ((tree)); 18190075Sobrienstatic int discriminator_for_string_literal PARAMS ((tree, tree)); 18290075Sobrienstatic void write_discriminator PARAMS ((int)); 18390075Sobrienstatic void write_local_name PARAMS ((tree, tree, tree)); 18490075Sobrienstatic void dump_substitution_candidates PARAMS ((void)); 18590075Sobrienstatic const char *mangle_decl_string PARAMS ((tree)); 18690075Sobrien 18790075Sobrien/* Control functions. */ 18890075Sobrien 18990075Sobrienstatic inline void start_mangling PARAMS ((void)); 19090075Sobrienstatic inline const char *finish_mangling PARAMS ((void)); 19190075Sobrienstatic tree mangle_special_for_type PARAMS ((tree, const char *)); 19290075Sobrien 19390075Sobrien/* Foreign language functions. */ 19490075Sobrien 19590075Sobrienstatic void write_java_integer_type_codes PARAMS ((tree)); 19690075Sobrien 19790075Sobrien/* Append a single character to the end of the mangled 19890075Sobrien representation. */ 19990075Sobrien#define write_char(CHAR) \ 20090075Sobrien obstack_1grow (&G.name_obstack, (CHAR)) 20190075Sobrien 20290075Sobrien/* Append a sized buffer to the end of the mangled representation. */ 20390075Sobrien#define write_chars(CHAR, LEN) \ 20490075Sobrien obstack_grow (&G.name_obstack, (CHAR), (LEN)) 20590075Sobrien 20690075Sobrien/* Append a NUL-terminated string to the end of the mangled 20790075Sobrien representation. */ 20890075Sobrien#define write_string(STRING) \ 20990075Sobrien obstack_grow (&G.name_obstack, (STRING), strlen (STRING)) 21090075Sobrien 21190075Sobrien/* Return the position at which the next character will be appended to 21290075Sobrien the mangled representation. */ 21390075Sobrien#define mangled_position() \ 21490075Sobrien obstack_object_size (&G.name_obstack) 21590075Sobrien 21690075Sobrien/* Non-zero if NODE1 and NODE2 are both TREE_LIST nodes and have the 21790075Sobrien same purpose (context, which may be a type) and value (template 21890075Sobrien decl). See write_template_prefix for more information on what this 21990075Sobrien is used for. */ 22090075Sobrien#define NESTED_TEMPLATE_MATCH(NODE1, NODE2) \ 22190075Sobrien (TREE_CODE (NODE1) == TREE_LIST \ 22290075Sobrien && TREE_CODE (NODE2) == TREE_LIST \ 22390075Sobrien && ((TYPE_P (TREE_PURPOSE (NODE1)) \ 22490075Sobrien && same_type_p (TREE_PURPOSE (NODE1), TREE_PURPOSE (NODE2)))\ 22590075Sobrien || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \ 22690075Sobrien && TREE_VALUE (NODE1) == TREE_VALUE (NODE2)) 22790075Sobrien 22890075Sobrien/* Write out a signed quantity in base 10. */ 22990075Sobrien#define write_signed_number(NUMBER) \ 23090075Sobrien write_number ((NUMBER), /*unsigned_p=*/0, 10) 23190075Sobrien 23290075Sobrien/* Write out an unsigned quantity in base 10. */ 23390075Sobrien#define write_unsigned_number(NUMBER) \ 23490075Sobrien write_number ((NUMBER), /*unsigned_p=*/1, 10) 23590075Sobrien 23690075Sobrien/* If DECL is a template instance, return non-zero and, if 23790075Sobrien TEMPLATE_INFO is non-NULL, set *TEMPLATE_INFO to its template info. 23890075Sobrien Otherwise return zero. */ 23990075Sobrien 24090075Sobrienstatic int 24190075Sobriendecl_is_template_id (decl, template_info) 24290075Sobrien tree decl; 24390075Sobrien tree* template_info; 24490075Sobrien{ 24590075Sobrien if (TREE_CODE (decl) == TYPE_DECL) 24690075Sobrien { 24790075Sobrien /* TYPE_DECLs are handled specially. Look at its type to decide 24890075Sobrien if this is a template instantiation. */ 24990075Sobrien tree type = TREE_TYPE (decl); 25090075Sobrien 25190075Sobrien if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type)) 25290075Sobrien { 25390075Sobrien if (template_info != NULL) 25490075Sobrien /* For a templated TYPE_DECL, the template info is hanging 25590075Sobrien off the type. */ 25690075Sobrien *template_info = CLASSTYPE_TEMPLATE_INFO (type); 25790075Sobrien return 1; 25890075Sobrien } 25990075Sobrien } 26090075Sobrien else 26190075Sobrien { 26290075Sobrien /* Check if this is a primary template. */ 26390075Sobrien if (DECL_LANG_SPECIFIC (decl) != NULL 26490075Sobrien && DECL_USE_TEMPLATE (decl) 26590075Sobrien && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)) 26690075Sobrien && TREE_CODE (decl) != TEMPLATE_DECL) 26790075Sobrien { 26890075Sobrien if (template_info != NULL) 26990075Sobrien /* For most templated decls, the template info is hanging 27090075Sobrien off the decl. */ 27190075Sobrien *template_info = DECL_TEMPLATE_INFO (decl); 27290075Sobrien return 1; 27390075Sobrien } 27490075Sobrien } 27590075Sobrien 27690075Sobrien /* It's not a template id. */ 27790075Sobrien return 0; 27890075Sobrien} 27990075Sobrien 28090075Sobrien/* Produce debugging output of current substitution candidates. */ 28190075Sobrien 28290075Sobrienstatic void 28390075Sobriendump_substitution_candidates () 28490075Sobrien{ 28590075Sobrien unsigned i; 28690075Sobrien 28790075Sobrien fprintf (stderr, " ++ substitutions "); 28890075Sobrien for (i = 0; i < VARRAY_ACTIVE_SIZE (G.substitutions); ++i) 28990075Sobrien { 29090075Sobrien tree el = VARRAY_TREE (G.substitutions, i); 29190075Sobrien const char *name = "???"; 29290075Sobrien 29390075Sobrien if (i > 0) 29490075Sobrien fprintf (stderr, " "); 29590075Sobrien if (DECL_P (el)) 29690075Sobrien name = IDENTIFIER_POINTER (DECL_NAME (el)); 29790075Sobrien else if (TREE_CODE (el) == TREE_LIST) 29890075Sobrien name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el))); 29990075Sobrien else if (TYPE_NAME (el)) 30090075Sobrien name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (el))); 30190075Sobrien fprintf (stderr, " S%d_ = ", i - 1); 30290075Sobrien if (TYPE_P (el) && 30390075Sobrien (CP_TYPE_RESTRICT_P (el) 30490075Sobrien || CP_TYPE_VOLATILE_P (el) 30590075Sobrien || CP_TYPE_CONST_P (el))) 30690075Sobrien fprintf (stderr, "CV-"); 30790075Sobrien fprintf (stderr, "%s (%s at %p)\n", 30890075Sobrien name, tree_code_name[TREE_CODE (el)], (void *) el); 30990075Sobrien } 31090075Sobrien} 31190075Sobrien 31290075Sobrien/* Both decls and types can be substitution candidates, but sometimes 31390075Sobrien they refer to the same thing. For instance, a TYPE_DECL and 31490075Sobrien RECORD_TYPE for the same class refer to the same thing, and should 31590075Sobrien be treated accordinginly in substitutions. This function returns a 31690075Sobrien canonicalized tree node representing NODE that is used when adding 31790075Sobrien and substitution candidates and finding matches. */ 31890075Sobrien 31990075Sobrienstatic inline tree 32090075Sobriencanonicalize_for_substitution (node) 32190075Sobrien tree node; 32290075Sobrien{ 32390075Sobrien /* For a TYPE_DECL, use the type instead. */ 32490075Sobrien if (TREE_CODE (node) == TYPE_DECL) 32590075Sobrien node = TREE_TYPE (node); 32690075Sobrien if (TYPE_P (node)) 32790075Sobrien node = canonical_type_variant (node); 32890075Sobrien 32990075Sobrien return node; 33090075Sobrien} 33190075Sobrien 33290075Sobrien/* Add NODE as a substitution candidate. NODE must not already be on 33390075Sobrien the list of candidates. */ 33490075Sobrien 33590075Sobrienstatic void 33690075Sobrienadd_substitution (node) 33790075Sobrien tree node; 33890075Sobrien{ 33990075Sobrien tree c; 34090075Sobrien 34190075Sobrien if (DEBUG_MANGLE) 34290075Sobrien fprintf (stderr, " ++ add_substitution (%s at %10p)\n", 34390075Sobrien tree_code_name[TREE_CODE (node)], (void *) node); 34490075Sobrien 34590075Sobrien /* Get the canonicalized substitution candidate for NODE. */ 34690075Sobrien c = canonicalize_for_substitution (node); 34790075Sobrien if (DEBUG_MANGLE && c != node) 34890075Sobrien fprintf (stderr, " ++ using candidate (%s at %10p)\n", 34990075Sobrien tree_code_name[TREE_CODE (node)], (void *) node); 35090075Sobrien node = c; 35190075Sobrien 35290075Sobrien#if ENABLE_CHECKING 35390075Sobrien /* Make sure NODE isn't already a candidate. */ 35490075Sobrien { 35590075Sobrien int i; 35690075Sobrien for (i = VARRAY_ACTIVE_SIZE (G.substitutions); --i >= 0; ) 35790075Sobrien { 35890075Sobrien tree candidate = VARRAY_TREE (G.substitutions, i); 35990075Sobrien if ((DECL_P (node) 36090075Sobrien && node == candidate) 36190075Sobrien || (TYPE_P (node) 36290075Sobrien && TYPE_P (candidate) 36390075Sobrien && same_type_p (node, candidate))) 36490075Sobrien abort (); 36590075Sobrien } 36690075Sobrien } 36790075Sobrien#endif /* ENABLE_CHECKING */ 36890075Sobrien 36990075Sobrien /* Put the decl onto the varray of substitution candidates. */ 37090075Sobrien VARRAY_PUSH_TREE (G.substitutions, node); 37190075Sobrien 37290075Sobrien if (DEBUG_MANGLE) 37390075Sobrien dump_substitution_candidates (); 37490075Sobrien} 37590075Sobrien 37690075Sobrien/* Helper function for find_substitution. Returns non-zero if NODE, 37790075Sobrien which may be a decl or a CLASS_TYPE, is a template-id with template 37890075Sobrien name of substitution_index[INDEX] in the ::std namespace. */ 37990075Sobrien 38090075Sobrienstatic inline int 38190075Sobrienis_std_substitution (node, index) 38290075Sobrien tree node; 38390075Sobrien substitution_identifier_index_t index; 38490075Sobrien{ 38590075Sobrien tree type = NULL; 38690075Sobrien tree decl = NULL; 38790075Sobrien 38890075Sobrien if (DECL_P (node)) 38990075Sobrien { 39090075Sobrien type = TREE_TYPE (node); 39190075Sobrien decl = node; 39290075Sobrien } 39390075Sobrien else if (CLASS_TYPE_P (node)) 39490075Sobrien { 39590075Sobrien type = node; 39690075Sobrien decl = TYPE_NAME (node); 39790075Sobrien } 39890075Sobrien else 39990075Sobrien /* These are not the droids you're looking for. */ 40090075Sobrien return 0; 40190075Sobrien 40290075Sobrien return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) 40390075Sobrien && TYPE_LANG_SPECIFIC (type) 40490075Sobrien && CLASSTYPE_TEMPLATE_INFO (type) 40590075Sobrien && (DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) 40690075Sobrien == subst_identifiers[index])); 40790075Sobrien} 40890075Sobrien 40990075Sobrien/* Helper function for find_substitution. Returns non-zero if NODE, 41090075Sobrien which may be a decl or a CLASS_TYPE, is the template-id 41190075Sobrien ::std::identifier<char>, where identifier is 41290075Sobrien substitution_index[INDEX]. */ 41390075Sobrien 41490075Sobrienstatic inline int 41590075Sobrienis_std_substitution_char (node, index) 41690075Sobrien tree node; 41790075Sobrien substitution_identifier_index_t index; 41890075Sobrien{ 41990075Sobrien tree args; 42090075Sobrien /* Check NODE's name is ::std::identifier. */ 42190075Sobrien if (!is_std_substitution (node, index)) 42290075Sobrien return 0; 42390075Sobrien /* Figure out its template args. */ 42490075Sobrien if (DECL_P (node)) 42590075Sobrien args = DECL_TI_ARGS (node); 42690075Sobrien else if (CLASS_TYPE_P (node)) 42790075Sobrien args = CLASSTYPE_TI_ARGS (node); 42890075Sobrien else 42990075Sobrien /* Oops, not a template. */ 43090075Sobrien return 0; 43190075Sobrien /* NODE's template arg list should be <char>. */ 43290075Sobrien return 43390075Sobrien TREE_VEC_LENGTH (args) == 1 43490075Sobrien && TREE_VEC_ELT (args, 0) == char_type_node; 43590075Sobrien} 43690075Sobrien 43790075Sobrien/* Check whether a substitution should be used to represent NODE in 43890075Sobrien the mangling. 43990075Sobrien 44090075Sobrien First, check standard special-case substitutions. 44190075Sobrien 44290075Sobrien <substitution> ::= St 44390075Sobrien # ::std 44490075Sobrien 44590075Sobrien ::= Sa 44690075Sobrien # ::std::allocator 44790075Sobrien 44890075Sobrien ::= Sb 44990075Sobrien # ::std::basic_string 45090075Sobrien 45190075Sobrien ::= Ss 45290075Sobrien # ::std::basic_string<char, 45390075Sobrien ::std::char_traits<char>, 45490075Sobrien ::std::allocator<char> > 45590075Sobrien 45690075Sobrien ::= Si 45790075Sobrien # ::std::basic_istream<char, ::std::char_traits<char> > 45890075Sobrien 45990075Sobrien ::= So 46090075Sobrien # ::std::basic_ostream<char, ::std::char_traits<char> > 46190075Sobrien 46290075Sobrien ::= Sd 46390075Sobrien # ::std::basic_iostream<char, ::std::char_traits<char> > 46490075Sobrien 46590075Sobrien Then examine the stack of currently available substitution 46690075Sobrien candidates for entities appearing earlier in the same mangling 46790075Sobrien 46890075Sobrien If a substitution is found, write its mangled representation and 46990075Sobrien return non-zero. If none is found, just return zero. */ 47090075Sobrien 47190075Sobrienstatic int 47290075Sobrienfind_substitution (node) 47390075Sobrien tree node; 47490075Sobrien{ 47590075Sobrien int i; 47690075Sobrien int size = VARRAY_ACTIVE_SIZE (G.substitutions); 47790075Sobrien tree decl; 47890075Sobrien tree type; 47990075Sobrien 48090075Sobrien if (DEBUG_MANGLE) 48190075Sobrien fprintf (stderr, " ++ find_substitution (%s at %p)\n", 48290075Sobrien tree_code_name[TREE_CODE (node)], (void *) node); 48390075Sobrien 48490075Sobrien /* Obtain the canonicalized substitution representation for NODE. 48590075Sobrien This is what we'll compare against. */ 48690075Sobrien node = canonicalize_for_substitution (node); 48790075Sobrien 48890075Sobrien /* Check for builtin substitutions. */ 48990075Sobrien 49090075Sobrien decl = TYPE_P (node) ? TYPE_NAME (node) : node; 49190075Sobrien type = TYPE_P (node) ? node : TREE_TYPE (node); 49290075Sobrien 49390075Sobrien /* Check for std::allocator. */ 49490075Sobrien if (decl 49590075Sobrien && is_std_substitution (decl, SUBID_ALLOCATOR) 49690075Sobrien && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl))) 49790075Sobrien { 49890075Sobrien write_string ("Sa"); 49990075Sobrien return 1; 50090075Sobrien } 50190075Sobrien 50290075Sobrien /* Check for std::basic_string. */ 50390075Sobrien if (decl && is_std_substitution (decl, SUBID_BASIC_STRING)) 50490075Sobrien { 50590075Sobrien if (TYPE_P (node)) 50690075Sobrien { 50790075Sobrien /* If this is a type (i.e. a fully-qualified template-id), 50890075Sobrien check for 50990075Sobrien std::basic_string <char, 51090075Sobrien std::char_traits<char>, 51190075Sobrien std::allocator<char> > . */ 51290075Sobrien if (cp_type_quals (type) == TYPE_UNQUALIFIED 51390075Sobrien && CLASSTYPE_USE_TEMPLATE (type)) 51490075Sobrien { 51590075Sobrien tree args = CLASSTYPE_TI_ARGS (type); 51690075Sobrien if (TREE_VEC_LENGTH (args) == 3 51790075Sobrien && same_type_p (TREE_VEC_ELT (args, 0), char_type_node) 51890075Sobrien && is_std_substitution_char (TREE_VEC_ELT (args, 1), 51990075Sobrien SUBID_CHAR_TRAITS) 52090075Sobrien && is_std_substitution_char (TREE_VEC_ELT (args, 2), 52190075Sobrien SUBID_ALLOCATOR)) 52290075Sobrien { 52390075Sobrien write_string ("Ss"); 52490075Sobrien return 1; 52590075Sobrien } 52690075Sobrien } 52790075Sobrien } 52890075Sobrien else 52990075Sobrien /* Substitute for the template name only if this isn't a type. */ 53090075Sobrien { 53190075Sobrien write_string ("Sb"); 53290075Sobrien return 1; 53390075Sobrien } 53490075Sobrien } 53590075Sobrien 53690075Sobrien /* Check for basic_{i,o,io}stream. */ 53790075Sobrien if (TYPE_P (node) 53890075Sobrien && cp_type_quals (type) == TYPE_UNQUALIFIED 53990075Sobrien && CLASS_TYPE_P (type) 54090075Sobrien && CLASSTYPE_USE_TEMPLATE (type) 54190075Sobrien && CLASSTYPE_TEMPLATE_INFO (type) != NULL) 54290075Sobrien { 54390075Sobrien /* First, check for the template 54490075Sobrien args <char, std::char_traits<char> > . */ 54590075Sobrien tree args = CLASSTYPE_TI_ARGS (type); 54690075Sobrien if (TREE_VEC_LENGTH (args) == 2 54790075Sobrien && same_type_p (TREE_VEC_ELT (args, 0), char_type_node) 54890075Sobrien && is_std_substitution_char (TREE_VEC_ELT (args, 1), 54990075Sobrien SUBID_CHAR_TRAITS)) 55090075Sobrien { 55190075Sobrien /* Got them. Is this basic_istream? */ 55290075Sobrien tree name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)); 55390075Sobrien if (name == subst_identifiers[SUBID_BASIC_ISTREAM]) 55490075Sobrien { 55590075Sobrien write_string ("Si"); 55690075Sobrien return 1; 55790075Sobrien } 55890075Sobrien /* Or basic_ostream? */ 55990075Sobrien else if (name == subst_identifiers[SUBID_BASIC_OSTREAM]) 56090075Sobrien { 56190075Sobrien write_string ("So"); 56290075Sobrien return 1; 56390075Sobrien } 56490075Sobrien /* Or basic_iostream? */ 56590075Sobrien else if (name == subst_identifiers[SUBID_BASIC_IOSTREAM]) 56690075Sobrien { 56790075Sobrien write_string ("Sd"); 56890075Sobrien return 1; 56990075Sobrien } 57090075Sobrien } 57190075Sobrien } 57290075Sobrien 57390075Sobrien /* Check for namespace std. */ 57490075Sobrien if (decl && DECL_NAMESPACE_STD_P (decl)) 57590075Sobrien { 57690075Sobrien write_string ("St"); 57790075Sobrien return 1; 57890075Sobrien } 57990075Sobrien 58090075Sobrien /* Now check the list of available substitutions for this mangling 58190075Sobrien operation. */ 58290075Sobrien for (i = 0; i < size; ++i) 58390075Sobrien { 58490075Sobrien tree candidate = VARRAY_TREE (G.substitutions, i); 58590075Sobrien /* NODE is a matched to a candidate if it's the same decl node or 58690075Sobrien if it's the same type. */ 58790075Sobrien if (decl == candidate 58890075Sobrien || (TYPE_P (candidate) && type && TYPE_P (type) 58990075Sobrien && same_type_p (type, candidate)) 59090075Sobrien || NESTED_TEMPLATE_MATCH (node, candidate)) 59190075Sobrien { 59290075Sobrien write_substitution (i); 59390075Sobrien return 1; 59490075Sobrien } 59590075Sobrien } 59690075Sobrien 59790075Sobrien /* No substitution found. */ 59890075Sobrien return 0; 59990075Sobrien} 60090075Sobrien 60190075Sobrien 60290075Sobrien/* <mangled-name> ::= _Z <encoding> */ 60390075Sobrien 60490075Sobrienstatic inline void 60590075Sobrienwrite_mangled_name (decl) 60690075Sobrien tree decl; 60790075Sobrien{ 60890075Sobrien MANGLE_TRACE_TREE ("mangled-name", decl); 60990075Sobrien 61090075Sobrien if (DECL_LANG_SPECIFIC (decl) 61190075Sobrien && DECL_EXTERN_C_FUNCTION_P (decl) 61290075Sobrien && ! DECL_OVERLOADED_OPERATOR_P (decl)) 61390075Sobrien /* The standard notes: 61490075Sobrien "The <encoding> of an extern "C" function is treated like 61590075Sobrien global-scope data, i.e. as its <source-name> without a type." 61690075Sobrien We cannot write overloaded operators that way though, 61790075Sobrien because it contains characters invalid in assembler. */ 61890075Sobrien write_source_name (DECL_NAME (decl)); 61990075Sobrien else 62090075Sobrien /* C++ name; needs to be mangled. */ 62190075Sobrien { 62290075Sobrien write_string ("_Z"); 62390075Sobrien write_encoding (decl); 62490075Sobrien } 62590075Sobrien} 62690075Sobrien 62790075Sobrien/* <encoding> ::= <function name> <bare-function-type> 62890075Sobrien ::= <data name> */ 62990075Sobrien 63090075Sobrienstatic void 63190075Sobrienwrite_encoding (decl) 63290075Sobrien tree decl; 63390075Sobrien{ 63490075Sobrien MANGLE_TRACE_TREE ("encoding", decl); 63590075Sobrien 63690075Sobrien if (DECL_LANG_SPECIFIC (decl) && DECL_EXTERN_C_FUNCTION_P (decl)) 63790075Sobrien { 63890075Sobrien /* For overloaded operators write just the mangled name 63990075Sobrien without arguments. */ 64090075Sobrien if (DECL_OVERLOADED_OPERATOR_P (decl)) 64190075Sobrien write_name (decl, /*ignore_local_scope=*/0); 64290075Sobrien else 64390075Sobrien write_source_name (DECL_NAME (decl)); 64490075Sobrien return; 64590075Sobrien } 64690075Sobrien 64790075Sobrien write_name (decl, /*ignore_local_scope=*/0); 64890075Sobrien if (TREE_CODE (decl) == FUNCTION_DECL) 64990075Sobrien { 65090075Sobrien tree fn_type; 65190075Sobrien 65290075Sobrien if (decl_is_template_id (decl, NULL)) 65390075Sobrien fn_type = get_mostly_instantiated_function_type (decl, NULL, NULL); 65490075Sobrien else 65590075Sobrien fn_type = TREE_TYPE (decl); 65690075Sobrien 65790075Sobrien write_bare_function_type (fn_type, 65890075Sobrien (!DECL_CONSTRUCTOR_P (decl) 65990075Sobrien && !DECL_DESTRUCTOR_P (decl) 66090075Sobrien && !DECL_CONV_FN_P (decl) 66190075Sobrien && decl_is_template_id (decl, NULL)), 66290075Sobrien decl); 66390075Sobrien } 66490075Sobrien} 66590075Sobrien 66690075Sobrien/* <name> ::= <unscoped-name> 66790075Sobrien ::= <unscoped-template-name> <template-args> 66890075Sobrien ::= <nested-name> 66990075Sobrien ::= <local-name> 67090075Sobrien 67190075Sobrien If IGNORE_LOCAL_SCOPE is non-zero, this production of <name> is 67290075Sobrien called from <local-name>, which mangles the enclosing scope 67390075Sobrien elsewhere and then uses this function to mangle just the part 67490075Sobrien underneath the function scope. So don't use the <local-name> 67590075Sobrien production, to avoid an infinite recursion. */ 67690075Sobrien 67790075Sobrienstatic void 67890075Sobrienwrite_name (decl, ignore_local_scope) 67990075Sobrien tree decl; 68090075Sobrien int ignore_local_scope; 68190075Sobrien{ 68290075Sobrien tree context; 68390075Sobrien 68490075Sobrien MANGLE_TRACE_TREE ("name", decl); 68590075Sobrien 68690075Sobrien if (TREE_CODE (decl) == TYPE_DECL) 68790075Sobrien { 68890075Sobrien /* In case this is a typedef, fish out the corresponding 68990075Sobrien TYPE_DECL for the main variant. */ 69090075Sobrien decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); 69190075Sobrien context = TYPE_CONTEXT (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); 69290075Sobrien } 69390075Sobrien else 69490075Sobrien context = (DECL_CONTEXT (decl) == NULL) ? NULL : CP_DECL_CONTEXT (decl); 69590075Sobrien 69690075Sobrien /* A decl in :: or ::std scope is treated specially. The former is 69790075Sobrien mangled using <unscoped-name> or <unscoped-template-name>, the 69890075Sobrien latter with a special substitution. Also, a name that is 69990075Sobrien directly in a local function scope is also mangled with 70090075Sobrien <unscoped-name> rather than a full <nested-name>. */ 70190075Sobrien if (context == NULL 70290075Sobrien || context == global_namespace 70390075Sobrien || DECL_NAMESPACE_STD_P (context) 70490075Sobrien || (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL)) 70590075Sobrien { 70690075Sobrien tree template_info; 70790075Sobrien /* Is this a template instance? */ 70890075Sobrien if (decl_is_template_id (decl, &template_info)) 70990075Sobrien { 71090075Sobrien /* Yes: use <unscoped-template-name>. */ 71190075Sobrien write_unscoped_template_name (TI_TEMPLATE (template_info)); 71290075Sobrien write_template_args (TI_ARGS (template_info)); 71390075Sobrien } 71490075Sobrien else 71590075Sobrien /* Everything else gets an <unqualified-name>. */ 71690075Sobrien write_unscoped_name (decl); 71790075Sobrien } 71890075Sobrien else 71990075Sobrien { 72090075Sobrien /* Handle local names, unless we asked not to (that is, invoked 72190075Sobrien under <local-name>, to handle only the part of the name under 72290075Sobrien the local scope). */ 72390075Sobrien if (!ignore_local_scope) 72490075Sobrien { 72590075Sobrien /* Scan up the list of scope context, looking for a 72690075Sobrien function. If we find one, this entity is in local 72790075Sobrien function scope. local_entity tracks context one scope 72890075Sobrien level down, so it will contain the element that's 72990075Sobrien directly in that function's scope, either decl or one of 73090075Sobrien its enclosing scopes. */ 73190075Sobrien tree local_entity = decl; 73290075Sobrien while (context != NULL && context != global_namespace) 73390075Sobrien { 73490075Sobrien /* Make sure we're always dealing with decls. */ 73590075Sobrien if (context != NULL && TYPE_P (context)) 73690075Sobrien context = TYPE_NAME (context); 73790075Sobrien /* Is this a function? */ 73890075Sobrien if (TREE_CODE (context) == FUNCTION_DECL) 73990075Sobrien { 74090075Sobrien /* Yes, we have local scope. Use the <local-name> 74190075Sobrien production for the innermost function scope. */ 74290075Sobrien write_local_name (context, local_entity, decl); 74390075Sobrien return; 74490075Sobrien } 74590075Sobrien /* Up one scope level. */ 74690075Sobrien local_entity = context; 74790075Sobrien context = CP_DECL_CONTEXT (context); 74890075Sobrien } 74990075Sobrien 75090075Sobrien /* No local scope found? Fall through to <nested-name>. */ 75190075Sobrien } 75290075Sobrien 75390075Sobrien /* Other decls get a <nested-name> to encode their scope. */ 75490075Sobrien write_nested_name (decl); 75590075Sobrien } 75690075Sobrien} 75790075Sobrien 75890075Sobrien/* <unscoped-name> ::= <unqualified-name> 75990075Sobrien ::= St <unqualified-name> # ::std:: */ 76090075Sobrien 76190075Sobrienstatic void 76290075Sobrienwrite_unscoped_name (decl) 76390075Sobrien tree decl; 76490075Sobrien{ 76590075Sobrien tree context = CP_DECL_CONTEXT (decl); 76690075Sobrien 76790075Sobrien MANGLE_TRACE_TREE ("unscoped-name", decl); 76890075Sobrien 76990075Sobrien /* Is DECL in ::std? */ 77090075Sobrien if (DECL_NAMESPACE_STD_P (context)) 77190075Sobrien { 77290075Sobrien write_string ("St"); 77390075Sobrien write_unqualified_name (decl); 77490075Sobrien } 77590075Sobrien /* If not, it should be either in the global namespace, or directly 77690075Sobrien in a local function scope. */ 77790075Sobrien else if (context == global_namespace 77890075Sobrien || context == NULL 77990075Sobrien || TREE_CODE (context) == FUNCTION_DECL) 78090075Sobrien write_unqualified_name (decl); 78190075Sobrien else 78290075Sobrien abort (); 78390075Sobrien} 78490075Sobrien 78590075Sobrien/* <unscoped-template-name> ::= <unscoped-name> 78690075Sobrien ::= <substitution> */ 78790075Sobrien 78890075Sobrienstatic void 78990075Sobrienwrite_unscoped_template_name (decl) 79090075Sobrien tree decl; 79190075Sobrien{ 79290075Sobrien MANGLE_TRACE_TREE ("unscoped-template-name", decl); 79390075Sobrien 79490075Sobrien if (find_substitution (decl)) 79590075Sobrien return; 79690075Sobrien write_unscoped_name (decl); 79790075Sobrien add_substitution (decl); 79890075Sobrien} 79990075Sobrien 80090075Sobrien/* Write the nested name, including CV-qualifiers, of DECL. 80190075Sobrien 80290075Sobrien <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E 80390075Sobrien ::= N [<CV-qualifiers>] <template-prefix> <template-args> E 80490075Sobrien 80590075Sobrien <CV-qualifiers> ::= [r] [V] [K] */ 80690075Sobrien 80790075Sobrienstatic void 80890075Sobrienwrite_nested_name (decl) 80990075Sobrien tree decl; 81090075Sobrien{ 81190075Sobrien tree template_info; 81290075Sobrien 81390075Sobrien MANGLE_TRACE_TREE ("nested-name", decl); 81490075Sobrien 81590075Sobrien write_char ('N'); 81690075Sobrien 81790075Sobrien /* Write CV-qualifiers, if this is a member function. */ 81890075Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 81990075Sobrien && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) 82090075Sobrien { 82190075Sobrien if (DECL_VOLATILE_MEMFUNC_P (decl)) 82290075Sobrien write_char ('V'); 82390075Sobrien if (DECL_CONST_MEMFUNC_P (decl)) 82490075Sobrien write_char ('K'); 82590075Sobrien } 82690075Sobrien 82790075Sobrien /* Is this a template instance? */ 82890075Sobrien if (decl_is_template_id (decl, &template_info)) 82990075Sobrien { 83090075Sobrien /* Yes, use <template-prefix>. */ 83190075Sobrien write_template_prefix (decl); 83290075Sobrien write_template_args (TI_ARGS (template_info)); 83390075Sobrien } 83490075Sobrien else 83590075Sobrien { 83690075Sobrien /* No, just use <prefix> */ 83790075Sobrien write_prefix (DECL_CONTEXT (decl)); 83890075Sobrien write_unqualified_name (decl); 83990075Sobrien } 84090075Sobrien write_char ('E'); 84190075Sobrien} 84290075Sobrien 84390075Sobrien/* <prefix> ::= <prefix> <unqualified-name>> 84490075Sobrien ::= <template-prefix> <template-args> 84590075Sobrien ::= # empty 84690075Sobrien ::= <substitution> */ 84790075Sobrien 84890075Sobrienstatic void 84990075Sobrienwrite_prefix (node) 85090075Sobrien tree node; 85190075Sobrien{ 85290075Sobrien tree decl; 85390075Sobrien /* Non-NULL if NODE represents a template-id. */ 85490075Sobrien tree template_info = NULL; 85590075Sobrien 85690075Sobrien MANGLE_TRACE_TREE ("prefix", node); 85790075Sobrien 85890075Sobrien if (node == NULL 85990075Sobrien || node == global_namespace) 86090075Sobrien return; 86190075Sobrien 86290075Sobrien if (find_substitution (node)) 86390075Sobrien return; 86490075Sobrien 86590075Sobrien if (DECL_P (node)) 86690075Sobrien /* Node is a decl. */ 86790075Sobrien { 86890075Sobrien /* If this is a function decl, that means we've hit function 86990075Sobrien scope, so this prefix must be for a local name. In this 87090075Sobrien case, we're under the <local-name> production, which encodes 87190075Sobrien the enclosing function scope elsewhere. So don't continue 87290075Sobrien here. */ 87390075Sobrien if (TREE_CODE (node) == FUNCTION_DECL) 87490075Sobrien return; 87590075Sobrien 87690075Sobrien decl = node; 87790075Sobrien decl_is_template_id (decl, &template_info); 87890075Sobrien } 87990075Sobrien else 88090075Sobrien /* Node is a type. */ 88190075Sobrien { 88290075Sobrien decl = TYPE_NAME (node); 88390075Sobrien if (CLASSTYPE_TEMPLATE_ID_P (node)) 88490075Sobrien template_info = CLASSTYPE_TEMPLATE_INFO (node); 88590075Sobrien } 88690075Sobrien 88790075Sobrien if (template_info != NULL) 88890075Sobrien /* Templated. */ 88990075Sobrien { 89090075Sobrien write_template_prefix (decl); 89190075Sobrien write_template_args (TI_ARGS (template_info)); 89290075Sobrien } 89390075Sobrien else 89490075Sobrien /* Not templated. */ 89590075Sobrien { 89690075Sobrien write_prefix (CP_DECL_CONTEXT (decl)); 89790075Sobrien write_unqualified_name (decl); 89890075Sobrien } 89990075Sobrien 90090075Sobrien add_substitution (node); 90190075Sobrien} 90290075Sobrien 90390075Sobrien/* <template-prefix> ::= <prefix> <template component> 90490075Sobrien ::= <substitution> */ 90590075Sobrien 90690075Sobrienstatic void 90790075Sobrienwrite_template_prefix (node) 90890075Sobrien tree node; 90990075Sobrien{ 91090075Sobrien tree decl = DECL_P (node) ? node : TYPE_NAME (node); 91190075Sobrien tree type = DECL_P (node) ? TREE_TYPE (node) : node; 91290075Sobrien tree context = CP_DECL_CONTEXT (decl); 91390075Sobrien tree template_info; 91490075Sobrien tree template; 91590075Sobrien tree substitution; 91690075Sobrien 91790075Sobrien MANGLE_TRACE_TREE ("template-prefix", node); 91890075Sobrien 91990075Sobrien /* Find the template decl. */ 92090075Sobrien if (decl_is_template_id (decl, &template_info)) 92190075Sobrien template = TI_TEMPLATE (template_info); 92290075Sobrien else if (CLASSTYPE_TEMPLATE_ID_P (type)) 92390075Sobrien template = CLASSTYPE_TI_TEMPLATE (type); 92490075Sobrien else 92590075Sobrien /* Oops, not a template. */ 92690075Sobrien abort (); 92790075Sobrien 92890075Sobrien /* For a member template, though, the template name for the 92990075Sobrien innermost name must have all the outer template levels 93090075Sobrien instantiated. For instance, consider 93190075Sobrien 93290075Sobrien template<typename T> struct Outer { 93390075Sobrien template<typename U> struct Inner {}; 93490075Sobrien }; 93590075Sobrien 93690075Sobrien The template name for `Inner' in `Outer<int>::Inner<float>' is 93790075Sobrien `Outer<int>::Inner<U>'. In g++, we don't instantiate the template 93890075Sobrien levels separately, so there's no TEMPLATE_DECL available for this 93990075Sobrien (there's only `Outer<T>::Inner<U>'). 94090075Sobrien 94190075Sobrien In order to get the substitutions right, we create a special 94290075Sobrien TREE_LIST to represent the substitution candidate for a nested 94390075Sobrien template. The TREE_PURPOSE is the template's context, fully 94490075Sobrien instantiated, and the TREE_VALUE is the TEMPLATE_DECL for the inner 94590075Sobrien template. 94690075Sobrien 94790075Sobrien So, for the example above, `Outer<int>::Inner' is represented as a 94890075Sobrien substitution candidate by a TREE_LIST whose purpose is `Outer<int>' 94990075Sobrien and whose value is `Outer<T>::Inner<U>'. */ 95090075Sobrien if (TYPE_P (context)) 95190075Sobrien substitution = build_tree_list (context, template); 95290075Sobrien else 95390075Sobrien substitution = template; 95490075Sobrien 95590075Sobrien if (find_substitution (substitution)) 95690075Sobrien return; 95790075Sobrien 95890075Sobrien write_prefix (context); 95990075Sobrien write_unqualified_name (decl); 96090075Sobrien 96190075Sobrien add_substitution (substitution); 96290075Sobrien} 96390075Sobrien 96490075Sobrien/* We don't need to handle thunks, vtables, or VTTs here. Those are 96590075Sobrien mangled through special entry points. 96690075Sobrien 96790075Sobrien <unqualified-name> ::= <operator-name> 96890075Sobrien ::= <special-name> 96990075Sobrien ::= <source-name> */ 97090075Sobrien 97190075Sobrienstatic void 97290075Sobrienwrite_unqualified_name (decl) 97390075Sobrien tree decl; 97490075Sobrien{ 97590075Sobrien MANGLE_TRACE_TREE ("unqualified-name", decl); 97690075Sobrien 97790075Sobrien if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_CONSTRUCTOR_P (decl)) 97890075Sobrien write_special_name_constructor (decl); 97990075Sobrien else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl)) 98090075Sobrien write_special_name_destructor (decl); 98190075Sobrien else if (DECL_CONV_FN_P (decl)) 98290075Sobrien { 98390075Sobrien /* Conversion operator. Handle it right here. 98490075Sobrien <operator> ::= cv <type> */ 98590075Sobrien write_string ("cv"); 98690075Sobrien write_type (TREE_TYPE (DECL_NAME (decl))); 98790075Sobrien } 98890075Sobrien else if (DECL_OVERLOADED_OPERATOR_P (decl)) 98990075Sobrien { 99090075Sobrien operator_name_info_t *oni; 99190075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (decl)) 99290075Sobrien oni = assignment_operator_name_info; 99390075Sobrien else 99490075Sobrien oni = operator_name_info; 99590075Sobrien 99690075Sobrien write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name); 99790075Sobrien } 99890075Sobrien else 99990075Sobrien write_source_name (DECL_NAME (decl)); 100090075Sobrien} 100190075Sobrien 100290075Sobrien/* Non-termial <source-name>. IDENTIFIER is an IDENTIFIER_NODE. 100390075Sobrien 100490075Sobrien <source-name> ::= </length/ number> <identifier> */ 100590075Sobrien 100690075Sobrienstatic void 100790075Sobrienwrite_source_name (identifier) 100890075Sobrien tree identifier; 100990075Sobrien{ 101090075Sobrien MANGLE_TRACE_TREE ("source-name", identifier); 101190075Sobrien 101290075Sobrien /* Never write the whole template-id name including the template 101390075Sobrien arguments; we only want the template name. */ 101490075Sobrien if (IDENTIFIER_TEMPLATE (identifier)) 101590075Sobrien identifier = IDENTIFIER_TEMPLATE (identifier); 101690075Sobrien 101790075Sobrien write_unsigned_number (IDENTIFIER_LENGTH (identifier)); 101890075Sobrien write_identifier (IDENTIFIER_POINTER (identifier)); 101990075Sobrien} 102090075Sobrien 102190075Sobrien/* Convert NUMBER to ascii using base BASE and generating at least 102290075Sobrien MIN_DIGITS characters. BUFFER points to the _end_ of the buffer 102390075Sobrien into which to store the characters. Returns the number of 102490075Sobrien characters generated (these will be layed out in advance of where 102590075Sobrien BUFFER points). */ 102690075Sobrien 102790075Sobrienstatic int 102890075Sobrienhwint_to_ascii (number, base, buffer, min_digits) 102990075Sobrien unsigned HOST_WIDE_INT number; 103090075Sobrien unsigned int base; 103190075Sobrien char *buffer; 103290075Sobrien unsigned min_digits; 103390075Sobrien{ 103490075Sobrien static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 103590075Sobrien unsigned digits = 0; 103690075Sobrien 103790075Sobrien while (number) 103890075Sobrien { 103990075Sobrien unsigned HOST_WIDE_INT d = number / base; 104090075Sobrien 104190075Sobrien *--buffer = base_digits[number - d * base]; 104290075Sobrien digits++; 104390075Sobrien number = d; 104490075Sobrien } 104590075Sobrien while (digits < min_digits) 104690075Sobrien { 104790075Sobrien *--buffer = base_digits[0]; 104890075Sobrien digits++; 104990075Sobrien } 105090075Sobrien return digits; 105190075Sobrien} 105290075Sobrien 105390075Sobrien/* Non-terminal <number>. 105490075Sobrien 105590075Sobrien <number> ::= [n] </decimal integer/> */ 105690075Sobrien 105790075Sobrienstatic void 105890075Sobrienwrite_number (number, unsigned_p, base) 105990075Sobrien unsigned HOST_WIDE_INT number; 106090075Sobrien int unsigned_p; 106190075Sobrien unsigned int base; 106290075Sobrien{ 106390075Sobrien char buffer[sizeof (HOST_WIDE_INT) * 8]; 106490075Sobrien unsigned count = 0; 106590075Sobrien 106690075Sobrien if (!unsigned_p && (HOST_WIDE_INT) number < 0) 106790075Sobrien { 106890075Sobrien write_char ('n'); 106990075Sobrien number = -((HOST_WIDE_INT) number); 107090075Sobrien } 107190075Sobrien count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1); 107290075Sobrien write_chars (buffer + sizeof (buffer) - count, count); 107390075Sobrien} 107490075Sobrien 107590075Sobrien/* Write out an integral CST in decimal. Most numbers are small, and 107690075Sobrien representable in a HOST_WIDE_INT. Occasionally we'll have numbers 107790075Sobrien bigger than that, which we must deal with. */ 107890075Sobrien 107990075Sobrienstatic inline void 108090075Sobrienwrite_integer_cst (cst) 108190075Sobrien tree cst; 108290075Sobrien{ 108390075Sobrien int sign = tree_int_cst_sgn (cst); 108490075Sobrien 108590075Sobrien if (TREE_INT_CST_HIGH (cst) + (sign < 0)) 108690075Sobrien { 108790075Sobrien /* A bignum. We do this in chunks, each of which fits in a 108890075Sobrien HOST_WIDE_INT. */ 108990075Sobrien char buffer[sizeof (HOST_WIDE_INT) * 8 * 2]; 109090075Sobrien unsigned HOST_WIDE_INT chunk; 109190075Sobrien unsigned chunk_digits; 109290075Sobrien char *ptr = buffer + sizeof (buffer); 109390075Sobrien unsigned count = 0; 109490075Sobrien tree n, base, type; 109590075Sobrien int done; 109690075Sobrien 109790075Sobrien /* HOST_WIDE_INT must be at least 32 bits, so 10^9 is 109890075Sobrien representable. */ 109990075Sobrien chunk = 1000000000; 110090075Sobrien chunk_digits = 9; 110190075Sobrien 110290075Sobrien if (sizeof (HOST_WIDE_INT) >= 8) 110390075Sobrien { 110490075Sobrien /* It is at least 64 bits, so 10^18 is representable. */ 110590075Sobrien chunk_digits = 18; 110690075Sobrien chunk *= chunk; 110790075Sobrien } 110890075Sobrien 110990075Sobrien type = signed_or_unsigned_type (1, TREE_TYPE (cst)); 111090075Sobrien base = build_int_2 (chunk, 0); 111190075Sobrien n = build_int_2 (TREE_INT_CST_LOW (cst), TREE_INT_CST_HIGH (cst)); 111290075Sobrien TREE_TYPE (n) = TREE_TYPE (base) = type; 111390075Sobrien 111490075Sobrien if (sign < 0) 111590075Sobrien { 111690075Sobrien write_char ('n'); 111790075Sobrien n = fold (build1 (NEGATE_EXPR, type, n)); 111890075Sobrien } 111990075Sobrien do 112090075Sobrien { 112190075Sobrien tree d = fold (build (FLOOR_DIV_EXPR, type, n, base)); 112290075Sobrien tree tmp = fold (build (MULT_EXPR, type, d, base)); 112390075Sobrien unsigned c; 112490075Sobrien 112590075Sobrien done = integer_zerop (d); 112690075Sobrien tmp = fold (build (MINUS_EXPR, type, n, tmp)); 112790075Sobrien c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr, 112890075Sobrien done ? 1 : chunk_digits); 112990075Sobrien ptr -= c; 113090075Sobrien count += c; 113190075Sobrien n = d; 113290075Sobrien } 113390075Sobrien while (!done); 113490075Sobrien write_chars (ptr, count); 113590075Sobrien } 113690075Sobrien else 113790075Sobrien { 113890075Sobrien /* A small num. */ 113990075Sobrien unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst); 114090075Sobrien 114190075Sobrien if (sign < 0) 114290075Sobrien { 114390075Sobrien write_char ('n'); 114490075Sobrien low = -low; 114590075Sobrien } 114690075Sobrien write_unsigned_number (low); 114790075Sobrien } 114890075Sobrien} 114990075Sobrien 115090075Sobrien/* Non-terminal <identifier>. 115190075Sobrien 115290075Sobrien <identifier> ::= </unqualified source code identifier> */ 115390075Sobrien 115490075Sobrienstatic void 115590075Sobrienwrite_identifier (identifier) 115690075Sobrien const char *identifier; 115790075Sobrien{ 115890075Sobrien MANGLE_TRACE ("identifier", identifier); 115990075Sobrien write_string (identifier); 116090075Sobrien} 116190075Sobrien 116290075Sobrien/* Handle constructor productions of non-terminal <special-name>. 116390075Sobrien CTOR is a constructor FUNCTION_DECL. 116490075Sobrien 116590075Sobrien <special-name> ::= C1 # complete object constructor 116690075Sobrien ::= C2 # base object constructor 116790075Sobrien ::= C3 # complete object allocating constructor 116890075Sobrien 116990075Sobrien Currently, allocating constructors are never used. 117090075Sobrien 117190075Sobrien We also need to provide mangled names for the maybe-in-charge 117290075Sobrien constructor, so we treat it here too. mangle_decl_string will 117390075Sobrien append *INTERNAL* to that, to make sure we never emit it. */ 117490075Sobrien 117590075Sobrienstatic void 117690075Sobrienwrite_special_name_constructor (ctor) 117790075Sobrien tree ctor; 117890075Sobrien{ 117990075Sobrien if (DECL_COMPLETE_CONSTRUCTOR_P (ctor) 118090075Sobrien /* Even though we don't ever emit a definition of the 118190075Sobrien old-style destructor, we still have to consider entities 118290075Sobrien (like static variables) nested inside it. */ 118390075Sobrien || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (ctor)) 118490075Sobrien write_string ("C1"); 118590075Sobrien else if (DECL_BASE_CONSTRUCTOR_P (ctor)) 118690075Sobrien write_string ("C2"); 118790075Sobrien else 118890075Sobrien abort (); 118990075Sobrien} 119090075Sobrien 119190075Sobrien/* Handle destructor productions of non-terminal <special-name>. 119290075Sobrien DTOR is a destructor FUNCTION_DECL. 119390075Sobrien 119490075Sobrien <special-name> ::= D0 # deleting (in-charge) destructor 119590075Sobrien ::= D1 # complete object (in-charge) destructor 119690075Sobrien ::= D2 # base object (not-in-charge) destructor 119790075Sobrien 119890075Sobrien We also need to provide mangled names for the maybe-incharge 119990075Sobrien destructor, so we treat it here too. mangle_decl_string will 120090075Sobrien append *INTERNAL* to that, to make sure we never emit it. */ 120190075Sobrien 120290075Sobrienstatic void 120390075Sobrienwrite_special_name_destructor (dtor) 120490075Sobrien tree dtor; 120590075Sobrien{ 120690075Sobrien if (DECL_DELETING_DESTRUCTOR_P (dtor)) 120790075Sobrien write_string ("D0"); 120890075Sobrien else if (DECL_COMPLETE_DESTRUCTOR_P (dtor) 120990075Sobrien /* Even though we don't ever emit a definition of the 121090075Sobrien old-style destructor, we still have to consider entities 121190075Sobrien (like static variables) nested inside it. */ 121290075Sobrien || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (dtor)) 121390075Sobrien write_string ("D1"); 121490075Sobrien else if (DECL_BASE_DESTRUCTOR_P (dtor)) 121590075Sobrien write_string ("D2"); 121690075Sobrien else 121790075Sobrien abort (); 121890075Sobrien} 121990075Sobrien 122090075Sobrien/* Return the discriminator for ENTITY appearing inside 122190075Sobrien FUNCTION. The discriminator is the lexical ordinal of VAR among 122290075Sobrien entities with the same name in the same FUNCTION. */ 122390075Sobrien 122490075Sobrienstatic int 122590075Sobriendiscriminator_for_local_entity (entity) 122690075Sobrien tree entity; 122790075Sobrien{ 122890075Sobrien tree *type; 122990075Sobrien int discriminator; 123090075Sobrien 123190075Sobrien /* Assume this is the only local entity with this name. */ 123290075Sobrien discriminator = 0; 123390075Sobrien 123490075Sobrien if (DECL_DISCRIMINATOR_P (entity) && DECL_LANG_SPECIFIC (entity)) 123590075Sobrien discriminator = DECL_DISCRIMINATOR (entity); 123690075Sobrien else if (TREE_CODE (entity) == TYPE_DECL) 123790075Sobrien { 123890075Sobrien /* Scan the list of local classes. */ 123990075Sobrien entity = TREE_TYPE (entity); 124090075Sobrien for (type = &VARRAY_TREE (local_classes, 0); *type != entity; ++type) 124190075Sobrien if (TYPE_IDENTIFIER (*type) == TYPE_IDENTIFIER (entity) 124290075Sobrien && TYPE_CONTEXT (*type) == TYPE_CONTEXT (entity)) 124390075Sobrien ++discriminator; 124490075Sobrien } 124590075Sobrien 124690075Sobrien return discriminator; 124790075Sobrien} 124890075Sobrien 124990075Sobrien/* Return the discriminator for STRING, a string literal used inside 125090075Sobrien FUNCTION. The disciminator is the lexical ordinal of STRING among 125190075Sobrien string literals used in FUNCTION. */ 125290075Sobrien 125390075Sobrienstatic int 125490075Sobriendiscriminator_for_string_literal (function, string) 125590075Sobrien tree function ATTRIBUTE_UNUSED; 125690075Sobrien tree string ATTRIBUTE_UNUSED; 125790075Sobrien{ 125890075Sobrien /* For now, we don't discriminate amongst string literals. */ 125990075Sobrien return 0; 126090075Sobrien} 126190075Sobrien 126290075Sobrien/* <discriminator> := _ <number> 126390075Sobrien 126490075Sobrien The discriminator is used only for the second and later occurrences 126590075Sobrien of the same name within a single function. In this case <number> is 126690075Sobrien n - 2, if this is the nth occurrence, in lexical order. */ 126790075Sobrien 126890075Sobrienstatic void 126990075Sobrienwrite_discriminator (discriminator) 127090075Sobrien int discriminator; 127190075Sobrien{ 127290075Sobrien /* If discriminator is zero, don't write anything. Otherwise... */ 127390075Sobrien if (discriminator > 0) 127490075Sobrien { 127590075Sobrien write_char ('_'); 127690075Sobrien write_unsigned_number (discriminator - 1); 127790075Sobrien } 127890075Sobrien} 127990075Sobrien 128090075Sobrien/* Mangle the name of a function-scope entity. FUNCTION is the 128190075Sobrien FUNCTION_DECL for the enclosing function. ENTITY is the decl for 128290075Sobrien the entity itself. LOCAL_ENTITY is the entity that's directly 128390075Sobrien scoped in FUNCTION_DECL, either ENTITY itself or an enclosing scope 128490075Sobrien of ENTITY. 128590075Sobrien 128690075Sobrien <local-name> := Z <function encoding> E <entity name> [<discriminator>] 128790075Sobrien := Z <function encoding> E s [<discriminator>] */ 128890075Sobrien 128990075Sobrienstatic void 129090075Sobrienwrite_local_name (function, local_entity, entity) 129190075Sobrien tree function; 129290075Sobrien tree local_entity; 129390075Sobrien tree entity; 129490075Sobrien{ 129590075Sobrien MANGLE_TRACE_TREE ("local-name", entity); 129690075Sobrien 129790075Sobrien write_char ('Z'); 129890075Sobrien write_encoding (function); 129990075Sobrien write_char ('E'); 130090075Sobrien if (TREE_CODE (entity) == STRING_CST) 130190075Sobrien { 130290075Sobrien write_char ('s'); 130390075Sobrien write_discriminator (discriminator_for_string_literal (function, 130490075Sobrien entity)); 130590075Sobrien } 130690075Sobrien else 130790075Sobrien { 130890075Sobrien /* Now the <entity name>. Let write_name know its being called 130990075Sobrien from <local-name>, so it doesn't try to process the enclosing 131090075Sobrien function scope again. */ 131190075Sobrien write_name (entity, /*ignore_local_scope=*/1); 131290075Sobrien write_discriminator (discriminator_for_local_entity (local_entity)); 131390075Sobrien } 131490075Sobrien} 131590075Sobrien 131690075Sobrien/* Non-terminals <type> and <CV-qualifier>. 131790075Sobrien 131890075Sobrien <type> ::= <builtin-type> 131990075Sobrien ::= <function-type> 132090075Sobrien ::= <class-enum-type> 132190075Sobrien ::= <array-type> 132290075Sobrien ::= <pointer-to-member-type> 132390075Sobrien ::= <template-param> 132490075Sobrien ::= <substitution> 132590075Sobrien ::= <CV-qualifier> 132690075Sobrien ::= P <type> # pointer-to 132790075Sobrien ::= R <type> # reference-to 132890075Sobrien ::= C <type> # complex pair (C 2000) 132990075Sobrien ::= G <type> # imaginary (C 2000) [not supported] 133090075Sobrien ::= U <source-name> <type> # vendor extended type qualifier 133190075Sobrien 133290075Sobrien TYPE is a type node. */ 133390075Sobrien 133490075Sobrienstatic void 133590075Sobrienwrite_type (type) 133690075Sobrien tree type; 133790075Sobrien{ 133890075Sobrien /* This gets set to non-zero if TYPE turns out to be a (possibly 133990075Sobrien CV-qualified) builtin type. */ 134090075Sobrien int is_builtin_type = 0; 134190075Sobrien 134290075Sobrien MANGLE_TRACE_TREE ("type", type); 134390075Sobrien 134490075Sobrien if (type == error_mark_node) 134590075Sobrien return; 134690075Sobrien 134790075Sobrien if (find_substitution (type)) 134890075Sobrien return; 134990075Sobrien 135090075Sobrien if (write_CV_qualifiers_for_type (type) > 0) 135190075Sobrien /* If TYPE was CV-qualified, we just wrote the qualifiers; now 135290075Sobrien mangle the unqualified type. The recursive call is needed here 135390075Sobrien since both the qualified and uqualified types are substitution 135490075Sobrien candidates. */ 135590075Sobrien write_type (TYPE_MAIN_VARIANT (type)); 135690075Sobrien else 135790075Sobrien { 135890075Sobrien /* See through any typedefs. */ 135990075Sobrien type = TYPE_MAIN_VARIANT (type); 136090075Sobrien 136190075Sobrien switch (TREE_CODE (type)) 136290075Sobrien { 136390075Sobrien case VOID_TYPE: 136490075Sobrien case BOOLEAN_TYPE: 136590075Sobrien case INTEGER_TYPE: /* Includes wchar_t. */ 136690075Sobrien case REAL_TYPE: 136790075Sobrien /* If this is a typedef, TYPE may not be one of 136890075Sobrien the standard builtin type nodes, but an alias of one. Use 136990075Sobrien TYPE_MAIN_VARIANT to get to the underlying builtin type. */ 137090075Sobrien write_builtin_type (TYPE_MAIN_VARIANT (type)); 137190075Sobrien ++is_builtin_type; 137290075Sobrien break; 137390075Sobrien 137490075Sobrien case COMPLEX_TYPE: 137590075Sobrien write_char ('C'); 137690075Sobrien write_type (TREE_TYPE (type)); 137790075Sobrien break; 137890075Sobrien 137990075Sobrien case FUNCTION_TYPE: 138090075Sobrien case METHOD_TYPE: 138190075Sobrien write_function_type (type); 138290075Sobrien break; 138390075Sobrien 138490075Sobrien case UNION_TYPE: 138590075Sobrien case RECORD_TYPE: 138690075Sobrien case ENUMERAL_TYPE: 138790075Sobrien /* A pointer-to-member function is represented as a special 138890075Sobrien RECORD_TYPE, so check for this first. */ 138990075Sobrien if (TYPE_PTRMEMFUNC_P (type)) 139090075Sobrien write_pointer_to_member_type (type); 139190075Sobrien else 139290075Sobrien write_class_enum_type (type); 139390075Sobrien break; 139490075Sobrien 139590075Sobrien case TYPENAME_TYPE: 139690075Sobrien case UNBOUND_CLASS_TEMPLATE: 139790075Sobrien /* We handle TYPENAME_TYPEs and UNBOUND_CLASS_TEMPLATEs like 139890075Sobrien ordinary nested names. */ 139990075Sobrien write_nested_name (TYPE_STUB_DECL (type)); 140090075Sobrien break; 140190075Sobrien 140290075Sobrien case ARRAY_TYPE: 140390075Sobrien write_array_type (type); 140490075Sobrien break; 140590075Sobrien 140690075Sobrien case POINTER_TYPE: 140790075Sobrien /* A pointer-to-member variable is represented by a POINTER_TYPE 140890075Sobrien to an OFFSET_TYPE, so check for this first. */ 140990075Sobrien if (TYPE_PTRMEM_P (type)) 141090075Sobrien write_pointer_to_member_type (type); 141190075Sobrien else 141290075Sobrien { 141390075Sobrien write_char ('P'); 141490075Sobrien write_type (TREE_TYPE (type)); 141590075Sobrien } 141690075Sobrien break; 141790075Sobrien 141890075Sobrien case REFERENCE_TYPE: 141990075Sobrien write_char ('R'); 142090075Sobrien write_type (TREE_TYPE (type)); 142190075Sobrien break; 142290075Sobrien 142390075Sobrien case TEMPLATE_TYPE_PARM: 142490075Sobrien case TEMPLATE_PARM_INDEX: 142590075Sobrien write_template_param (type); 142690075Sobrien break; 142790075Sobrien 142890075Sobrien case TEMPLATE_TEMPLATE_PARM: 142990075Sobrien write_template_template_param (type); 143090075Sobrien break; 143190075Sobrien 143290075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 143390075Sobrien write_template_template_param (type); 143490075Sobrien write_template_args 143590075Sobrien (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))); 143690075Sobrien break; 143790075Sobrien 143890075Sobrien case OFFSET_TYPE: 143990075Sobrien write_pointer_to_member_type (build_pointer_type (type)); 144090075Sobrien break; 144190075Sobrien 144290075Sobrien case VECTOR_TYPE: 144390075Sobrien write_string ("U8__vector"); 144490075Sobrien write_type (TREE_TYPE (type)); 144590075Sobrien break; 144690075Sobrien 144790075Sobrien default: 144890075Sobrien abort (); 144990075Sobrien } 145090075Sobrien } 145190075Sobrien 145290075Sobrien /* Types other than builtin types are substitution candidates. */ 145390075Sobrien if (!is_builtin_type) 145490075Sobrien add_substitution (type); 145590075Sobrien} 145690075Sobrien 145790075Sobrien/* Non-terminal <CV-qualifiers> for type nodes. Returns the number of 145890075Sobrien CV-qualifiers written for TYPE. 145990075Sobrien 146090075Sobrien <CV-qualifiers> ::= [r] [V] [K] */ 146190075Sobrien 146290075Sobrienstatic int 146390075Sobrienwrite_CV_qualifiers_for_type (type) 146490075Sobrien tree type; 146590075Sobrien{ 146690075Sobrien int num_qualifiers = 0; 146790075Sobrien 146890075Sobrien /* The order is specified by: 146990075Sobrien 147090075Sobrien "In cases where multiple order-insensitive qualifiers are 147190075Sobrien present, they should be ordered 'K' (closest to the base type), 147290075Sobrien 'V', 'r', and 'U' (farthest from the base type) ..." */ 147390075Sobrien 147490075Sobrien if (CP_TYPE_RESTRICT_P (type)) 147590075Sobrien { 147690075Sobrien write_char ('r'); 147790075Sobrien ++num_qualifiers; 147890075Sobrien } 147990075Sobrien if (CP_TYPE_VOLATILE_P (type)) 148090075Sobrien { 148190075Sobrien write_char ('V'); 148290075Sobrien ++num_qualifiers; 148390075Sobrien } 148490075Sobrien if (CP_TYPE_CONST_P (type)) 148590075Sobrien { 148690075Sobrien write_char ('K'); 148790075Sobrien ++num_qualifiers; 148890075Sobrien } 148990075Sobrien 149090075Sobrien return num_qualifiers; 149190075Sobrien} 149290075Sobrien 149390075Sobrien/* Non-terminal <builtin-type>. 149490075Sobrien 149590075Sobrien <builtin-type> ::= v # void 149690075Sobrien ::= b # bool 149790075Sobrien ::= w # wchar_t 149890075Sobrien ::= c # char 149990075Sobrien ::= a # signed char 150090075Sobrien ::= h # unsigned char 150190075Sobrien ::= s # short 150290075Sobrien ::= t # unsigned short 150390075Sobrien ::= i # int 150490075Sobrien ::= j # unsigned int 150590075Sobrien ::= l # long 150690075Sobrien ::= m # unsigned long 150790075Sobrien ::= x # long long, __int64 150890075Sobrien ::= y # unsigned long long, __int64 150990075Sobrien ::= n # __int128 [not supported] 151090075Sobrien ::= o # unsigned __int128 [not supported] 151190075Sobrien ::= f # float 151290075Sobrien ::= d # double 151390075Sobrien ::= e # long double, __float80 151490075Sobrien ::= g # __float128 [not supported] 151590075Sobrien ::= u <source-name> # vendor extended type */ 151690075Sobrien 151790075Sobrienstatic void 151890075Sobrienwrite_builtin_type (type) 151990075Sobrien tree type; 152090075Sobrien{ 152190075Sobrien switch (TREE_CODE (type)) 152290075Sobrien { 152390075Sobrien case VOID_TYPE: 152490075Sobrien write_char ('v'); 152590075Sobrien break; 152690075Sobrien 152790075Sobrien case BOOLEAN_TYPE: 152890075Sobrien write_char ('b'); 152990075Sobrien break; 153090075Sobrien 153190075Sobrien case INTEGER_TYPE: 153290075Sobrien /* If this is size_t, get the underlying int type. */ 153390075Sobrien if (TYPE_IS_SIZETYPE (type)) 153490075Sobrien type = TYPE_DOMAIN (type); 153590075Sobrien 153690075Sobrien /* TYPE may still be wchar_t, since that isn't in 153790075Sobrien integer_type_nodes. */ 153890075Sobrien if (type == wchar_type_node) 153990075Sobrien write_char ('w'); 154090075Sobrien else if (TYPE_FOR_JAVA (type)) 154190075Sobrien write_java_integer_type_codes (type); 154290075Sobrien else 154390075Sobrien { 154490075Sobrien size_t itk; 154590075Sobrien /* Assume TYPE is one of the shared integer type nodes. Find 154690075Sobrien it in the array of these nodes. */ 154790075Sobrien iagain: 154890075Sobrien for (itk = 0; itk < itk_none; ++itk) 154990075Sobrien if (type == integer_types[itk]) 155090075Sobrien { 155190075Sobrien /* Print the corresponding single-letter code. */ 155290075Sobrien write_char (integer_type_codes[itk]); 155390075Sobrien break; 155490075Sobrien } 155590075Sobrien 155690075Sobrien if (itk == itk_none) 155790075Sobrien { 155890075Sobrien tree t = type_for_mode (TYPE_MODE (type), TREE_UNSIGNED (type)); 155990075Sobrien if (type == t) 156090075Sobrien /* Couldn't find this type. */ 156190075Sobrien abort (); 156290075Sobrien type = t; 156390075Sobrien goto iagain; 156490075Sobrien } 156590075Sobrien } 156690075Sobrien break; 156790075Sobrien 156890075Sobrien case REAL_TYPE: 156990075Sobrien if (type == float_type_node 157090075Sobrien || type == java_float_type_node) 157190075Sobrien write_char ('f'); 157290075Sobrien else if (type == double_type_node 157390075Sobrien || type == java_double_type_node) 157490075Sobrien write_char ('d'); 157590075Sobrien else if (type == long_double_type_node) 157690075Sobrien write_char ('e'); 157790075Sobrien else 157890075Sobrien abort (); 157990075Sobrien break; 158090075Sobrien 158190075Sobrien default: 158290075Sobrien abort (); 158390075Sobrien } 158490075Sobrien} 158590075Sobrien 158690075Sobrien/* Non-terminal <function-type>. NODE is a FUNCTION_TYPE or 158790075Sobrien METHOD_TYPE. The return type is mangled before the parameter 158890075Sobrien types. 158990075Sobrien 159090075Sobrien <function-type> ::= F [Y] <bare-function-type> E */ 159190075Sobrien 159290075Sobrienstatic void 159390075Sobrienwrite_function_type (type) 159490075Sobrien tree type; 159590075Sobrien{ 159690075Sobrien MANGLE_TRACE_TREE ("function-type", type); 159790075Sobrien 159890075Sobrien write_char ('F'); 159990075Sobrien /* We don't track whether or not a type is `extern "C"'. Note that 160090075Sobrien you can have an `extern "C"' function that does not have 160190075Sobrien `extern "C"' type, and vice versa: 160290075Sobrien 160390075Sobrien extern "C" typedef void function_t(); 160490075Sobrien function_t f; // f has C++ linkage, but its type is 160590075Sobrien // `extern "C"' 160690075Sobrien 160790075Sobrien typedef void function_t(); 160890075Sobrien extern "C" function_t f; // Vice versa. 160990075Sobrien 161090075Sobrien See [dcl.link]. */ 161190075Sobrien write_bare_function_type (type, /*include_return_type_p=*/1, 161290075Sobrien /*decl=*/NULL); 161390075Sobrien write_char ('E'); 161490075Sobrien} 161590075Sobrien 161690075Sobrien/* Non-terminal <bare-function-type>. TYPE is a FUNCTION_TYPE or 161790075Sobrien METHOD_TYPE. If INCLUDE_RETURN_TYPE is non-zero, the return value 161890075Sobrien is mangled before the parameter types. If non-NULL, DECL is 161990075Sobrien FUNCTION_DECL for the function whose type is being emitted. 162090075Sobrien 162190075Sobrien <bare-function-type> ::= </signature/ type>+ */ 162290075Sobrien 162390075Sobrienstatic void 162490075Sobrienwrite_bare_function_type (type, include_return_type_p, decl) 162590075Sobrien tree type; 162690075Sobrien int include_return_type_p; 162790075Sobrien tree decl; 162890075Sobrien{ 162990075Sobrien MANGLE_TRACE_TREE ("bare-function-type", type); 163090075Sobrien 163190075Sobrien /* Mangle the return type, if requested. */ 163290075Sobrien if (include_return_type_p) 163390075Sobrien write_type (TREE_TYPE (type)); 163490075Sobrien 163590075Sobrien /* Now mangle the types of the arguments. */ 163690075Sobrien write_method_parms (TYPE_ARG_TYPES (type), 163790075Sobrien TREE_CODE (type) == METHOD_TYPE, 163890075Sobrien decl); 163990075Sobrien} 164090075Sobrien 164190075Sobrien/* Write the mangled representation of a method parameter list of 164290075Sobrien types given in PARM_TYPES. If METHOD_P is non-zero, the function is 164390075Sobrien considered a non-static method, and the this parameter is omitted. 164490075Sobrien If non-NULL, DECL is the FUNCTION_DECL for the function whose 164590075Sobrien parameters are being emitted. */ 164690075Sobrien 164790075Sobrienstatic void 164890075Sobrienwrite_method_parms (parm_types, method_p, decl) 164990075Sobrien tree decl; 165090075Sobrien tree parm_types; 165190075Sobrien int method_p; 165290075Sobrien{ 165390075Sobrien tree first_parm_type; 165490075Sobrien tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE; 165590075Sobrien 165690075Sobrien /* Assume this parameter type list is variable-length. If it ends 165790075Sobrien with a void type, then it's not. */ 165890075Sobrien int varargs_p = 1; 165990075Sobrien 166090075Sobrien /* If this is a member function, skip the first arg, which is the 166190075Sobrien this pointer. 166290075Sobrien "Member functions do not encode the type of their implicit this 166390075Sobrien parameter." 166490075Sobrien 166590075Sobrien Similarly, there's no need to mangle artificial parameters, like 166690075Sobrien the VTT parameters for constructors and destructors. */ 166790075Sobrien if (method_p) 166890075Sobrien { 166990075Sobrien parm_types = TREE_CHAIN (parm_types); 167090075Sobrien parm_decl = parm_decl ? TREE_CHAIN (parm_decl) : NULL_TREE; 167190075Sobrien 167290075Sobrien while (parm_decl && DECL_ARTIFICIAL (parm_decl)) 167390075Sobrien { 167490075Sobrien parm_types = TREE_CHAIN (parm_types); 167590075Sobrien parm_decl = TREE_CHAIN (parm_decl); 167690075Sobrien } 167790075Sobrien } 167890075Sobrien 167990075Sobrien for (first_parm_type = parm_types; 168090075Sobrien parm_types; 168190075Sobrien parm_types = TREE_CHAIN (parm_types)) 168290075Sobrien { 168390075Sobrien tree parm = TREE_VALUE (parm_types); 168490075Sobrien if (parm == void_type_node) 168590075Sobrien { 168690075Sobrien /* "Empty parameter lists, whether declared as () or 168790075Sobrien conventionally as (void), are encoded with a void parameter 168890075Sobrien (v)." */ 168990075Sobrien if (parm_types == first_parm_type) 169090075Sobrien write_type (parm); 169190075Sobrien /* If the parm list is terminated with a void type, it's 169290075Sobrien fixed-length. */ 169390075Sobrien varargs_p = 0; 169490075Sobrien /* A void type better be the last one. */ 169590075Sobrien my_friendly_assert (TREE_CHAIN (parm_types) == NULL, 20000523); 169690075Sobrien } 169790075Sobrien else 169890075Sobrien write_type (parm); 169990075Sobrien } 170090075Sobrien 170190075Sobrien if (varargs_p) 170290075Sobrien /* <builtin-type> ::= z # ellipsis */ 170390075Sobrien write_char ('z'); 170490075Sobrien} 170590075Sobrien 170690075Sobrien/* <class-enum-type> ::= <name> */ 170790075Sobrien 170890075Sobrienstatic void 170990075Sobrienwrite_class_enum_type (type) 171090075Sobrien tree type; 171190075Sobrien{ 171290075Sobrien write_name (TYPE_NAME (type), /*ignore_local_scope=*/0); 171390075Sobrien} 171490075Sobrien 171590075Sobrien/* Non-terminal <template-args>. ARGS is a TREE_VEC of template 171690075Sobrien arguments. 171790075Sobrien 171890075Sobrien <template-args> ::= I <template-arg>+ E */ 171990075Sobrien 172090075Sobrienstatic void 172190075Sobrienwrite_template_args (args) 172290075Sobrien tree args; 172390075Sobrien{ 172490075Sobrien int i; 172590075Sobrien int length = TREE_VEC_LENGTH (args); 172690075Sobrien 172790075Sobrien MANGLE_TRACE_TREE ("template-args", args); 172890075Sobrien 172990075Sobrien my_friendly_assert (length > 0, 20000422); 173090075Sobrien 173190075Sobrien if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) 173290075Sobrien { 173390075Sobrien /* We have nested template args. We want the innermost template 173490075Sobrien argument list. */ 173590075Sobrien args = TREE_VEC_ELT (args, length - 1); 173690075Sobrien length = TREE_VEC_LENGTH (args); 173790075Sobrien } 173890075Sobrien 173990075Sobrien write_char ('I'); 174090075Sobrien for (i = 0; i < length; ++i) 174190075Sobrien write_template_arg (TREE_VEC_ELT (args, i)); 174290075Sobrien write_char ('E'); 174390075Sobrien} 174490075Sobrien 174590075Sobrien/* <expression> ::= <unary operator-name> <expression> 174690075Sobrien ::= <binary operator-name> <expression> <expression> 174790075Sobrien ::= <expr-primary> 174890075Sobrien 174990075Sobrien <expr-primary> ::= <template-param> 175090075Sobrien ::= L <type> <value number> E # literal 175190075Sobrien ::= L <mangled-name> E # external name */ 175290075Sobrien 175390075Sobrienstatic void 175490075Sobrienwrite_expression (expr) 175590075Sobrien tree expr; 175690075Sobrien{ 175790075Sobrien enum tree_code code; 175890075Sobrien 175990075Sobrien code = TREE_CODE (expr); 176090075Sobrien 176190075Sobrien /* Handle pointers-to-members by making them look like expression 176290075Sobrien nodes. */ 176390075Sobrien if (code == PTRMEM_CST) 176490075Sobrien { 176590075Sobrien expr = build_nt (ADDR_EXPR, 176690075Sobrien build_nt (SCOPE_REF, 176790075Sobrien PTRMEM_CST_CLASS (expr), 176890075Sobrien PTRMEM_CST_MEMBER (expr))); 176990075Sobrien code = TREE_CODE (expr); 177090075Sobrien } 177190075Sobrien 177290075Sobrien /* Handle template parameters. */ 177390075Sobrien if (code == TEMPLATE_TYPE_PARM 177490075Sobrien || code == TEMPLATE_TEMPLATE_PARM 177590075Sobrien || code == BOUND_TEMPLATE_TEMPLATE_PARM 177690075Sobrien || code == TEMPLATE_PARM_INDEX) 177790075Sobrien write_template_param (expr); 177890075Sobrien /* Handle literals. */ 177990075Sobrien else if (TREE_CODE_CLASS (code) == 'c') 178090075Sobrien write_template_arg_literal (expr); 178190075Sobrien else if (DECL_P (expr)) 178290075Sobrien { 178390075Sobrien write_char ('L'); 178490075Sobrien write_mangled_name (expr); 178590075Sobrien write_char ('E'); 178690075Sobrien } 178790075Sobrien else 178890075Sobrien { 178990075Sobrien int i; 179090075Sobrien 179190075Sobrien /* Skip NOP_EXPRs. They can occur when (say) a pointer argument 179290075Sobrien is converted (via qualification conversions) to another 179390075Sobrien type. */ 179490075Sobrien while (TREE_CODE (expr) == NOP_EXPR) 179590075Sobrien { 179690075Sobrien expr = TREE_OPERAND (expr, 0); 179790075Sobrien code = TREE_CODE (expr); 179890075Sobrien } 179990075Sobrien 180090075Sobrien /* When we bind a variable or function to a non-type template 180190075Sobrien argument with reference type, we create an ADDR_EXPR to show 180290075Sobrien the fact that the entity's address has been taken. But, we 180390075Sobrien don't actually want to output a mangling code for the `&'. */ 180490075Sobrien if (TREE_CODE (expr) == ADDR_EXPR 180590075Sobrien && TREE_TYPE (expr) 180690075Sobrien && TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE) 180790075Sobrien { 180890075Sobrien expr = TREE_OPERAND (expr, 0); 180990075Sobrien if (DECL_P (expr)) 181090075Sobrien { 181190075Sobrien write_expression (expr); 181290075Sobrien return; 181390075Sobrien } 181490075Sobrien 181590075Sobrien code = TREE_CODE (expr); 181690075Sobrien } 181790075Sobrien 181890075Sobrien /* If it wasn't any of those, recursively expand the expression. */ 181990075Sobrien write_string (operator_name_info[(int) code].mangled_name); 182090075Sobrien 182190075Sobrien switch (code) 182290075Sobrien { 182390075Sobrien case CAST_EXPR: 182490075Sobrien write_type (TREE_TYPE (expr)); 182590075Sobrien write_expression (TREE_VALUE (TREE_OPERAND (expr, 0))); 182690075Sobrien break; 182790075Sobrien 182890075Sobrien case STATIC_CAST_EXPR: 182990075Sobrien case CONST_CAST_EXPR: 183090075Sobrien write_type (TREE_TYPE (expr)); 183190075Sobrien write_expression (TREE_OPERAND (expr, 0)); 183290075Sobrien break; 183390075Sobrien 183490075Sobrien /* Handle pointers-to-members specially. */ 183590075Sobrien case SCOPE_REF: 183690075Sobrien write_type (TREE_OPERAND (expr, 0)); 183790075Sobrien if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE) 183890075Sobrien write_source_name (TREE_OPERAND (expr, 1)); 183990075Sobrien else 184090075Sobrien write_encoding (TREE_OPERAND (expr, 1)); 184190075Sobrien break; 184290075Sobrien 184390075Sobrien default: 184490075Sobrien for (i = 0; i < TREE_CODE_LENGTH (code); ++i) 184590075Sobrien write_expression (TREE_OPERAND (expr, i)); 184690075Sobrien } 184790075Sobrien } 184890075Sobrien} 184990075Sobrien 185090075Sobrien/* Literal subcase of non-terminal <template-arg>. 185190075Sobrien 185290075Sobrien "Literal arguments, e.g. "A<42L>", are encoded with their type 185390075Sobrien and value. Negative integer values are preceded with "n"; for 185490075Sobrien example, "A<-42L>" becomes "1AILln42EE". The bool value false is 185590075Sobrien encoded as 0, true as 1. If floating-point arguments are accepted 185690075Sobrien as an extension, their values should be encoded using a 185790075Sobrien fixed-length lowercase hexadecimal string corresponding to the 185890075Sobrien internal representation (IEEE on IA-64), high-order bytes first, 185990075Sobrien without leading zeroes. For example: "Lfbff000000E" is -1.0f." */ 186090075Sobrien 186190075Sobrienstatic void 186290075Sobrienwrite_template_arg_literal (value) 186390075Sobrien tree value; 186490075Sobrien{ 186590075Sobrien tree type = TREE_TYPE (value); 186690075Sobrien write_char ('L'); 186790075Sobrien write_type (type); 186890075Sobrien 186990075Sobrien if (TREE_CODE (value) == CONST_DECL) 187090075Sobrien write_integer_cst (DECL_INITIAL (value)); 187190075Sobrien else if (TREE_CODE (value) == INTEGER_CST) 187290075Sobrien { 187390075Sobrien if (same_type_p (type, boolean_type_node)) 187490075Sobrien { 187590075Sobrien if (value == boolean_false_node || integer_zerop (value)) 187690075Sobrien write_unsigned_number (0); 187790075Sobrien else if (value == boolean_true_node) 187890075Sobrien write_unsigned_number (1); 187990075Sobrien else 188090075Sobrien abort (); 188190075Sobrien } 188290075Sobrien else 188390075Sobrien write_integer_cst (value); 188490075Sobrien } 188590075Sobrien else if (TREE_CODE (value) == REAL_CST) 188690075Sobrien { 188790075Sobrien#ifdef CROSS_COMPILE 188890075Sobrien static int explained; 188990075Sobrien 189090075Sobrien if (!explained) 189190075Sobrien { 189290075Sobrien sorry ("real-valued template parameters when cross-compiling"); 189390075Sobrien explained = 1; 189490075Sobrien } 189590075Sobrien#else 189690075Sobrien size_t i; 189790075Sobrien for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i) 189890075Sobrien write_number (((unsigned char *) 189990075Sobrien &TREE_REAL_CST (value))[i], 190090075Sobrien /*unsigned_p=*/1, 190190075Sobrien 16); 190290075Sobrien#endif 190390075Sobrien } 190490075Sobrien else 190590075Sobrien abort (); 190690075Sobrien 190790075Sobrien write_char ('E'); 190890075Sobrien} 190990075Sobrien 191090075Sobrien/* Non-terminal <tempalate-arg>. 191190075Sobrien 191290075Sobrien <template-arg> ::= <type> # type 191390075Sobrien ::= L <type> </value/ number> E # literal 191490075Sobrien ::= LZ <name> E # external name 191590075Sobrien ::= X <expression> E # expression */ 191690075Sobrien 191790075Sobrienstatic void 191890075Sobrienwrite_template_arg (node) 191990075Sobrien tree node; 192090075Sobrien{ 192190075Sobrien enum tree_code code = TREE_CODE (node); 192290075Sobrien 192390075Sobrien MANGLE_TRACE_TREE ("template-arg", node); 192490075Sobrien 192590075Sobrien /* A template template paramter's argument list contains TREE_LIST 192690075Sobrien nodes of which the value field is the the actual argument. */ 192790075Sobrien if (code == TREE_LIST) 192890075Sobrien { 192990075Sobrien node = TREE_VALUE (node); 193090075Sobrien /* If it's a decl, deal with its type instead. */ 193190075Sobrien if (DECL_P (node)) 193290075Sobrien { 193390075Sobrien node = TREE_TYPE (node); 193490075Sobrien code = TREE_CODE (node); 193590075Sobrien } 193690075Sobrien } 193790075Sobrien 193890075Sobrien if (TYPE_P (node)) 193990075Sobrien write_type (node); 194090075Sobrien else if (code == TEMPLATE_DECL) 194190075Sobrien /* A template appearing as a template arg is a template template arg. */ 194290075Sobrien write_template_template_arg (node); 194390075Sobrien else if (DECL_P (node)) 194490075Sobrien { 194590075Sobrien write_char ('L'); 194690075Sobrien write_char ('Z'); 194790075Sobrien write_encoding (node); 194890075Sobrien write_char ('E'); 194990075Sobrien } 195090075Sobrien else if (TREE_CODE_CLASS (code) == 'c' && code != PTRMEM_CST) 195190075Sobrien write_template_arg_literal (node); 195290075Sobrien else 195390075Sobrien { 195490075Sobrien /* Template arguments may be expressions. */ 195590075Sobrien write_char ('X'); 195690075Sobrien write_expression (node); 195790075Sobrien write_char ('E'); 195890075Sobrien } 195990075Sobrien} 196090075Sobrien 196190075Sobrien/* <template-template-arg> 196290075Sobrien ::= <name> 196390075Sobrien ::= <substitution> */ 196490075Sobrien 196590075Sobrienvoid 196690075Sobrienwrite_template_template_arg (tree decl) 196790075Sobrien{ 196890075Sobrien MANGLE_TRACE_TREE ("template-template-arg", decl); 196990075Sobrien 197090075Sobrien if (find_substitution (decl)) 197190075Sobrien return; 197290075Sobrien write_name (decl, /*ignore_local_scope=*/0); 197390075Sobrien add_substitution (decl); 197490075Sobrien} 197590075Sobrien 197690075Sobrien 197790075Sobrien/* Non-terminal <array-type>. TYPE is an ARRAY_TYPE. 197890075Sobrien 197990075Sobrien <array-type> ::= A [</dimension/ number>] _ </element/ type> 198090075Sobrien ::= A <expression> _ </element/ type> 198190075Sobrien 198290075Sobrien "Array types encode the dimension (number of elements) and the 198390075Sobrien element type. For variable length arrays, the dimension (but not 198490075Sobrien the '_' separator) is omitted." */ 198590075Sobrien 198690075Sobrienstatic void 198790075Sobrienwrite_array_type (type) 198890075Sobrien tree type; 198990075Sobrien{ 199090075Sobrien write_char ('A'); 199190075Sobrien if (TYPE_DOMAIN (type)) 199290075Sobrien { 199390075Sobrien tree index_type; 199490075Sobrien tree max; 199590075Sobrien 199690075Sobrien index_type = TYPE_DOMAIN (type); 199790075Sobrien /* The INDEX_TYPE gives the upper and lower bounds of the 199890075Sobrien array. */ 199990075Sobrien max = TYPE_MAX_VALUE (index_type); 200090075Sobrien if (TREE_CODE (max) == INTEGER_CST) 200190075Sobrien { 200290075Sobrien /* The ABI specifies that we should mangle the number of 200390075Sobrien elements in the array, not the largest allowed index. */ 200490075Sobrien max = size_binop (PLUS_EXPR, max, size_one_node); 200590075Sobrien write_unsigned_number (tree_low_cst (max, 1)); 200690075Sobrien } 200790075Sobrien else 200890075Sobrien write_expression (TREE_OPERAND (max, 0)); 200990075Sobrien } 201090075Sobrien write_char ('_'); 201190075Sobrien write_type (TREE_TYPE (type)); 201290075Sobrien} 201390075Sobrien 201490075Sobrien/* Non-terminal <pointer-to-member-type> for pointer-to-member 201590075Sobrien variables. TYPE is a pointer-to-member POINTER_TYPE. 201690075Sobrien 201790075Sobrien <pointer-to-member-type> ::= M </class/ type> </member/ type> */ 201890075Sobrien 201990075Sobrienstatic void 202090075Sobrienwrite_pointer_to_member_type (type) 202190075Sobrien tree type; 202290075Sobrien{ 202390075Sobrien write_char ('M'); 202490075Sobrien /* For a pointer-to-function member, the class type may be 202590075Sobrien cv-qualified, but that won't be reflected in 202690075Sobrien TYPE_PTRMEM_CLASS_TYPE. So, we go fishing around in 202790075Sobrien TYPE_PTRMEM_POINTED_TO_TYPE instead. */ 202890075Sobrien if (TYPE_PTRMEMFUNC_P (type)) 202990075Sobrien { 203090075Sobrien tree fn_type; 203190075Sobrien tree this_type; 203290075Sobrien 203390075Sobrien fn_type = TYPE_PTRMEM_POINTED_TO_TYPE (type); 203490075Sobrien /* The first parameter must be a POINTER_TYPE pointing to the 203590075Sobrien `this' parameter. */ 203690075Sobrien this_type = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fn_type))); 203790075Sobrien write_type (this_type); 203890075Sobrien } 203990075Sobrien /* For a pointer-to-data member, things are simpler. */ 204090075Sobrien else 204190075Sobrien write_type (TYPE_PTRMEM_CLASS_TYPE (type)); 204290075Sobrien write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type)); 204390075Sobrien} 204490075Sobrien 204590075Sobrien/* Non-terminal <template-param>. PARM is a TEMPLATE_TYPE_PARM, 204690075Sobrien TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a 204790075Sobrien TEMPLATE_PARM_INDEX. 204890075Sobrien 204990075Sobrien <template-param> ::= T </parameter/ number> _ */ 205090075Sobrien 205190075Sobrienstatic void 205290075Sobrienwrite_template_param (parm) 205390075Sobrien tree parm; 205490075Sobrien{ 205590075Sobrien int parm_index; 205690075Sobrien 205790075Sobrien MANGLE_TRACE_TREE ("template-parm", parm); 205890075Sobrien 205990075Sobrien switch (TREE_CODE (parm)) 206090075Sobrien { 206190075Sobrien case TEMPLATE_TYPE_PARM: 206290075Sobrien case TEMPLATE_TEMPLATE_PARM: 206390075Sobrien case BOUND_TEMPLATE_TEMPLATE_PARM: 206490075Sobrien parm_index = TEMPLATE_TYPE_IDX (parm); 206590075Sobrien break; 206690075Sobrien 206790075Sobrien case TEMPLATE_PARM_INDEX: 206890075Sobrien parm_index = TEMPLATE_PARM_IDX (parm); 206990075Sobrien break; 207090075Sobrien 207190075Sobrien default: 207290075Sobrien abort (); 207390075Sobrien } 207490075Sobrien 207590075Sobrien write_char ('T'); 207690075Sobrien /* NUMBER as it appears in the mangling is (-1)-indexed, with the 207790075Sobrien earliest template param denoted by `_'. */ 207890075Sobrien if (parm_index > 0) 207990075Sobrien write_unsigned_number (parm_index - 1); 208090075Sobrien write_char ('_'); 208190075Sobrien} 208290075Sobrien 208390075Sobrien/* <template-template-param> 208490075Sobrien ::= <template-param> 208590075Sobrien ::= <substitution> */ 208690075Sobrien 208790075Sobrienstatic void 208890075Sobrienwrite_template_template_param (parm) 208990075Sobrien tree parm; 209090075Sobrien{ 209190075Sobrien tree template = NULL_TREE; 209290075Sobrien 209390075Sobrien /* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the 209490075Sobrien template template parameter. The substitution candidate here is 209590075Sobrien only the template. */ 209690075Sobrien if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM) 209790075Sobrien { 209890075Sobrien template 209990075Sobrien = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)); 210090075Sobrien if (find_substitution (template)) 210190075Sobrien return; 210290075Sobrien } 210390075Sobrien 210490075Sobrien /* <template-param> encodes only the template parameter position, 210590075Sobrien not its template arguments, which is fine here. */ 210690075Sobrien write_template_param (parm); 210790075Sobrien if (template) 210890075Sobrien add_substitution (template); 210990075Sobrien} 211090075Sobrien 211190075Sobrien/* Non-terminal <substitution>. 211290075Sobrien 211390075Sobrien <substitution> ::= S <seq-id> _ 211490075Sobrien ::= S_ */ 211590075Sobrien 211690075Sobrienstatic void 211790075Sobrienwrite_substitution (seq_id) 211890075Sobrien int seq_id; 211990075Sobrien{ 212090075Sobrien MANGLE_TRACE ("substitution", ""); 212190075Sobrien 212290075Sobrien write_char ('S'); 212390075Sobrien if (seq_id > 0) 212490075Sobrien write_number (seq_id - 1, /*unsigned=*/1, 36); 212590075Sobrien write_char ('_'); 212690075Sobrien} 212790075Sobrien 212890075Sobrien/* Start mangling a new name or type. */ 212990075Sobrien 213090075Sobrienstatic inline void 213190075Sobrienstart_mangling () 213290075Sobrien{ 213390075Sobrien obstack_free (&G.name_obstack, obstack_base (&G.name_obstack)); 213490075Sobrien} 213590075Sobrien 213690075Sobrien/* Done with mangling. Return the generated mangled name. */ 213790075Sobrien 213890075Sobrienstatic inline const char * 213990075Sobrienfinish_mangling () 214090075Sobrien{ 214190075Sobrien /* Clear all the substitutions. */ 214290075Sobrien VARRAY_POP_ALL (G.substitutions); 214390075Sobrien 214490075Sobrien /* Null-terminate the string. */ 214590075Sobrien write_char ('\0'); 214690075Sobrien 214790075Sobrien return (const char *) obstack_base (&G.name_obstack); 214890075Sobrien} 214990075Sobrien 215090075Sobrien/* Initialize data structures for mangling. */ 215190075Sobrien 215290075Sobrienvoid 215390075Sobrieninit_mangle () 215490075Sobrien{ 215590075Sobrien gcc_obstack_init (&G.name_obstack); 215690075Sobrien VARRAY_TREE_INIT (G.substitutions, 1, "mangling substitutions"); 215790075Sobrien 215890075Sobrien /* Cache these identifiers for quick comparison when checking for 215990075Sobrien standard substitutions. */ 216090075Sobrien subst_identifiers[SUBID_ALLOCATOR] = get_identifier ("allocator"); 216190075Sobrien subst_identifiers[SUBID_BASIC_STRING] = get_identifier ("basic_string"); 216290075Sobrien subst_identifiers[SUBID_CHAR_TRAITS] = get_identifier ("char_traits"); 216390075Sobrien subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream"); 216490075Sobrien subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream"); 216590075Sobrien subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream"); 216690075Sobrien} 216790075Sobrien 216890075Sobrien/* Generate the mangled name of DECL. */ 216990075Sobrien 217090075Sobrienstatic const char * 217190075Sobrienmangle_decl_string (decl) 217290075Sobrien tree decl; 217390075Sobrien{ 217490075Sobrien const char *result; 217590075Sobrien 217690075Sobrien start_mangling (); 217790075Sobrien 217890075Sobrien if (TREE_CODE (decl) == TYPE_DECL) 217990075Sobrien write_type (TREE_TYPE (decl)); 218090075Sobrien else if (/* The names of `extern "C"' functions are not mangled. */ 218190075Sobrien (DECL_EXTERN_C_FUNCTION_P (decl) 218290075Sobrien /* But overloaded operator names *are* mangled. */ 218390075Sobrien && !DECL_OVERLOADED_OPERATOR_P (decl)) 218490075Sobrien /* The names of global variables aren't mangled either. */ 218590075Sobrien || (TREE_CODE (decl) == VAR_DECL 218690075Sobrien && CP_DECL_CONTEXT (decl) == global_namespace) 218790075Sobrien /* And neither are `extern "C"' variables. */ 218890075Sobrien || (TREE_CODE (decl) == VAR_DECL 218990075Sobrien && DECL_EXTERN_C_P (decl))) 219090075Sobrien write_string (IDENTIFIER_POINTER (DECL_NAME (decl))); 219190075Sobrien else 219290075Sobrien { 219390075Sobrien write_mangled_name (decl); 219490075Sobrien if (DECL_LANG_SPECIFIC (decl) 219590075Sobrien && (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl) 219690075Sobrien || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl))) 219790075Sobrien /* We need a distinct mangled name for these entities, but 219890075Sobrien we should never actually output it. So, we append some 219990075Sobrien characters the assembler won't like. */ 220090075Sobrien write_string (" *INTERNAL* "); 220190075Sobrien } 220290075Sobrien 220390075Sobrien result = finish_mangling (); 220490075Sobrien if (DEBUG_MANGLE) 220590075Sobrien fprintf (stderr, "mangle_decl_string = '%s'\n\n", result); 220690075Sobrien return result; 220790075Sobrien} 220890075Sobrien 220990075Sobrien/* Create an identifier for the external mangled name of DECL. */ 221090075Sobrien 221190075Sobrienvoid 221290075Sobrienmangle_decl (decl) 221390075Sobrien tree decl; 221490075Sobrien{ 221590075Sobrien tree id = get_identifier (mangle_decl_string (decl)); 221690075Sobrien 221790075Sobrien SET_DECL_ASSEMBLER_NAME (decl, id); 221890075Sobrien} 221990075Sobrien 222090075Sobrien/* Generate the mangled representation of TYPE. */ 222190075Sobrien 222290075Sobrienconst char * 222390075Sobrienmangle_type_string (type) 222490075Sobrien tree type; 222590075Sobrien{ 222690075Sobrien const char *result; 222790075Sobrien 222890075Sobrien start_mangling (); 222990075Sobrien write_type (type); 223090075Sobrien result = finish_mangling (); 223190075Sobrien if (DEBUG_MANGLE) 223290075Sobrien fprintf (stderr, "mangle_type_string = '%s'\n\n", result); 223390075Sobrien return result; 223490075Sobrien} 223590075Sobrien 223690075Sobrien/* Create an identifier for the mangled representation of TYPE. */ 223790075Sobrien 223890075Sobrientree 223990075Sobrienmangle_type (type) 224090075Sobrien tree type; 224190075Sobrien{ 224290075Sobrien return get_identifier (mangle_type_string (type)); 224390075Sobrien} 224490075Sobrien 224590075Sobrien/* Create an identifier for the mangled name of a special component 224690075Sobrien for belonging to TYPE. CODE is the ABI-specified code for this 224790075Sobrien component. */ 224890075Sobrien 224990075Sobrienstatic tree 225090075Sobrienmangle_special_for_type (type, code) 225190075Sobrien tree type; 225290075Sobrien const char *code; 225390075Sobrien{ 225490075Sobrien const char *result; 225590075Sobrien 225690075Sobrien /* We don't have an actual decl here for the special component, so 225790075Sobrien we can't just process the <encoded-name>. Instead, fake it. */ 225890075Sobrien start_mangling (); 225990075Sobrien 226090075Sobrien /* Start the mangling. */ 226190075Sobrien write_string ("_Z"); 226290075Sobrien write_string (code); 226390075Sobrien 226490075Sobrien /* Add the type. */ 226590075Sobrien write_type (type); 226690075Sobrien result = finish_mangling (); 226790075Sobrien 226890075Sobrien if (DEBUG_MANGLE) 226990075Sobrien fprintf (stderr, "mangle_special_for_type = %s\n\n", result); 227090075Sobrien 227190075Sobrien return get_identifier (result); 227290075Sobrien} 227390075Sobrien 227490075Sobrien/* Create an identifier for the mangled representation of the typeinfo 227590075Sobrien structure for TYPE. */ 227690075Sobrien 227790075Sobrientree 227890075Sobrienmangle_typeinfo_for_type (type) 227990075Sobrien tree type; 228090075Sobrien{ 228190075Sobrien return mangle_special_for_type (type, "TI"); 228290075Sobrien} 228390075Sobrien 228490075Sobrien/* Create an identifier for the mangled name of the NTBS containing 228590075Sobrien the mangled name of TYPE. */ 228690075Sobrien 228790075Sobrientree 228890075Sobrienmangle_typeinfo_string_for_type (type) 228990075Sobrien tree type; 229090075Sobrien{ 229190075Sobrien return mangle_special_for_type (type, "TS"); 229290075Sobrien} 229390075Sobrien 229490075Sobrien/* Create an identifier for the mangled name of the vtable for TYPE. */ 229590075Sobrien 229690075Sobrientree 229790075Sobrienmangle_vtbl_for_type (type) 229890075Sobrien tree type; 229990075Sobrien{ 230090075Sobrien return mangle_special_for_type (type, "TV"); 230190075Sobrien} 230290075Sobrien 230390075Sobrien/* Returns an identifier for the mangled name of the VTT for TYPE. */ 230490075Sobrien 230590075Sobrientree 230690075Sobrienmangle_vtt_for_type (type) 230790075Sobrien tree type; 230890075Sobrien{ 230990075Sobrien return mangle_special_for_type (type, "TT"); 231090075Sobrien} 231190075Sobrien 231290075Sobrien/* Return an identifier for a construction vtable group. TYPE is 231390075Sobrien the most derived class in the hierarchy; BINFO is the base 231490075Sobrien subobject for which this construction vtable group will be used. 231590075Sobrien 231690075Sobrien This mangling isn't part of the ABI specification; in the ABI 231790075Sobrien specification, the vtable group is dumped in the same COMDAT as the 231890075Sobrien main vtable, and is referenced only from that vtable, so it doesn't 231990075Sobrien need an external name. For binary formats without COMDAT sections, 232090075Sobrien though, we need external names for the vtable groups. 232190075Sobrien 232290075Sobrien We use the production 232390075Sobrien 232490075Sobrien <special-name> ::= CT <type> <offset number> _ <base type> */ 232590075Sobrien 232690075Sobrientree 232790075Sobrienmangle_ctor_vtbl_for_type (type, binfo) 232890075Sobrien tree type; 232990075Sobrien tree binfo; 233090075Sobrien{ 233190075Sobrien const char *result; 233290075Sobrien 233390075Sobrien start_mangling (); 233490075Sobrien 233590075Sobrien write_string ("_Z"); 233690075Sobrien write_string ("TC"); 233790075Sobrien write_type (type); 233890075Sobrien write_integer_cst (BINFO_OFFSET (binfo)); 233990075Sobrien write_char ('_'); 234090075Sobrien write_type (BINFO_TYPE (binfo)); 234190075Sobrien 234290075Sobrien result = finish_mangling (); 234390075Sobrien if (DEBUG_MANGLE) 234490075Sobrien fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", result); 234590075Sobrien return get_identifier (result); 234690075Sobrien} 234790075Sobrien 234890075Sobrien/* Return an identifier for the mangled name of a thunk to FN_DECL. 234990075Sobrien OFFSET is the initial adjustment to this used to find the vptr. If 235090075Sobrien VCALL_OFFSET is non-NULL, this is a virtual thunk, and it is the 235190075Sobrien vtbl offset in bytes. 235290075Sobrien 235390075Sobrien <special-name> ::= Th <offset number> _ <base encoding> 235490075Sobrien ::= Tv <offset number> _ <vcall offset number> _ 235590075Sobrien <base encoding> 235690075Sobrien*/ 235790075Sobrien 235890075Sobrientree 235990075Sobrienmangle_thunk (fn_decl, offset, vcall_offset) 236090075Sobrien tree fn_decl; 236190075Sobrien tree offset; 236290075Sobrien tree vcall_offset; 236390075Sobrien{ 236490075Sobrien const char *result; 236590075Sobrien 236690075Sobrien start_mangling (); 236790075Sobrien 236890075Sobrien write_string ("_Z"); 236990075Sobrien /* The <special-name> for virtual thunks is Tv, for non-virtual 237090075Sobrien thunks Th. */ 237190075Sobrien write_char ('T'); 237290075Sobrien if (vcall_offset != 0) 237390075Sobrien write_char ('v'); 237490075Sobrien else 237590075Sobrien write_char ('h'); 237690075Sobrien 237790075Sobrien /* For either flavor, write the offset to this. */ 237890075Sobrien write_integer_cst (offset); 237990075Sobrien write_char ('_'); 238090075Sobrien 238190075Sobrien /* For a virtual thunk, add the vcall offset. */ 238290075Sobrien if (vcall_offset) 238390075Sobrien { 238490075Sobrien /* Virtual thunk. Write the vcall offset and base type name. */ 238590075Sobrien write_integer_cst (vcall_offset); 238690075Sobrien write_char ('_'); 238790075Sobrien } 238890075Sobrien 238990075Sobrien /* Scoped name. */ 239090075Sobrien write_encoding (fn_decl); 239190075Sobrien 239290075Sobrien result = finish_mangling (); 239390075Sobrien if (DEBUG_MANGLE) 239490075Sobrien fprintf (stderr, "mangle_thunk = %s\n\n", result); 239590075Sobrien return get_identifier (result); 239690075Sobrien} 239790075Sobrien 239890075Sobrien/* Return an identifier for the mangled unqualified name for a 239990075Sobrien conversion operator to TYPE. This mangling is not specified by the 240090075Sobrien ABI spec; it is only used internally. */ 240190075Sobrien 240290075Sobrientree 240390075Sobrienmangle_conv_op_name_for_type (type) 240490075Sobrien tree type; 240590075Sobrien{ 240690075Sobrien tree identifier; 240790075Sobrien 240890075Sobrien /* Build the mangling for TYPE. */ 240990075Sobrien const char *mangled_type = mangle_type_string (type); 241090075Sobrien /* Allocate a temporary buffer for the complete name. */ 241190075Sobrien char *op_name = concat ("operator ", mangled_type, NULL); 241290075Sobrien /* Find or create an identifier. */ 241390075Sobrien identifier = get_identifier (op_name); 241490075Sobrien /* Done with the temporary buffer. */ 241590075Sobrien free (op_name); 241690075Sobrien /* Set bits on the identifier so we know later it's a conversion. */ 241790075Sobrien IDENTIFIER_OPNAME_P (identifier) = 1; 241890075Sobrien IDENTIFIER_TYPENAME_P (identifier) = 1; 241990075Sobrien /* Hang TYPE off the identifier so it can be found easily later when 242090075Sobrien performing conversions. */ 242190075Sobrien TREE_TYPE (identifier) = type; 242290075Sobrien 242390075Sobrien return identifier; 242490075Sobrien} 242590075Sobrien 242690075Sobrien/* Return an identifier for the name of an initialization guard 242790075Sobrien variable for indicated VARIABLE. */ 242890075Sobrien 242990075Sobrientree 243090075Sobrienmangle_guard_variable (variable) 243190075Sobrien tree variable; 243290075Sobrien{ 243390075Sobrien start_mangling (); 243490075Sobrien write_string ("_ZGV"); 243590075Sobrien if (strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0) 243690075Sobrien /* The name of a guard variable for a reference temporary should refer 243790075Sobrien to the reference, not the temporary. */ 243890075Sobrien write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4); 243990075Sobrien else 244090075Sobrien write_name (variable, /*ignore_local_scope=*/0); 244190075Sobrien return get_identifier (finish_mangling ()); 244290075Sobrien} 244390075Sobrien 244490075Sobrien/* Return an identifier for the name of a temporary variable used to 244590075Sobrien initialize a static reference. This isn't part of the ABI, but we might 244690075Sobrien as well call them something readable. */ 244790075Sobrien 244890075Sobrientree 244990075Sobrienmangle_ref_init_variable (variable) 245090075Sobrien tree variable; 245190075Sobrien{ 245290075Sobrien start_mangling (); 245390075Sobrien write_string ("_ZGR"); 245490075Sobrien write_name (variable, /*ignore_local_scope=*/0); 245590075Sobrien return get_identifier (finish_mangling ()); 245690075Sobrien} 245790075Sobrien 245890075Sobrien 245990075Sobrien/* Foreign language type mangling section. */ 246090075Sobrien 246190075Sobrien/* How to write the type codes for the integer Java type. */ 246290075Sobrien 246390075Sobrienstatic void 246490075Sobrienwrite_java_integer_type_codes (type) 246590075Sobrien tree type; 246690075Sobrien{ 246790075Sobrien if (type == java_int_type_node) 246890075Sobrien write_char ('i'); 246990075Sobrien else if (type == java_short_type_node) 247090075Sobrien write_char ('s'); 247190075Sobrien else if (type == java_byte_type_node) 247290075Sobrien write_char ('c'); 247390075Sobrien else if (type == java_char_type_node) 247490075Sobrien write_char ('w'); 247590075Sobrien else if (type == java_long_type_node) 247690075Sobrien write_char ('x'); 247790075Sobrien else if (type == java_boolean_type_node) 247890075Sobrien write_char ('b'); 247990075Sobrien else 248090075Sobrien abort (); 248190075Sobrien} 248290075Sobrien 2483