1169689Skan/* Some code common to C++ and ObjC++ front ends.
2169689Skan   Copyright (C) 2004 Free Software Foundation, Inc.
3169689Skan   Contributed by Ziemowit Laski  <zlaski@apple.com>
4169689Skan
5169689SkanThis file is part of GCC.
6169689Skan
7169689SkanGCC is free software; you can redistribute it and/or modify it under
8169689Skanthe terms of the GNU General Public License as published by the Free
9169689SkanSoftware Foundation; either version 2, or (at your option) any later
10169689Skanversion.
11169689Skan
12169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
14169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15169689Skanfor more details.
16169689Skan
17169689SkanYou should have received a copy of the GNU General Public License
18169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
21169689Skan
22169689Skan#include "config.h"
23169689Skan#include "system.h"
24169689Skan#include "coretypes.h"
25169689Skan#include "tm.h"
26169689Skan#include "tree.h"
27169689Skan#include "cp-tree.h"
28169689Skan#include "c-common.h"
29169689Skan#include "toplev.h"
30169689Skan#include "langhooks.h"
31169689Skan#include "langhooks-def.h"
32169689Skan#include "diagnostic.h"
33169689Skan#include "debug.h"
34169689Skan#include "cxx-pretty-print.h"
35169689Skan#include "cp-objcp-common.h"
36169689Skan
37169689Skan/* Special routine to get the alias set for C++.  */
38169689Skan
39169689SkanHOST_WIDE_INT
40169689Skancxx_get_alias_set (tree t)
41169689Skan{
42169689Skan  if (IS_FAKE_BASE_TYPE (t))
43169689Skan    /* The base variant of a type must be in the same alias set as the
44169689Skan       complete type.  */
45169689Skan    return get_alias_set (TYPE_CONTEXT (t));
46169689Skan
47169689Skan  /* Punt on PMFs until we canonicalize functions properly.  */
48169689Skan  if (TYPE_PTRMEMFUNC_P (t))
49169689Skan    return 0;
50169689Skan
51169689Skan  return c_common_get_alias_set (t);
52169689Skan}
53169689Skan
54169689Skan/* Called from check_global_declarations.  */
55169689Skan
56169689Skanbool
57169689Skancxx_warn_unused_global_decl (tree decl)
58169689Skan{
59169689Skan  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
60169689Skan    return false;
61169689Skan  if (DECL_IN_SYSTEM_HEADER (decl))
62169689Skan    return false;
63169689Skan
64169689Skan  /* Const variables take the place of #defines in C++.  */
65169689Skan  if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl))
66169689Skan    return false;
67169689Skan
68169689Skan  return true;
69169689Skan}
70169689Skan
71169689Skan/* Langhook for expr_size: Tell the backend that the value of an expression
72169689Skan   of non-POD class type does not include any tail padding; a derived class
73169689Skan   might have allocated something there.  */
74169689Skan
75169689Skantree
76169689Skancp_expr_size (tree exp)
77169689Skan{
78169689Skan  tree type = TREE_TYPE (exp);
79169689Skan
80169689Skan  if (CLASS_TYPE_P (type))
81169689Skan    {
82169689Skan      /* The backend should not be interested in the size of an expression
83169689Skan	 of a type with both of these set; all copies of such types must go
84169689Skan	 through a constructor or assignment op.  */
85169689Skan      gcc_assert (!TYPE_HAS_COMPLEX_INIT_REF (type)
86169689Skan		  || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)
87169689Skan		  /* But storing a CONSTRUCTOR isn't a copy.  */
88169689Skan		  || TREE_CODE (exp) == CONSTRUCTOR
89169689Skan		  /* And, the gimplifier will sometimes make a copy of
90169689Skan		     an aggregate.  In particular, for a case like:
91169689Skan
92169689Skan			struct S { S(); };
93169689Skan			struct X { int a; S s; };
94169689Skan			X x = { 0 };
95169689Skan
96169689Skan		     the gimplifier will create a temporary with
97169689Skan		     static storage duration, perform static
98169689Skan		     initialization of the temporary, and then copy
99169689Skan		     the result.  Since the "s" subobject is never
100169689Skan		     constructed, this is a valid transformation.  */
101169689Skan		  || CP_AGGREGATE_TYPE_P (type));
102169689Skan
103169689Skan      /* This would be wrong for a type with virtual bases, but they are
104169689Skan	 caught by the assert above.  */
105169689Skan      return (is_empty_class (type)
106169689Skan	      ? size_zero_node
107169689Skan	      : CLASSTYPE_SIZE_UNIT (type));
108169689Skan    }
109169689Skan  else
110169689Skan    /* Use the default code.  */
111169689Skan    return lhd_expr_size (exp);
112169689Skan}
113169689Skan
114169689Skan/* Langhook for tree_size: determine size of our 'x' and 'c' nodes.  */
115169689Skansize_t
116169689Skancp_tree_size (enum tree_code code)
117169689Skan{
118169689Skan  switch (code)
119169689Skan    {
120169689Skan    case TINST_LEVEL:		return sizeof (struct tinst_level_s);
121169689Skan    case PTRMEM_CST:		return sizeof (struct ptrmem_cst);
122169689Skan    case BASELINK:		return sizeof (struct tree_baselink);
123169689Skan    case TEMPLATE_PARM_INDEX:	return sizeof (template_parm_index);
124169689Skan    case DEFAULT_ARG:		return sizeof (struct tree_default_arg);
125169689Skan    case OVERLOAD:		return sizeof (struct tree_overload);
126169689Skan    default:
127169689Skan      gcc_unreachable ();
128169689Skan    }
129169689Skan  /* NOTREACHED */
130169689Skan}
131169689Skan
132169689Skan/* Returns true if T is a variably modified type, in the sense of C99.
133169689Skan   FN is as passed to variably_modified_p.
134169689Skan   This routine needs only check cases that cannot be handled by the
135169689Skan   language-independent logic in tree.c.  */
136169689Skan
137169689Skanbool
138169689Skancp_var_mod_type_p (tree type, tree fn)
139169689Skan{
140169689Skan  /* If TYPE is a pointer-to-member, it is variably modified if either
141169689Skan     the class or the member are variably modified.  */
142169689Skan  if (TYPE_PTR_TO_MEMBER_P (type))
143169689Skan    return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type), fn)
144169689Skan	    || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type),
145169689Skan					 fn));
146169689Skan
147169689Skan  /* All other types are not variably modified.  */
148169689Skan  return false;
149169689Skan}
150169689Skan
151169689Skan/* Construct a C++-aware pretty-printer for CONTEXT.  It is assumed
152169689Skan   that CONTEXT->printer is an already constructed basic pretty_printer.  */
153169689Skanvoid
154169689Skancxx_initialize_diagnostics (diagnostic_context *context)
155169689Skan{
156169689Skan  pretty_printer *base = context->printer;
157169689Skan  cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
158169689Skan  memcpy (pp_base (pp), base, sizeof (pretty_printer));
159169689Skan  pp_cxx_pretty_printer_init (pp);
160169689Skan  context->printer = (pretty_printer *) pp;
161169689Skan
162169689Skan  /* It is safe to free this object because it was previously malloc()'d.  */
163169689Skan  free (base);
164169689Skan}
165169689Skan
166169689Skan/* This compares two types for equivalence ("compatible" in C-based languages).
167169689Skan   This routine should only return 1 if it is sure.  It should not be used
168169689Skan   in contexts where erroneously returning 0 causes problems.  */
169169689Skan
170169689Skanint
171169689Skancxx_types_compatible_p (tree x, tree y)
172169689Skan{
173169689Skan  if (same_type_ignoring_top_level_qualifiers_p (x, y))
174169689Skan    return 1;
175169689Skan
176169689Skan  /* Once we get to the middle-end, references and pointers are
177169689Skan     interchangeable.  FIXME should we try to replace all references with
178169689Skan     pointers?  */
179169689Skan  if (POINTER_TYPE_P (x) && POINTER_TYPE_P (y)
180169689Skan      && TYPE_MODE (x) == TYPE_MODE (y)
181169689Skan      && TYPE_REF_CAN_ALIAS_ALL (x) == TYPE_REF_CAN_ALIAS_ALL (y)
182169689Skan      && same_type_p (TREE_TYPE (x), TREE_TYPE (y)))
183169689Skan    return 1;
184169689Skan
185169689Skan  return 0;
186169689Skan}
187169689Skan
188169689Skantree
189169689Skancxx_staticp (tree arg)
190169689Skan{
191169689Skan  switch (TREE_CODE (arg))
192169689Skan    {
193169689Skan    case BASELINK:
194169689Skan      return staticp (BASELINK_FUNCTIONS (arg));
195169689Skan
196169689Skan    default:
197169689Skan      break;
198169689Skan    }
199169689Skan
200169689Skan  return NULL_TREE;
201169689Skan}
202169689Skan
203169689Skan/* Stubs to keep c-opts.c happy.  */
204169689Skanvoid
205169689Skanpush_file_scope (void)
206169689Skan{
207169689Skan}
208169689Skan
209169689Skanvoid
210169689Skanpop_file_scope (void)
211169689Skan{
212169689Skan}
213169689Skan
214169689Skan/* c-pragma.c needs to query whether a decl has extern "C" linkage.  */
215169689Skanbool
216169689Skanhas_c_linkage (tree decl)
217169689Skan{
218169689Skan  return DECL_EXTERN_C_P (decl);
219169689Skan}
220169689Skan
221169689Skanstatic GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
222169689Skan     htab_t shadowed_var_for_decl;
223169689Skan
224169689Skan/* Lookup a shadowed var for FROM, and return it if we find one.  */
225169689Skan
226169689Skantree
227169689Skandecl_shadowed_for_var_lookup (tree from)
228169689Skan{
229169689Skan  struct tree_map *h, in;
230169689Skan  in.from = from;
231169689Skan
232169689Skan  h = (struct tree_map *) htab_find_with_hash (shadowed_var_for_decl, &in,
233169689Skan					       htab_hash_pointer (from));
234169689Skan  if (h)
235169689Skan    return h->to;
236169689Skan  return NULL_TREE;
237169689Skan}
238169689Skan
239169689Skan/* Insert a mapping FROM->TO in the shadowed var hashtable.  */
240169689Skan
241169689Skanvoid
242169689Skandecl_shadowed_for_var_insert (tree from, tree to)
243169689Skan{
244169689Skan  struct tree_map *h;
245169689Skan  void **loc;
246169689Skan
247169689Skan  h = GGC_NEW (struct tree_map);
248169689Skan  h->hash = htab_hash_pointer (from);
249169689Skan  h->from = from;
250169689Skan  h->to = to;
251169689Skan  loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, h->hash, INSERT);
252169689Skan  *(struct tree_map **) loc = h;
253169689Skan}
254169689Skan
255169689Skanvoid
256169689Skaninit_shadowed_var_for_decl (void)
257169689Skan{
258169689Skan  shadowed_var_for_decl = htab_create_ggc (512, tree_map_hash,
259169689Skan					   tree_map_eq, 0);
260169689Skan}
261169689Skan
262261188Spfg/* APPLE LOCAL begin radar 5741070  */
263261188Spfg/* Given an IDENTIFIER tree for a class interface, find (if possible) and
264261188Spfg return the record type for the class interface.  */
265169689Skan
266261188Spfgtree
267261188Spfgc_return_interface_record_type (tree typename)
268261188Spfg{
269261188Spfg  enum tree_code_class class;
270261188Spfg  enum tree_code code;
271261188Spfg  tree retval = NULL;
272261188Spfg
273261188Spfg  if (typename == NULL)
274261188Spfg      return retval;
275261188Spfg
276261188Spfg  code = TREE_CODE (typename);
277261188Spfg  class = TREE_CODE_CLASS (code);
278261188Spfg
279261188Spfg  if (code != IDENTIFIER_NODE
280261188Spfg      || class != tcc_exceptional)
281261188Spfg      return retval;
282261188Spfg
283261188Spfg  if (TREE_TYPE (typename)
284261188Spfg      && TREE_CODE (TREE_TYPE (typename)) == RECORD_TYPE)
285261188Spfg      retval = TREE_TYPE (typename);
286261188Spfg
287261188Spfg  if (retval
288261188Spfg      && TREE_CODE (retval) != RECORD_TYPE)
289261188Spfg      retval = NULL;
290261188Spfg
291261188Spfg  return retval;
292261188Spfg}
293261188Spfg/* APPLE LOCAL end radar 5741070  */
294261188Spfg
295169689Skan#include "gt-cp-cp-objcp-common.h"
296