1 /* LTO symbol table.
2    Copyright (C) 2009-2013 Free Software Foundation, Inc.
3    Contributed by CodeSourcery, Inc.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "diagnostic-core.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "ggc.h"
28 #include "hashtab.h"
29 #include "plugin-api.h"
30 #include "lto-streamer.h"
31 
32 /* Vector to keep track of external variables we've seen so far.  */
33 vec<tree, va_gc> *lto_global_var_decls;
34 
35 /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
36    all edges and removing the old node.  */
37 
38 static void
lto_cgraph_replace_node(struct cgraph_node * node,struct cgraph_node * prevailing_node)39 lto_cgraph_replace_node (struct cgraph_node *node,
40 			 struct cgraph_node *prevailing_node)
41 {
42   struct cgraph_edge *e, *next;
43   bool compatible_p;
44 
45   if (cgraph_dump_file)
46     {
47       fprintf (cgraph_dump_file, "Replacing cgraph node %s/%i by %s/%i"
48  	       " for symbol %s\n",
49 	       cgraph_node_name (node), node->uid,
50 	       cgraph_node_name (prevailing_node),
51 	       prevailing_node->uid,
52 	       IDENTIFIER_POINTER ((*targetm.asm_out.mangle_assembler_name)
53 		 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->symbol.decl)))));
54     }
55 
56   /* Merge node flags.  */
57   if (node->symbol.force_output)
58     cgraph_mark_force_output_node (prevailing_node);
59   if (node->symbol.address_taken)
60     {
61       gcc_assert (!prevailing_node->global.inlined_to);
62       cgraph_mark_address_taken_node (prevailing_node);
63     }
64 
65   /* Redirect all incoming edges.  */
66   compatible_p
67     = types_compatible_p (TREE_TYPE (TREE_TYPE (prevailing_node->symbol.decl)),
68 			  TREE_TYPE (TREE_TYPE (node->symbol.decl)));
69   for (e = node->callers; e; e = next)
70     {
71       next = e->next_caller;
72       cgraph_redirect_edge_callee (e, prevailing_node);
73       /* If there is a mismatch between the supposed callee return type and
74 	 the real one do not attempt to inline this function.
75 	 ???  We really need a way to match function signatures for ABI
76 	 compatibility and perform related promotions at inlining time.  */
77       if (!compatible_p)
78 	e->call_stmt_cannot_inline_p = 1;
79     }
80   /* Redirect incomming references.  */
81   ipa_clone_referring ((symtab_node)prevailing_node, &node->symbol.ref_list);
82 
83   /* Finally remove the replaced node.  */
84   cgraph_remove_node (node);
85 }
86 
87 /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
88    all edges and removing the old node.  */
89 
90 static void
lto_varpool_replace_node(struct varpool_node * vnode,struct varpool_node * prevailing_node)91 lto_varpool_replace_node (struct varpool_node *vnode,
92 			  struct varpool_node *prevailing_node)
93 {
94   gcc_assert (!vnode->finalized || prevailing_node->finalized);
95   gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
96 
97   ipa_clone_referring ((symtab_node)prevailing_node, &vnode->symbol.ref_list);
98 
99   /* Be sure we can garbage collect the initializer.  */
100   if (DECL_INITIAL (vnode->symbol.decl))
101     DECL_INITIAL (vnode->symbol.decl) = error_mark_node;
102   /* Finally remove the replaced node.  */
103   varpool_remove_node (vnode);
104 }
105 
106 /* Merge two variable or function symbol table entries PREVAILING and ENTRY.
107    Return false if the symbols are not fully compatible and a diagnostic
108    should be emitted.  */
109 
110 static bool
lto_symtab_merge(symtab_node prevailing,symtab_node entry)111 lto_symtab_merge (symtab_node prevailing, symtab_node entry)
112 {
113   tree prevailing_decl = prevailing->symbol.decl;
114   tree decl = entry->symbol.decl;
115   tree prevailing_type, type;
116 
117   if (prevailing_decl == decl)
118     return true;
119 
120   /* Merge decl state in both directions, we may still end up using
121      the new decl.  */
122   TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
123   TREE_ADDRESSABLE (decl) |= TREE_ADDRESSABLE (prevailing_decl);
124 
125   /* The linker may ask us to combine two incompatible symbols.
126      Detect this case and notify the caller of required diagnostics.  */
127 
128   if (TREE_CODE (decl) == FUNCTION_DECL)
129     {
130       if (!types_compatible_p (TREE_TYPE (prevailing_decl),
131 			       TREE_TYPE (decl)))
132 	/* If we don't have a merged type yet...sigh.  The linker
133 	   wouldn't complain if the types were mismatched, so we
134 	   probably shouldn't either.  Just use the type from
135 	   whichever decl appears to be associated with the
136 	   definition.  If for some odd reason neither decl is, the
137 	   older one wins.  */
138 	(void) 0;
139 
140       return true;
141     }
142 
143   /* Now we exclusively deal with VAR_DECLs.  */
144 
145   /* Sharing a global symbol is a strong hint that two types are
146      compatible.  We could use this information to complete
147      incomplete pointed-to types more aggressively here, ignoring
148      mismatches in both field and tag names.  It's difficult though
149      to guarantee that this does not have side-effects on merging
150      more compatible types from other translation units though.  */
151 
152   /* We can tolerate differences in type qualification, the
153      qualification of the prevailing definition will prevail.
154      ???  In principle we might want to only warn for structurally
155      incompatible types here, but unless we have protective measures
156      for TBAA in place that would hide useful information.  */
157   prevailing_type = TYPE_MAIN_VARIANT (TREE_TYPE (prevailing_decl));
158   type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
159 
160   if (!types_compatible_p (prevailing_type, type))
161     {
162       if (COMPLETE_TYPE_P (type))
163 	return false;
164 
165       /* If type is incomplete then avoid warnings in the cases
166 	 that TBAA handles just fine.  */
167 
168       if (TREE_CODE (prevailing_type) != TREE_CODE (type))
169 	return false;
170 
171       if (TREE_CODE (prevailing_type) == ARRAY_TYPE)
172 	{
173 	  tree tem1 = TREE_TYPE (prevailing_type);
174 	  tree tem2 = TREE_TYPE (type);
175 	  while (TREE_CODE (tem1) == ARRAY_TYPE
176 		 && TREE_CODE (tem2) == ARRAY_TYPE)
177 	    {
178 	      tem1 = TREE_TYPE (tem1);
179 	      tem2 = TREE_TYPE (tem2);
180 	    }
181 
182 	  if (TREE_CODE (tem1) != TREE_CODE (tem2))
183 	    return false;
184 
185 	  if (!types_compatible_p (tem1, tem2))
186 	    return false;
187 	}
188 
189       /* Fallthru.  Compatible enough.  */
190     }
191 
192   /* ???  We might want to emit a warning here if type qualification
193      differences were spotted.  Do not do this unconditionally though.  */
194 
195   /* There is no point in comparing too many details of the decls here.
196      The type compatibility checks or the completing of types has properly
197      dealt with most issues.  */
198 
199   /* The following should all not invoke fatal errors as in non-LTO
200      mode the linker wouldn't complain either.  Just emit warnings.  */
201 
202   /* Report a warning if user-specified alignments do not match.  */
203   if ((DECL_USER_ALIGN (prevailing_decl) && DECL_USER_ALIGN (decl))
204       && DECL_ALIGN (prevailing_decl) < DECL_ALIGN (decl))
205     return false;
206 
207   return true;
208 }
209 
210 /* Return true if the symtab entry E can be replaced by another symtab
211    entry.  */
212 
213 static bool
lto_symtab_resolve_replaceable_p(symtab_node e)214 lto_symtab_resolve_replaceable_p (symtab_node e)
215 {
216   if (DECL_EXTERNAL (e->symbol.decl)
217       || DECL_COMDAT (e->symbol.decl)
218       || DECL_ONE_ONLY (e->symbol.decl)
219       || DECL_WEAK (e->symbol.decl))
220     return true;
221 
222   if (TREE_CODE (e->symbol.decl) == VAR_DECL)
223     return (DECL_COMMON (e->symbol.decl)
224 	    || (!flag_no_common && !DECL_INITIAL (e->symbol.decl)));
225 
226   return false;
227 }
228 
229 /* Return true if the symtab entry E can be the prevailing one.  */
230 
231 static bool
lto_symtab_resolve_can_prevail_p(symtab_node e)232 lto_symtab_resolve_can_prevail_p (symtab_node e)
233 {
234   if (!symtab_real_symbol_p (e))
235     return false;
236 
237   /* The C++ frontend ends up neither setting TREE_STATIC nor
238      DECL_EXTERNAL on virtual methods but only TREE_PUBLIC.
239      So do not reject !TREE_STATIC here but only DECL_EXTERNAL.  */
240   if (DECL_EXTERNAL (e->symbol.decl))
241     return false;
242 
243   /* For functions we need a non-discarded body.  */
244   if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
245     return (cgraph (e)->analyzed);
246 
247   else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
248     return varpool (e)->finalized;
249 
250   gcc_unreachable ();
251 }
252 
253 /* Resolve the symbol with the candidates in the chain *SLOT and store
254    their resolutions.  */
255 
256 static symtab_node
lto_symtab_resolve_symbols(symtab_node first)257 lto_symtab_resolve_symbols (symtab_node first)
258 {
259   symtab_node e;
260   symtab_node prevailing = NULL;
261 
262   /* Always set e->node so that edges are updated to reflect decl merging. */
263   for (e = first; e; e = e->symbol.next_sharing_asm_name)
264     if (symtab_real_symbol_p (e)
265 	&& (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
266 	    || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
267 	    || e->symbol.resolution == LDPR_PREVAILING_DEF))
268       {
269 	prevailing = e;
270 	break;
271       }
272 
273   /* If the chain is already resolved there is nothing else to do.  */
274   if (prevailing)
275     {
276       /* Assert it's the only one.  */
277       for (e = prevailing->symbol.next_sharing_asm_name; e; e = e->symbol.next_sharing_asm_name)
278 	if (symtab_real_symbol_p (e)
279 	    && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
280 		|| e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
281 		|| e->symbol.resolution == LDPR_PREVAILING_DEF))
282 	  fatal_error ("multiple prevailing defs for %qE",
283 		       DECL_NAME (prevailing->symbol.decl));
284       return prevailing;
285     }
286 
287   /* Find the single non-replaceable prevailing symbol and
288      diagnose ODR violations.  */
289   for (e = first; e; e = e->symbol.next_sharing_asm_name)
290     {
291       if (!lto_symtab_resolve_can_prevail_p (e))
292 	continue;
293 
294       /* If we have a non-replaceable definition it prevails.  */
295       if (!lto_symtab_resolve_replaceable_p (e))
296 	{
297 	  if (prevailing)
298 	    {
299 	      error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
300 			"%qD has already been defined", e->symbol.decl);
301 	      inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
302 		      "previously defined here");
303 	    }
304 	  prevailing = e;
305 	}
306     }
307   if (prevailing)
308     return prevailing;
309 
310   /* Do a second round choosing one from the replaceable prevailing decls.  */
311   for (e = first; e; e = e->symbol.next_sharing_asm_name)
312     {
313       if (!lto_symtab_resolve_can_prevail_p (e)
314 	  || !symtab_real_symbol_p (e))
315 	continue;
316 
317       /* Choose the first function that can prevail as prevailing.  */
318       if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
319 	{
320 	  prevailing = e;
321 	  break;
322 	}
323 
324       /* From variables that can prevail choose the largest one.  */
325       if (!prevailing
326 	  || tree_int_cst_lt (DECL_SIZE (prevailing->symbol.decl),
327 			      DECL_SIZE (e->symbol.decl))
328 	  /* When variables are equivalent try to chose one that has useful
329 	     DECL_INITIAL.  This makes sense for keyed vtables that are
330 	     DECL_EXTERNAL but initialized.  In units that do not need them
331 	     we replace the initializer by error_mark_node to conserve
332 	     memory.
333 
334 	     We know that the vtable is keyed outside the LTO unit - otherwise
335 	     the keyed instance would prevail.  We still can preserve useful
336 	     info in the initializer.  */
337 	  || (DECL_SIZE (prevailing->symbol.decl) == DECL_SIZE (e->symbol.decl)
338 	      && (DECL_INITIAL (e->symbol.decl)
339 		  && DECL_INITIAL (e->symbol.decl) != error_mark_node)
340 	      && (!DECL_INITIAL (prevailing->symbol.decl)
341 		  || DECL_INITIAL (prevailing->symbol.decl) == error_mark_node)))
342 	prevailing = e;
343     }
344 
345   return prevailing;
346 }
347 
348 /* Merge all decls in the symbol table chain to the prevailing decl and
349    issue diagnostics about type mismatches.  If DIAGNOSED_P is true
350    do not issue further diagnostics.*/
351 
352 static void
lto_symtab_merge_decls_2(symtab_node first,bool diagnosed_p)353 lto_symtab_merge_decls_2 (symtab_node first, bool diagnosed_p)
354 {
355   symtab_node prevailing, e;
356   vec<tree> mismatches = vNULL;
357   unsigned i;
358   tree decl;
359 
360   /* Nothing to do for a single entry.  */
361   prevailing = first;
362   if (!prevailing->symbol.next_sharing_asm_name)
363     return;
364 
365   /* Try to merge each entry with the prevailing one.  */
366   for (e = prevailing->symbol.next_sharing_asm_name;
367        e; e = e->symbol.next_sharing_asm_name)
368     {
369       if (!lto_symtab_merge (prevailing, e)
370 	  && !diagnosed_p)
371 	mismatches.safe_push (e->symbol.decl);
372     }
373   if (mismatches.is_empty ())
374     return;
375 
376   /* Diagnose all mismatched re-declarations.  */
377   FOR_EACH_VEC_ELT (mismatches, i, decl)
378     {
379       if (!types_compatible_p (TREE_TYPE (prevailing->symbol.decl),
380 			       TREE_TYPE (decl)))
381 	diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
382 				   "type of %qD does not match original "
383 				   "declaration", decl);
384 
385       else if ((DECL_USER_ALIGN (prevailing->symbol.decl)
386 	        && DECL_USER_ALIGN (decl))
387 	       && DECL_ALIGN (prevailing->symbol.decl) < DECL_ALIGN (decl))
388 	{
389 	  diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
390 				     "alignment of %qD is bigger than "
391 				     "original declaration", decl);
392 	}
393     }
394   if (diagnosed_p)
395     inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
396 	    "previously declared here");
397 
398   mismatches.release ();
399 }
400 
401 /* Helper to process the decl chain for the symbol table entry *SLOT.  */
402 
403 static void
lto_symtab_merge_decls_1(symtab_node first)404 lto_symtab_merge_decls_1 (symtab_node first)
405 {
406   symtab_node e, prevailing;
407   bool diagnosed_p = false;
408 
409   if (cgraph_dump_file)
410     {
411       fprintf (cgraph_dump_file, "Merging nodes for %s. Candidates:\n",
412 	       symtab_node_asm_name (first));
413       for (e = first; e; e = e->symbol.next_sharing_asm_name)
414 	dump_symtab_node (cgraph_dump_file, e);
415     }
416 
417   /* Compute the symbol resolutions.  This is a no-op when using the
418      linker plugin and resolution was decided by the linker.  */
419   prevailing = lto_symtab_resolve_symbols (first);
420 
421   /* If there's not a prevailing symbol yet it's an external reference.
422      Happens a lot during ltrans.  Choose the first symbol with a
423      cgraph or a varpool node.  */
424   if (!prevailing)
425     {
426       prevailing = first;
427       /* For variables chose with a priority variant with vnode
428 	 attached (i.e. from unit where external declaration of
429 	 variable is actually used).
430 	 When there are multiple variants, chose one with size.
431 	 This is needed for C++ typeinfos, for example in
432 	 lto/20081204-1 there are typeifos in both units, just
433 	 one of them do have size.  */
434       if (TREE_CODE (prevailing->symbol.decl) == VAR_DECL)
435 	{
436 	  for (e = prevailing->symbol.next_sharing_asm_name;
437 	       e; e = e->symbol.next_sharing_asm_name)
438 	    if (!COMPLETE_TYPE_P (TREE_TYPE (prevailing->symbol.decl))
439 		&& COMPLETE_TYPE_P (TREE_TYPE (e->symbol.decl)))
440 	      prevailing = e;
441 	}
442       /* For variables prefer the non-builtin if one is available.  */
443       else if (TREE_CODE (prevailing->symbol.decl) == FUNCTION_DECL)
444 	{
445 	  for (e = first; e; e = e->symbol.next_sharing_asm_name)
446 	    if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL
447 		&& !DECL_BUILT_IN (e->symbol.decl))
448 	      {
449 		prevailing = e;
450 		break;
451 	      }
452 	}
453     }
454 
455   symtab_prevail_in_asm_name_hash (prevailing);
456 
457   /* Diagnose mismatched objects.  */
458   for (e = prevailing->symbol.next_sharing_asm_name;
459        e; e = e->symbol.next_sharing_asm_name)
460     {
461       if (TREE_CODE (prevailing->symbol.decl)
462 	  == TREE_CODE (e->symbol.decl))
463 	continue;
464 
465       switch (TREE_CODE (prevailing->symbol.decl))
466 	{
467 	case VAR_DECL:
468 	  gcc_assert (TREE_CODE (e->symbol.decl) == FUNCTION_DECL);
469 	  error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
470 		    "variable %qD redeclared as function",
471 		    prevailing->symbol.decl);
472 	  break;
473 
474 	case FUNCTION_DECL:
475 	  gcc_assert (TREE_CODE (e->symbol.decl) == VAR_DECL);
476 	  error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
477 		    "function %qD redeclared as variable",
478 		    prevailing->symbol.decl);
479 	  break;
480 
481 	default:
482 	  gcc_unreachable ();
483 	}
484 
485       diagnosed_p = true;
486     }
487   if (diagnosed_p)
488       inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
489 	      "previously declared here");
490 
491   /* Merge the chain to the single prevailing decl and diagnose
492      mismatches.  */
493   lto_symtab_merge_decls_2 (prevailing, diagnosed_p);
494 
495   if (cgraph_dump_file)
496     {
497       fprintf (cgraph_dump_file, "After resolution:\n");
498       for (e = prevailing; e; e = e->symbol.next_sharing_asm_name)
499 	dump_symtab_node (cgraph_dump_file, e);
500     }
501 }
502 
503 /* Resolve and merge all symbol table chains to a prevailing decl.  */
504 
505 void
lto_symtab_merge_decls(void)506 lto_symtab_merge_decls (void)
507 {
508   symtab_node node;
509 
510   /* Populate assembler name hash.   */
511   symtab_initialize_asm_name_hash ();
512 
513   FOR_EACH_SYMBOL (node)
514     if (TREE_PUBLIC (node->symbol.decl)
515 	&& node->symbol.next_sharing_asm_name
516 	&& !node->symbol.previous_sharing_asm_name)
517     lto_symtab_merge_decls_1 (node);
518 }
519 
520 /* Helper to process the decl chain for the symbol table entry *SLOT.  */
521 
522 static void
lto_symtab_merge_cgraph_nodes_1(symtab_node prevailing)523 lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
524 {
525   symtab_node e, next;
526 
527   /* Replace the cgraph node of each entry with the prevailing one.  */
528   for (e = prevailing->symbol.next_sharing_asm_name; e;
529        e = next)
530     {
531       next = e->symbol.next_sharing_asm_name;
532 
533       if (!symtab_real_symbol_p (e))
534 	continue;
535       cgraph_node *ce = dyn_cast <cgraph_node> (e);
536       if (ce && !DECL_BUILT_IN (e->symbol.decl))
537 	lto_cgraph_replace_node (ce, cgraph (prevailing));
538       if (varpool_node *ve = dyn_cast <varpool_node> (e))
539 	lto_varpool_replace_node (ve, varpool (prevailing));
540     }
541 
542   return;
543 }
544 
545 /* Merge cgraph nodes according to the symbol merging done by
546    lto_symtab_merge_decls.  */
547 
548 void
lto_symtab_merge_cgraph_nodes(void)549 lto_symtab_merge_cgraph_nodes (void)
550 {
551   struct cgraph_node *cnode;
552   struct varpool_node *vnode;
553   symtab_node node;
554 
555   /* Populate assembler name hash.   */
556   symtab_initialize_asm_name_hash ();
557 
558   if (!flag_ltrans)
559     FOR_EACH_SYMBOL (node)
560       if (TREE_PUBLIC (node->symbol.decl)
561 	  && node->symbol.next_sharing_asm_name
562 	  && !node->symbol.previous_sharing_asm_name)
563         lto_symtab_merge_cgraph_nodes_1 (node);
564 
565   FOR_EACH_FUNCTION (cnode)
566     {
567       if ((cnode->thunk.thunk_p || cnode->alias)
568 	  && cnode->thunk.alias)
569         cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
570       cnode->symbol.aux = NULL;
571     }
572   FOR_EACH_VARIABLE (vnode)
573     {
574       if (vnode->alias_of)
575         vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
576       vnode->symbol.aux = NULL;
577     }
578 }
579 
580 /* Given the decl DECL, return the prevailing decl with the same name. */
581 
582 tree
lto_symtab_prevailing_decl(tree decl)583 lto_symtab_prevailing_decl (tree decl)
584 {
585   symtab_node ret;
586 
587   /* Builtins and local symbols are their own prevailing decl.  */
588   if (!TREE_PUBLIC (decl) || is_builtin_fn (decl))
589     return decl;
590 
591   /* DECL_ABSTRACTs are their own prevailng decl.  */
592   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_ABSTRACT (decl))
593     return decl;
594 
595   /* Likewise builtins are their own prevailing decl.  This preserves
596      non-builtin vs. builtin uses from compile-time.  */
597   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
598     return decl;
599 
600   /* Ensure DECL_ASSEMBLER_NAME will not set assembler name.  */
601   gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
602 
603   /* Walk through the list of candidates and return the one we merged to.  */
604   ret = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
605   if (!ret)
606     return decl;
607 
608   return ret->symbol.decl;
609 }
610