From 8db29d88f3e8d5fc43b25d9e0049c25f6bfb74d1 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Tue, 31 Jan 2017 01:02:03 +0000 Subject: Introduce C++ support in libcc1 Extend libcc1's with an API for C++ support. Extend libcc1's C API to distinguish between integral types with the same width, as in C++. Likewise for float types. Export small bits of functionality from the C++ front-end for use in libcc1. Add support for the C++ front-end to look up names and addresses using a libcc1-registered binding oracle. Add support for global friends. for gcc/cp/ChangeLog Introduce C++ support in libcc1. * cp-tree.h (struct lang_identifier): Add oracle_looked_up. (ansi_opname): Rename to... (cp_operator_id): ... this. Adjust all callers. (ansi_assopname): Rename to... (cp_assignment_operator_id): ... this. Adjust all callers. (cp_literal_operator_id): Declare. (set_global_friend): Declare. (is_global_friend): Declare. (enum cp_oracle_request): New type. (cp_binding_oracle_function): New type. (cp_binding_oracle): Declare. (cp_finish_injected_record_type): Declare. * friend.c (global_friend): New var. (set_global_friend): New fn. (is_global_friend): New fn. (is_friend): Call is_global_friend. * name-lookup.c (cp_binding_oracle): New var. (query_oracle): New fn. (qualified_lookup_using_namespace): Call query_oracle. (lookup_name_real_1): Likewise. * parser.c (cp_literal_operator_id): Drop static. * search.c (friend_accessible_p): Call is_global_friend. * semantics.c (is_this_parameter): Accept a variable if the binding oracle is enabled. for include/ChangeLog Introduce C++ support in libcc1. * gcc-c-fe.def (int_type_v0): Rename from... (int_type): ... this. Introduce new version. (float_type_v0): Rename from... (float_type): ... this. Introduce new version. (char_type): New. * gcc-c-interface.h (gcc_c_api_version): Add GCC_C_FE_VERSION_1. (gcc_type_array): Move... * gcc-interface.h: ... here. * gcc-cp-fe.def: New. * gcc-cp-interface.h: New. for libcc1/ChangeLog Introduce C++ support. * Makefile.am (AM_CPPFLAGS): Move some -I flags to... (CPPFLAGS_FOR_C_FAMILY, CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): ... new macros. (plugin_LTLIBRARIES): Add libcp1plugin.la. (BUILT_SOURCES, MOSTLYCLEANFILES): Add... (cp-compiler-name.h): ... this. New. (c-compiler-name.h): Rename all over from... (compiler-name.h): ... this. Create it atomically. (marshall_c_source, marshall_cxx_source): New macros. (libcc1plugin_la_SOURCES): Rename plugin.cc to libcc1plugin.cc. Add marshall_c_source expansion. (libcc1plugin.lo_CPPFLAGS): New macro. (libcp1plugin_la_LDFLAGS): Likewise. (libcp1plugin_la_SOURCES): Likewise. (libcp1plugin.lo_CPPFLAGS): Likewise. (libcp1plugin_la_LIBADD): Likewise. (libcp1plugin_la_DEPENDENCIES): Likewise. (libcp1plugin_la_LINK): Likewise. (libcc1_la_SOURCES): Added marshall_c_source and marshall_cxx_source expansions. * Makefile.in: Rebuild. * compiler-name.h: Rename all over to... * c-compiler-name.h: ... this. Define C_COMPILER_NAME instead of COMPILER_NAME. * plugin.cc: Rename all over to... * libcc1plugin.cc: ... this. Include marshall-c.hh. (address_rewriter): Drop cleaning up of VLA sizes. (plugin_build_decl): Mark decls as external. (plugin_tagbind): Propagate name to all variants. (build_anonymous_node): New. (plugin_build_record_type): Use it instead of make_node. (plugin_build_union_type): Likewise. (plugin_build_enum_type): Likewise. (plugin_finish_record_or_union): Update all type variants. (safe_lookup_builtin_type): New. (plugin_int_check): Factor out of, and add checks to, ... (plugin_int_type): ... this. Rename to... (plugin_int_type_v0): ... this. (plugin_int_type): New interface, new implementation. (plugin_char_type): New. (plugin_float_type_v0): Rename from... (plugin_float_type): ... this. New interface, new implementation. (plugin_init): Bump handshake version. * libcc1.cc: Include marshall-c.hh. Drop gcc-interface.h. (call_binding_oracle): Rename to... (c_call_binding_oracle): ... this, into anonymous namespace. (call_symbol_address): Rename to... (c_call_symbol_address): ... this, likewise. (GCC_METHOD#): Move methods into cc1plugin::c:: namespace. (libcc1::compiler::find): Refer to C_COMPILER_NAME. (fork_exec): Bump to GCC_C_FE_VERSION_1. (libcc1_compile): Prefix callbacks with c_. (gcc_c_fe_context): Accept GCC_C_FE_VERSION_1. * libcc1.sym: Export gcc_cp_fe_context. * libcp1.cc: New, mostly copied and adjusted from libcc1.cc. * libcp1plugin.cc: New, initially copied from libcc1plugin.cc. * libcp1plugin.sym: New. * marshall-c.hh: New. Move C-specific types from... * marshall.cc: ... this. (cc1_plugin::marshall_array_start): New. (cc1_plugin::marshall_array_elmts): New. (cc1_plugin::marshall for gcc_type_array): Use the above. (cc1_plugin::unmarshall_array_start): New. (cc1_plugin::unmarshall_array_elmts): New. (cc1_plugin::unmarshall for gcc_type_array): Use the above. * marshall.hh: Declare the new array building blocks. Drop C-specific unmarshall declarations. * marshall-cp.hh: New. * names.cc (GCC_METHOD#): Add LANG:: to method names. (LANG): Define while including gcc-c-fe.def and gcc-cp-fe.def. * names.hh: Include gcc-c-fe.def and gcc-cp-fe.def in the corresponding namespaces. * rpc.hh: Don't include marshall.hh. [GCC_CP_INTERFACE_H] (argument_wrapper): Specialize for gcc_vbase_array, gcc_cp_template_args, gcc_cp_function_args. From-SVN: r245051 --- include/ChangeLog | 14 + include/gcc-c-fe.def | 35 +- include/gcc-c-interface.h | 21 +- include/gcc-cp-fe.def | 1050 ++++++++++++++++++++++++++++++++++++++++++++ include/gcc-cp-interface.h | 496 +++++++++++++++++++++ include/gcc-interface.h | 14 + 6 files changed, 1610 insertions(+), 20 deletions(-) create mode 100644 include/gcc-cp-fe.def create mode 100644 include/gcc-cp-interface.h (limited to 'include') diff --git a/include/ChangeLog b/include/ChangeLog index c1a52db..43b2071 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,17 @@ +2017-01-30 Alexandre Oliva + + Introduce C++ support in libcc1. + * gcc-c-fe.def (int_type_v0): Rename from... + (int_type): ... this. Introduce new version. + (float_type_v0): Rename from... + (float_type): ... this. Introduce new version. + (char_type): New. + * gcc-c-interface.h (gcc_c_api_version): Add GCC_C_FE_VERSION_1. + (gcc_type_array): Move... + * gcc-interface.h: ... here. + * gcc-cp-fe.def: New. + * gcc-cp-interface.h: New. + 2017-01-30 Jan Kratochvil * gcc-interface.h (enum gcc_base_api_version): Update comment diff --git a/include/gcc-c-fe.def b/include/gcc-c-fe.def index 09998ba..acf1940 100644 --- a/include/gcc-c-fe.def +++ b/include/gcc-c-fe.def @@ -125,16 +125,18 @@ GCC_METHOD3 (gcc_type, build_function_type, const struct gcc_type_array *, /* Argument ARGUMENT_TYPES. */ int /* bool */) /* Argument IS_VARARGS. */ -/* Return an integer type with the given properties. */ +/* Return an integer type with the given properties. + Deprecated in v1, use int_type instead. */ -GCC_METHOD2 (gcc_type, int_type, +GCC_METHOD2 (gcc_type, int_type_v0, int /* bool */, /* Argument IS_UNSIGNED. */ unsigned long) /* Argument SIZE_IN_BYTES. */ -/* Return a floating point type with the given properties. */ +/* Return a floating point type with the given properties. + Deprecated in v1, use float_type instead. */ -GCC_METHOD1 (gcc_type, float_type, - unsigned long) /* Argument SIZE_IN_BYTES. */ +GCC_METHOD1 (gcc_type, float_type_v0, + unsigned long) /* Argument SIZE_IN_BYTES. */ /* Return the 'void' type. */ @@ -195,3 +197,26 @@ GCC_METHOD5 (int /* bool */, build_constant, GCC_METHOD1 (gcc_type, error, const char *) /* Argument MESSAGE. */ + +/* Return an integer type with the given properties. If BUILTIN_NAME + is non-NULL, it must name a builtin integral type with the given + signedness and size, and that is the type that will be returned. */ + +GCC_METHOD3 (gcc_type, int_type, + int /* bool */, /* Argument IS_UNSIGNED. */ + unsigned long, /* Argument SIZE_IN_BYTES. */ + const char *) /* Argument BUILTIN_NAME. */ + +/* Return the 'char' type, a distinct type from both 'signed char' and + 'unsigned char' returned by int_type. */ + +GCC_METHOD0 (gcc_type, char_type) + +/* Return a floating point type with the given properties. If BUILTIN_NAME + is non-NULL, it must name a builtin integral type with the given + signedness and size, and that is the type that will be returned. */ + +GCC_METHOD2 (gcc_type, float_type, + unsigned long, /* Argument SIZE_IN_BYTES. */ + const char *) /* Argument BUILTIN_NAME. */ + diff --git a/include/gcc-c-interface.h b/include/gcc-c-interface.h index 00ccbfb..e048c86 100644 --- a/include/gcc-c-interface.h +++ b/include/gcc-c-interface.h @@ -41,7 +41,11 @@ struct gcc_c_context; enum gcc_c_api_version { - GCC_C_FE_VERSION_0 = 0 + GCC_C_FE_VERSION_0 = 0, + + /* Added char_type. Added new version of int_type and float_type, + deprecated int_type_v0 and float_type_v0. */ + GCC_C_FE_VERSION_1 = 1 }; /* Qualifiers. */ @@ -111,19 +115,6 @@ typedef gcc_address gcc_c_symbol_address_function (void *datum, struct gcc_c_context *ctxt, const char *identifier); -/* An array of types used for creating a function type. */ - -struct gcc_type_array -{ - /* Number of elements. */ - - int n_elements; - - /* The elements. */ - - gcc_type *elements; -}; - /* The vtable used by the C front end. */ struct gcc_c_fe_vtable @@ -146,7 +137,7 @@ struct gcc_c_fe_vtable provides the declaration. DATUM is an arbitrary piece of data that is passed back verbatim - to the callbakcs in requests. */ + to the callbacks in requests. */ void (*set_callbacks) (struct gcc_c_context *self, gcc_c_oracle_function *binding_oracle, diff --git a/include/gcc-cp-fe.def b/include/gcc-cp-fe.def new file mode 100644 index 0000000..c367c1d --- /dev/null +++ b/include/gcc-cp-fe.def @@ -0,0 +1,1050 @@ +/* Interface between GCC C++ FE and GDB -*- c -*- + + Copyright (C) 2014-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + + +/* Push namespace NAME as the current binding level, to which + newly-introduced decls will be bound. An empty string identifies + the global namespace, whereas NULL identifies an anonymous + namespace. A namespace named NAME is created in the current scope, + if needed. + + If the newly-created namespace is to be an inline namespace, see + make_namespace_inline. */ + +GCC_METHOD1 (int /* bool */, push_namespace, + const char *) /* Argument NAME. */ + +/* Push TYPE as the current binding level, making its members visible + for name lookup. The current scope before the call must be the + scope in which the class was declared. This should be used if the + definition of a class is already finished, but one wishes to define + a nested class, or to enter the scope of one of its member + functions. */ + +GCC_METHOD1 (int /* bool */, push_class, + gcc_type) /* Argument TYPE. */ + +/* Push FUNCTION_DECL as the current (empty) binding level (see + reactivate_decl). The current enclosing scope before the call must + be the scope in which the function was declared. */ + +GCC_METHOD1 (int /* bool */, push_function, + gcc_decl) /* Argument FUNCTION_DECL. */ + +/* Make DECL visible (again?) within SCOPE. When SCOPE is NULL, it + means the current scope; if it is not NULL, it must name a function + that is currently active, even if not at the top of the binding + chain. + + This function can be used to make e.g. a global function or + variable visible in a namespace or local scope (overriding another + enclosing definition of the same name), but its most common + expected use of this primitive, that gives it its name, is to make + declarations visible again after reentering a function scope, + because when a function is entered with push_function, that does + NOT make any of the declarations nested in it visible for name + lookup. + + There is a reason/excuse for that: unlike namespaces and classes, + G++ doesn't ever have to reenter function scopes, so its name + resolution infrastructure is not prepared to do that. But wait, + there is also a good use for this apparent limitation: a function + may contain multiple scopes (blocks), and the name may be bound to + different symbols in each of these scopes. With this interface, as + we reenter a function scope, we may choose which symbols to make + visible for the code snippet, or, if there could be template + functions in local scopes, for unresolved names in nested template + class default arguments, or in nested template function signatures. + + As for making a local declaration visible for the code snippet, + there are two possibilities: a) introduce it upfront, while + entering the scope for the user expression (see the enter_scope + callback, called by g++ when encountering the push_user_expression + pragma), which might save some scope switching and reactivate_decl + (though this can't be helped if some declarations have to be + introduced and discarded, because of multiple definitions of the + same name in different scopes within a function: they have to be + defined in discriminator order); or b) introduce it when its name + is looked up, entering the scope, introducing the declaration, + leaving the scope, and then reactivating the declaration in its + local scope. + + Here's some more detail on how reactivate_decl works. Say there's + a function foo whose body looks like this: + + { + { +// point 1 + class c {} o __attribute__ ((__used__)); // c , o + } + struct c { + void f() { +// point 2 + } + } o __attribute__ ((__used__)); // c_0, o_0 + { + class c {} p __attribute__ ((__used__)); // c_1, p +// point 3 + o.f(); + } + } + + When we are about to define class c at point 1, we enter the + function foo scope, and since no symbols are visible at point 1, we + proceed to declare class c. We may then define the class right + away, or, if we leave the function scope, and we later wish to + define it, or to define object o, we can reenter the scope and just + use the previously-obtained gcc_decl to define the class, without + having to reactivate the declaration. + + Now, if we are to set up the binding context for point 2, we have + to define c_0::f, and in order to do so, we have to declare and + define c_0. Before we can declare c_0, we MUST at least declare c. + + As a general rule, before we can declare or define any local name + with a discriminator, we have to at least declare any other + occurrences of the same name in the same enclosing entity with + lower or absent discriminator. + + So, we declare c, then we leave the function scope and reenter it + so as to declare c_0 (also with name "c", which is why we have to + leave and reenter the function scope, otherwise we would get an + error because of the duplicate definition; g++ will assign a + discriminator because it still remembers there was an earlier + declaration of c_0 within the function, it's just no longer in + scope), then we can define c_0, including its member function f. + + Likewise, if we wish to define o_0, we have to define o first. If + we wish to declare (and maybe then define) c_1, we have to at least + declare (c and then) c_0 first. + + Then, as we set up the binding context to compile a code snippet at + point 3, we may choose to activate c_1, o_0 and p upfront, + declaring and discarding c, c_0 and o, and then reentering the + funciton scope to declare c_1, o_0 and p; or we can wait for oracle + lookups of c, o or p. If c is looked up, and the debugger resolves + c in the scope to c_1, it is expected to enter the function scope + from the top level, declare c, leave it, reenter it, declare c_0, + leave it, reenter it, declare c_1, leave it, and then reactivate + c_1 in the function scope. If c_1 is needed as a complete type, + the definition may be given right after the declaration, or the + scope will have to be reentered in order to define the class. + +. If the code snippet is at point 2, we don't need to (re)activate + any declaration: nothing from any local scope is visible. Just + entering the scope of the class containing member function f + reactivates the names of its members, including the class name + itself. */ + +GCC_METHOD2 (int /* bool */, reactivate_decl, + gcc_decl, /* Argument DECL. */ + gcc_decl) /* Argument SCOPE. */ + +/* Pop the namespace last entered with push_namespace, or class last + entered with push_class, or function last entered with + push_function, restoring the binding level in effect before the + matching push_* call. */ + +GCC_METHOD0 (int /* bool */, pop_binding_level) + +/* Return the NAMESPACE_DECL, TYPE_DECL or FUNCTION_DECL of the + binding level that would be popped by pop_scope. */ + +GCC_METHOD0 (gcc_decl, get_current_binding_level_decl) + +/* Make the current binding level an inline namespace. It must be a + namespace to begin with. It is safe to call this more than once + for the same namespace, but after the first call, subsequent ones + will not return a success status. */ + +GCC_METHOD0 (int /* bool */, make_namespace_inline) + +/* Add USED_NS to the namespaces used by the current binding level. + Use get_current_binding_level_decl to obtain USED_NS's + gcc_decl. */ + +GCC_METHOD1 (int /* bool */, add_using_namespace, + gcc_decl) /* Argument USED_NS. */ + +/* Introduce a namespace alias declaration, as in: + + namespace foo = [... ::] bar; + + After this call, namespace TARGET will be visible as ALIAS within + the current namespace. Get the declaration for TARGET by calling + get_current_binding_level_decl after pushing into it. */ + +GCC_METHOD2 (int /* bool */, add_namespace_alias, + const char *, /* Argument ALIAS. */ + gcc_decl) /* Argument TARGET. */ + +/* Introduce a using declaration, as in: + + using foo::bar; + + The TARGET decl names the qualifying scope (foo:: above) and the + identifier (bar), but that does not mean that only TARGET will be + brought into the current scope: all bindings of TARGET's identifier + in the qualifying scope will be brought in. + + FLAGS should specify GCC_CP_SYMBOL_USING. If the current scope is + a class scope, visibility flags must be supplied. + + Even when TARGET is template dependent, we don't need to specify + whether or not it is a typename: the supplied declaration (that + could be a template-dependent type converted to declaration by + get_type_decl) indicates so. */ + +GCC_METHOD2 (int /* bool */, add_using_decl, + enum gcc_cp_symbol_kind, /* Argument FLAGS. */ + gcc_decl) /* Argument TARGET. */ + +/* Create a new "decl" in GCC, and bind it in the current binding + level. A decl is a declaration, basically a kind of symbol. + + NAME is the name of the new symbol. SYM_KIND is the kind of + symbol being requested. SYM_TYPE is the new symbol's C++ type; + except for labels, where this is not meaningful and should be + zero. If SUBSTITUTION_NAME is not NULL, then a reference to this + decl in the source will later be substituted with a dereference + of a variable of the given name. Otherwise, for symbols having + an address (e.g., functions), ADDRESS is the address. FILENAME + and LINE_NUMBER refer to the symbol's source location. If this + is not known, FILENAME can be NULL and LINE_NUMBER can be 0. + This function returns the new decl. + + Use this function to register typedefs, functions and variables to + namespace and local binding levels, and typedefs, member functions + (static or not), and static data members to class binding levels. + Class members must have their access controls specified with + GCC_CP_ACCESS_* flags in SYM_KIND. + + Note that, since access controls are disabled, we have no means to + express private, protected and public. + + There are various flags that can be set in SYM_KIND to specify + additional semantics. Look for GCC_CP_FLAGs in the definition of + enum gcc_cp_symbol_kind in gcc-cp-interface.h. + + In order to define member functions, pass GCC_CP_SYMBOL_FUNCTION in + SYM_KIND, and a function_type for static member functions or a + method type for non-static member functions, including constructors + and destructors. Use build_function_type to create a function + type; for a method type, start by creating a function type without + any compiler-introduced artificial arguments (the implicit this + pointer, and the __in_chrg added to constructors and destructors, + and __vtt_parm added to the former), and then use build_method_type + to create the method type out of the class type and the function + type. + + For operator functions, set GCC_CP_FLAG_SPECIAL_FUNCTION in + SYM_KIND, in addition to any other applicable flags, and pass as + NAME a string starting with the two-character mangling for operator + name: "ps" for unary plus, "mL" for multiply and assign, *=; etc. + Use "cv" for type converstion operators (the target type portion + may be omitted, as it is taken from the return type in SYM_TYPE). + For operator"", use "li" followed by the identifier (the mangled + name mandates digits specifying the length of the identifier; if + present, they determine the end of the identifier, otherwise, the + identifier extents to the end of the string, so that "li3_Kme" and + "li_Km" are equivalent). + + Constructors and destructors need special care, because for each + constructor and destructor there may be multiple clones defined + internally by the compiler. With build_decl, you can introduce the + base declaration of a constructor or a destructor, setting + GCC_CP_FLAG_SPECIAL_FUNCTION the flag and using names starting with + capital "C" or "D", respectively, followed by a digit (see below), + a blank, or NUL ('\0'). DO NOT supply an ADDRESS or a + SUBSTITUTION_NAME to build_decl, it would be meaningless (and + rejected) for the base declaration; use define_cdtor_clone to + introduce the address of each clone. For constructor templates, + declare the template with build_decl, and then, for each + specialization, introduce it with + build_function_template_specialization, and then define the + addresses of each of its clones with define_cdtor_clone. + + NAMEs for GCC_CP_FLAG_SPECIAL_FUNCTION: + + NAME meaning + C? constructor base declaration (? may be 1, 2, 4, blank or NUL) + D? destructor base declaration (? may be 0, 1, 2, 4, blank or NUL) + nw operator new + na operator new[] + dl operator delete + da operator delete[] + ps operator + (unary) + ng operator - (unary) + ad operator & (unary) + de operator * (unary) + co operator ~ + pl operator + + mi operator - + ml operator * + dv operator / + rm operator % + an operator & + or operator | + eo operator ^ + aS operator = + pL operator += + mI operator -= + mL operator *= + dV operator /= + rM operator %= + aN operator &= + oR operator |= + eO operator ^= + ls operator << + rs operator >> + lS operator <<= + rS operator >>= + eq operator == + ne operator != + lt operator < + gt operator > + le operator <= + ge operator >= + nt operator ! + aa operator && + oo operator || + pp operator ++ + mm operator -- + cm operator , + pm operator ->* + pt operator -> + cl operator () + ix operator [] + qu operator ? + cv operator (conversion operator) + li operator "" + + FIXME: How about attributes? */ + +GCC_METHOD7 (gcc_decl, build_decl, + const char *, /* Argument NAME. */ + enum gcc_cp_symbol_kind, /* Argument SYM_KIND. */ + gcc_type, /* Argument SYM_TYPE. */ + const char *, /* Argument SUBSTITUTION_NAME. */ + gcc_address, /* Argument ADDRESS. */ + const char *, /* Argument FILENAME. */ + unsigned int) /* Argument LINE_NUMBER. */ + +/* Supply the ADDRESS of one of the multiple clones of constructor or + destructor CDTOR. The clone is specified by NAME, using the + following name mangling conventions: + + C1 in-charge constructor + C2 not-in-charge constructor + C4 unified constructor + D0 deleting destructor + D1 in-charge destructor + D2 not-in-charge destructor + D4 unified destructor + + The following information is not necessary to use the API. + + C1 initializes an instance of the class (rather than of derived + classes), including virtual base classes, whereas C2 initializes a + sub-object (of the given class type) of an instance of some derived + class (or a full object that doesn't have any virtual base + classes). + + D0 and D1 destruct an instance of the class, including virtual base + classes, but only the former calls operator delete to release the + object's storage at the end; D2 destructs a sub-object (of the + given class type) of an instance of a derived class (or a full + object that doesn't have any virtual base classes). + + The [CD]4 manglings (and symbol definitions) are non-standard, but + GCC uses them in some cases: rather than assuming they are + in-charge or not-in-charge, they test the implicit argument that + the others ignore to tell how to behave. These are used instead of + cloning when we just can't use aliases. */ + +GCC_METHOD3 (gcc_decl, define_cdtor_clone, + const char *, /* Argument NAME. */ + gcc_decl, /* Argument CDTOR. */ + gcc_address) /* Argument ADDRESS. */ + +/* Return the type associated with the given declaration. This is + most useful to obtain the type associated with a forward-declared + class, because it is the gcc_type, rather than the gcc_decl, that + has to be used to build other types, but build_decl returns a + gcc_decl rather than a gcc_type. This call can in theory be used + to obtain the type from any other declaration; it is supposed to + return the same type that was supplied when the declaration was + created. */ + +GCC_METHOD1 (gcc_type, get_decl_type, + gcc_decl) /* Argument DECL. */ + +/* Return the declaration for a type. */ + +GCC_METHOD1 (gcc_decl, get_type_decl, + gcc_type) /* Argument TYPE. */ + +/* Declare DECL as a friend of the current class scope, if TYPE is + NULL, or of TYPE itself otherwise. DECL may be a function or a + class, be they template generics, template specializations or not + templates. TYPE must be a class type (not a template generic). + + The add_friend call cannot introduce a declaration; even if the + friend is first declared as a friend in the source code, the + declaration belongs in the enclosing namespace, so it must be + introduced in that namespace, and the resulting declaration can + then be made a friend. + + DECL cannot, however, be a member of a template class generic, + because we have no means to introduce their declarations. This + interface has no notion of definitions for template generics. As a + consequence, users of this interface must introduce each friend + template member specialization separately, i.e., instead of: + + template friend struct X::M; + + they must be declared as if they were: + + friend struct X::M; + friend struct X::M; + ... for each specialization of X. + + + Specializations of a template can have each others' members as + friends: + + template class foo { + int f(); + template friend int foo::f(); + }; + + It wouldn't always be possible to define all specializations of a + template class before introducing the friend declarations in their + expanded, per-specialization form. + + In order to simplify such friend declarations, and to enable + incremental friend declarations as template specializations are + introduced, add_friend can be called after the befriending class is + fully defined, passing it a non-NULL TYPE argument naming the + befriending class type. */ + +GCC_METHOD2 (int /* bool */, add_friend, + gcc_decl, /* Argument DECL. */ + gcc_type) /* Argument TYPE. */ + +/* Return the type of a pointer to a given base type. */ + +GCC_METHOD1 (gcc_type, build_pointer_type, + gcc_type) /* Argument BASE_TYPE. */ + +/* Return the type of a reference to a given base type. */ + +GCC_METHOD2 (gcc_type, build_reference_type, + gcc_type, /* Argument BASE_TYPE. */ + enum gcc_cp_ref_qualifiers) /* Argument RQUALS. */ + +/* Create a new pointer-to-member type. MEMBER_TYPE is the data + member type, while CLASS_TYPE is the class type containing the data + member. For pointers to member functions, MEMBER_TYPE must be a + method type, and CLASS_TYPE must be specified even though it might + be possible to extract it from the method type. */ + +GCC_METHOD2 (gcc_type, build_pointer_to_member_type, + gcc_type, /* Argument CLASS_TYPE. */ + gcc_type) /* Argument MEMBER_TYPE. */ + +/* Start a template parameter list scope and enters it, so that + subsequent build_type_template_parameter and + build_value_template_parameter calls create template parameters in + the list. The list is closed by a build_decl call with + GCC_CP_SYMBOL_FUNCTION or GCC_CP_SYMBOL_CLASS, that, when the scope + is a template parameter list, declares a template function or a + template class with the then-closed parameter list. The scope in + which the new declaration is to be introduced by build_decl must be + entered before calling start_template_decl, and build_decl returns + to that scope, from the template parameter list scope, before + introducing the declaration. */ + +GCC_METHOD0 (int /* bool */, start_template_decl) + +/* Build a typename template-parameter (e.g., the T in template + ). Either PACK_P should be nonzero, to indicate an + argument pack (the last argument in a variadic template argument + list, as in template ), or DEFAULT_TYPE may be + non-NULL to set the default type argument (e.g. X) for the template + parameter. FILENAME and LINE_NUMBER may specify the source + location in which the template parameter was declared. */ + +GCC_METHOD5 (gcc_type, build_type_template_parameter, + const char *, /* Argument ID. */ + int /* bool */, /* Argument PACK_P. */ + gcc_type, /* Argument DEFAULT_TYPE. */ + const char *, /* Argument FILENAME. */ + unsigned int) /* Argument LINE_NUMBER. */ + +/* Build a template template-parameter (e.g., the T in template +