1*1673e404SJohn Birrell /* 2*1673e404SJohn Birrell * CDDL HEADER START 3*1673e404SJohn Birrell * 4*1673e404SJohn Birrell * The contents of this file are subject to the terms of the 5*1673e404SJohn Birrell * Common Development and Distribution License (the "License"). 6*1673e404SJohn Birrell * You may not use this file except in compliance with the License. 7*1673e404SJohn Birrell * 8*1673e404SJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*1673e404SJohn Birrell * or http://www.opensolaris.org/os/licensing. 10*1673e404SJohn Birrell * See the License for the specific language governing permissions 11*1673e404SJohn Birrell * and limitations under the License. 12*1673e404SJohn Birrell * 13*1673e404SJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each 14*1673e404SJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*1673e404SJohn Birrell * If applicable, add the following below this CDDL HEADER, with the 16*1673e404SJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying 17*1673e404SJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner] 18*1673e404SJohn Birrell * 19*1673e404SJohn Birrell * CDDL HEADER END 20*1673e404SJohn Birrell */ 21*1673e404SJohn Birrell /* 22*1673e404SJohn Birrell * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*1673e404SJohn Birrell * Use is subject to license terms. 24*1673e404SJohn Birrell */ 25*1673e404SJohn Birrell 26*1673e404SJohn Birrell #pragma ident "%Z%%M% %I% %E% SMI" 27*1673e404SJohn Birrell 28*1673e404SJohn Birrell /* 29*1673e404SJohn Birrell * Routines for manipulating tdesc and tdata structures 30*1673e404SJohn Birrell */ 31*1673e404SJohn Birrell 32*1673e404SJohn Birrell #include <stdio.h> 33*1673e404SJohn Birrell #include <stdlib.h> 34*1673e404SJohn Birrell #include <strings.h> 35*1673e404SJohn Birrell #include <pthread.h> 36*1673e404SJohn Birrell 37*1673e404SJohn Birrell #include "ctftools.h" 38*1673e404SJohn Birrell #include "memory.h" 39*1673e404SJohn Birrell #include "traverse.h" 40*1673e404SJohn Birrell 41*1673e404SJohn Birrell /* 42*1673e404SJohn Birrell * The layout hash is used during the equivalency checking. We have a node in 43*1673e404SJohn Birrell * the child graph that may be equivalent to a node in the parent graph. To 44*1673e404SJohn Birrell * find the corresponding node (if any) in the parent, we need a quick way to 45*1673e404SJohn Birrell * get to all nodes in the parent that look like the node in the child. Since a 46*1673e404SJohn Birrell * large number of nodes don't have names, we need to incorporate the layout of 47*1673e404SJohn Birrell * the node into the hash. If we don't, we'll end up with the vast majority of 48*1673e404SJohn Birrell * nodes in bucket zero, with one or two nodes in each of the remaining buckets. 49*1673e404SJohn Birrell * 50*1673e404SJohn Birrell * There are a couple of constraints, both of which concern forward 51*1673e404SJohn Birrell * declarations. Recall that a forward declaration tdesc is equivalent to a 52*1673e404SJohn Birrell * tdesc that actually defines the structure or union. As such, we cannot 53*1673e404SJohn Birrell * incorporate anything into the hash for a named struct or union node that 54*1673e404SJohn Birrell * couldn't be found by looking at the forward, and vice versa. 55*1673e404SJohn Birrell */ 56*1673e404SJohn Birrell int 57*1673e404SJohn Birrell tdesc_layouthash(int nbuckets, void *node) 58*1673e404SJohn Birrell { 59*1673e404SJohn Birrell tdesc_t *tdp = node; 60*1673e404SJohn Birrell char *name = NULL; 61*1673e404SJohn Birrell ulong_t h = 0; 62*1673e404SJohn Birrell 63*1673e404SJohn Birrell if (tdp->t_name) 64*1673e404SJohn Birrell name = tdp->t_name; 65*1673e404SJohn Birrell else { 66*1673e404SJohn Birrell switch (tdp->t_type) { 67*1673e404SJohn Birrell case POINTER: 68*1673e404SJohn Birrell case TYPEDEF: 69*1673e404SJohn Birrell case VOLATILE: 70*1673e404SJohn Birrell case CONST: 71*1673e404SJohn Birrell case RESTRICT: 72*1673e404SJohn Birrell name = tdp->t_tdesc->t_name; 73*1673e404SJohn Birrell break; 74*1673e404SJohn Birrell case FUNCTION: 75*1673e404SJohn Birrell h = tdp->t_fndef->fn_nargs + 76*1673e404SJohn Birrell tdp->t_fndef->fn_vargs; 77*1673e404SJohn Birrell name = tdp->t_fndef->fn_ret->t_name; 78*1673e404SJohn Birrell break; 79*1673e404SJohn Birrell case ARRAY: 80*1673e404SJohn Birrell h = tdp->t_ardef->ad_nelems; 81*1673e404SJohn Birrell name = tdp->t_ardef->ad_contents->t_name; 82*1673e404SJohn Birrell break; 83*1673e404SJohn Birrell case STRUCT: 84*1673e404SJohn Birrell case UNION: 85*1673e404SJohn Birrell /* 86*1673e404SJohn Birrell * Unnamed structures, which cannot have forward 87*1673e404SJohn Birrell * declarations pointing to them. We can therefore 88*1673e404SJohn Birrell * incorporate the name of the first member into 89*1673e404SJohn Birrell * the hash value. 90*1673e404SJohn Birrell */ 91*1673e404SJohn Birrell name = tdp->t_members->ml_name; 92*1673e404SJohn Birrell break; 93*1673e404SJohn Birrell case ENUM: 94*1673e404SJohn Birrell /* Use the first element in the hash value */ 95*1673e404SJohn Birrell name = tdp->t_emem->el_name; 96*1673e404SJohn Birrell break; 97*1673e404SJohn Birrell default: 98*1673e404SJohn Birrell /* 99*1673e404SJohn Birrell * Intrinsics, forwards, and typedefs all have 100*1673e404SJohn Birrell * names. 101*1673e404SJohn Birrell */ 102*1673e404SJohn Birrell warning("Unexpected unnamed %d tdesc (ID %d)\n", 103*1673e404SJohn Birrell tdp->t_type, tdp->t_id); 104*1673e404SJohn Birrell } 105*1673e404SJohn Birrell } 106*1673e404SJohn Birrell 107*1673e404SJohn Birrell if (name) 108*1673e404SJohn Birrell return (hash_name(nbuckets, name)); 109*1673e404SJohn Birrell 110*1673e404SJohn Birrell return (h % nbuckets); 111*1673e404SJohn Birrell } 112*1673e404SJohn Birrell 113*1673e404SJohn Birrell int 114*1673e404SJohn Birrell tdesc_layoutcmp(void *arg1, void *arg2) 115*1673e404SJohn Birrell { 116*1673e404SJohn Birrell tdesc_t *tdp1 = arg1, *tdp2 = arg2; 117*1673e404SJohn Birrell 118*1673e404SJohn Birrell if (tdp1->t_name == NULL) { 119*1673e404SJohn Birrell if (tdp2->t_name == NULL) 120*1673e404SJohn Birrell return (0); 121*1673e404SJohn Birrell else 122*1673e404SJohn Birrell return (-1); 123*1673e404SJohn Birrell } else if (tdp2->t_name == NULL) 124*1673e404SJohn Birrell return (1); 125*1673e404SJohn Birrell else 126*1673e404SJohn Birrell return (strcmp(tdp1->t_name, tdp2->t_name)); 127*1673e404SJohn Birrell } 128*1673e404SJohn Birrell 129*1673e404SJohn Birrell int 130*1673e404SJohn Birrell tdesc_idhash(int nbuckets, void *data) 131*1673e404SJohn Birrell { 132*1673e404SJohn Birrell tdesc_t *tdp = data; 133*1673e404SJohn Birrell 134*1673e404SJohn Birrell return (tdp->t_id % nbuckets); 135*1673e404SJohn Birrell } 136*1673e404SJohn Birrell 137*1673e404SJohn Birrell int 138*1673e404SJohn Birrell tdesc_idcmp(void *arg1, void *arg2) 139*1673e404SJohn Birrell { 140*1673e404SJohn Birrell tdesc_t *tdp1 = arg1, *tdp2 = arg2; 141*1673e404SJohn Birrell 142*1673e404SJohn Birrell if (tdp1->t_id == tdp2->t_id) 143*1673e404SJohn Birrell return (0); 144*1673e404SJohn Birrell else 145*1673e404SJohn Birrell return (tdp1->t_id > tdp2->t_id ? 1 : -1); 146*1673e404SJohn Birrell } 147*1673e404SJohn Birrell 148*1673e404SJohn Birrell int 149*1673e404SJohn Birrell tdesc_namehash(int nbuckets, void *data) 150*1673e404SJohn Birrell { 151*1673e404SJohn Birrell tdesc_t *tdp = data; 152*1673e404SJohn Birrell ulong_t h, g; 153*1673e404SJohn Birrell char *c; 154*1673e404SJohn Birrell 155*1673e404SJohn Birrell if (tdp->t_name == NULL) 156*1673e404SJohn Birrell return (0); 157*1673e404SJohn Birrell 158*1673e404SJohn Birrell for (h = 0, c = tdp->t_name; *c; c++) { 159*1673e404SJohn Birrell h = (h << 4) + *c; 160*1673e404SJohn Birrell if ((g = (h & 0xf0000000)) != 0) { 161*1673e404SJohn Birrell h ^= (g >> 24); 162*1673e404SJohn Birrell h ^= g; 163*1673e404SJohn Birrell } 164*1673e404SJohn Birrell } 165*1673e404SJohn Birrell 166*1673e404SJohn Birrell return (h % nbuckets); 167*1673e404SJohn Birrell } 168*1673e404SJohn Birrell 169*1673e404SJohn Birrell int 170*1673e404SJohn Birrell tdesc_namecmp(void *arg1, void *arg2) 171*1673e404SJohn Birrell { 172*1673e404SJohn Birrell tdesc_t *tdp1 = arg1, *tdp2 = arg2; 173*1673e404SJohn Birrell 174*1673e404SJohn Birrell return (!streq(tdp1->t_name, tdp2->t_name)); 175*1673e404SJohn Birrell } 176*1673e404SJohn Birrell 177*1673e404SJohn Birrell #if defined(sun) 178*1673e404SJohn Birrell /*ARGSUSED1*/ 179*1673e404SJohn Birrell static int 180*1673e404SJohn Birrell tdesc_print(void *data, void *private __unused) 181*1673e404SJohn Birrell { 182*1673e404SJohn Birrell tdesc_t *tdp = data; 183*1673e404SJohn Birrell 184*1673e404SJohn Birrell printf("%7d %s\n", tdp->t_id, tdesc_name(tdp)); 185*1673e404SJohn Birrell 186*1673e404SJohn Birrell return (1); 187*1673e404SJohn Birrell } 188*1673e404SJohn Birrell #endif 189*1673e404SJohn Birrell 190*1673e404SJohn Birrell static void 191*1673e404SJohn Birrell free_intr(tdesc_t *tdp) 192*1673e404SJohn Birrell { 193*1673e404SJohn Birrell free(tdp->t_intr); 194*1673e404SJohn Birrell } 195*1673e404SJohn Birrell 196*1673e404SJohn Birrell static void 197*1673e404SJohn Birrell free_ardef(tdesc_t *tdp) 198*1673e404SJohn Birrell { 199*1673e404SJohn Birrell free(tdp->t_ardef); 200*1673e404SJohn Birrell } 201*1673e404SJohn Birrell 202*1673e404SJohn Birrell static void 203*1673e404SJohn Birrell free_mlist(tdesc_t *tdp) 204*1673e404SJohn Birrell { 205*1673e404SJohn Birrell mlist_t *ml = tdp->t_members; 206*1673e404SJohn Birrell mlist_t *oml; 207*1673e404SJohn Birrell 208*1673e404SJohn Birrell while (ml) { 209*1673e404SJohn Birrell oml = ml; 210*1673e404SJohn Birrell ml = ml->ml_next; 211*1673e404SJohn Birrell 212*1673e404SJohn Birrell if (oml->ml_name) 213*1673e404SJohn Birrell free(oml->ml_name); 214*1673e404SJohn Birrell free(oml); 215*1673e404SJohn Birrell } 216*1673e404SJohn Birrell } 217*1673e404SJohn Birrell 218*1673e404SJohn Birrell static void 219*1673e404SJohn Birrell free_elist(tdesc_t *tdp) 220*1673e404SJohn Birrell { 221*1673e404SJohn Birrell elist_t *el = tdp->t_emem; 222*1673e404SJohn Birrell elist_t *oel; 223*1673e404SJohn Birrell 224*1673e404SJohn Birrell while (el) { 225*1673e404SJohn Birrell oel = el; 226*1673e404SJohn Birrell el = el->el_next; 227*1673e404SJohn Birrell 228*1673e404SJohn Birrell if (oel->el_name) 229*1673e404SJohn Birrell free(oel->el_name); 230*1673e404SJohn Birrell free(oel); 231*1673e404SJohn Birrell } 232*1673e404SJohn Birrell } 233*1673e404SJohn Birrell 234*1673e404SJohn Birrell static void (*free_cbs[])(tdesc_t *) = { 235*1673e404SJohn Birrell NULL, 236*1673e404SJohn Birrell free_intr, 237*1673e404SJohn Birrell NULL, 238*1673e404SJohn Birrell free_ardef, 239*1673e404SJohn Birrell NULL, 240*1673e404SJohn Birrell free_mlist, 241*1673e404SJohn Birrell free_mlist, 242*1673e404SJohn Birrell free_elist, 243*1673e404SJohn Birrell NULL, 244*1673e404SJohn Birrell NULL, 245*1673e404SJohn Birrell NULL, 246*1673e404SJohn Birrell NULL, 247*1673e404SJohn Birrell NULL, 248*1673e404SJohn Birrell NULL 249*1673e404SJohn Birrell }; 250*1673e404SJohn Birrell 251*1673e404SJohn Birrell /*ARGSUSED1*/ 252*1673e404SJohn Birrell static void 253*1673e404SJohn Birrell tdesc_free_cb(void *arg, void *private __unused) 254*1673e404SJohn Birrell { 255*1673e404SJohn Birrell tdesc_t *tdp = arg; 256*1673e404SJohn Birrell if (tdp->t_name) 257*1673e404SJohn Birrell free(tdp->t_name); 258*1673e404SJohn Birrell if (free_cbs[tdp->t_type]) 259*1673e404SJohn Birrell free_cbs[tdp->t_type](tdp); 260*1673e404SJohn Birrell free(tdp); 261*1673e404SJohn Birrell 262*1673e404SJohn Birrell return; 263*1673e404SJohn Birrell } 264*1673e404SJohn Birrell 265*1673e404SJohn Birrell void 266*1673e404SJohn Birrell tdesc_free(tdesc_t *tdp) 267*1673e404SJohn Birrell { 268*1673e404SJohn Birrell tdesc_free_cb(tdp, NULL); 269*1673e404SJohn Birrell } 270*1673e404SJohn Birrell 271*1673e404SJohn Birrell static int 272*1673e404SJohn Birrell tdata_label_cmp(void *arg1, void *arg2) 273*1673e404SJohn Birrell { 274*1673e404SJohn Birrell labelent_t *le1 = arg1; 275*1673e404SJohn Birrell labelent_t *le2 = arg2; 276*1673e404SJohn Birrell return (le1->le_idx - le2->le_idx); 277*1673e404SJohn Birrell } 278*1673e404SJohn Birrell 279*1673e404SJohn Birrell void 280*1673e404SJohn Birrell tdata_label_add(tdata_t *td, const char *label, int idx) 281*1673e404SJohn Birrell { 282*1673e404SJohn Birrell labelent_t *le = xmalloc(sizeof (*le)); 283*1673e404SJohn Birrell 284*1673e404SJohn Birrell le->le_name = xstrdup(label); 285*1673e404SJohn Birrell le->le_idx = (idx == -1 ? td->td_nextid - 1 : idx); 286*1673e404SJohn Birrell 287*1673e404SJohn Birrell slist_add(&td->td_labels, le, tdata_label_cmp); 288*1673e404SJohn Birrell } 289*1673e404SJohn Birrell 290*1673e404SJohn Birrell static int 291*1673e404SJohn Birrell tdata_label_top_cb(void *data, void *arg) 292*1673e404SJohn Birrell { 293*1673e404SJohn Birrell labelent_t *le = data; 294*1673e404SJohn Birrell labelent_t **topp = arg; 295*1673e404SJohn Birrell 296*1673e404SJohn Birrell *topp = le; 297*1673e404SJohn Birrell 298*1673e404SJohn Birrell return (1); 299*1673e404SJohn Birrell } 300*1673e404SJohn Birrell 301*1673e404SJohn Birrell labelent_t * 302*1673e404SJohn Birrell tdata_label_top(tdata_t *td) 303*1673e404SJohn Birrell { 304*1673e404SJohn Birrell labelent_t *top = NULL; 305*1673e404SJohn Birrell 306*1673e404SJohn Birrell (void) list_iter(td->td_labels, tdata_label_top_cb, &top); 307*1673e404SJohn Birrell 308*1673e404SJohn Birrell return (top); 309*1673e404SJohn Birrell } 310*1673e404SJohn Birrell 311*1673e404SJohn Birrell static int 312*1673e404SJohn Birrell tdata_label_find_cb(void *arg1, void *arg2) 313*1673e404SJohn Birrell { 314*1673e404SJohn Birrell labelent_t *le = arg1; 315*1673e404SJohn Birrell labelent_t *tmpl = arg2; 316*1673e404SJohn Birrell return (streq(le->le_name, tmpl->le_name)); 317*1673e404SJohn Birrell } 318*1673e404SJohn Birrell 319*1673e404SJohn Birrell int 320*1673e404SJohn Birrell tdata_label_find(tdata_t *td, char *label) 321*1673e404SJohn Birrell { 322*1673e404SJohn Birrell labelent_t let; 323*1673e404SJohn Birrell labelent_t *ret; 324*1673e404SJohn Birrell 325*1673e404SJohn Birrell if (streq(label, "BASE")) { 326*1673e404SJohn Birrell ret = (labelent_t *)list_first(td->td_labels); 327*1673e404SJohn Birrell return (ret ? ret->le_idx : -1); 328*1673e404SJohn Birrell } 329*1673e404SJohn Birrell 330*1673e404SJohn Birrell let.le_name = label; 331*1673e404SJohn Birrell 332*1673e404SJohn Birrell if (!(ret = (labelent_t *)list_find(td->td_labels, &let, 333*1673e404SJohn Birrell tdata_label_find_cb))) 334*1673e404SJohn Birrell return (-1); 335*1673e404SJohn Birrell 336*1673e404SJohn Birrell return (ret->le_idx); 337*1673e404SJohn Birrell } 338*1673e404SJohn Birrell 339*1673e404SJohn Birrell static int 340*1673e404SJohn Birrell tdata_label_newmax_cb(void *data, void *arg) 341*1673e404SJohn Birrell { 342*1673e404SJohn Birrell labelent_t *le = data; 343*1673e404SJohn Birrell int *newmaxp = arg; 344*1673e404SJohn Birrell 345*1673e404SJohn Birrell if (le->le_idx > *newmaxp) { 346*1673e404SJohn Birrell le->le_idx = *newmaxp; 347*1673e404SJohn Birrell return (1); 348*1673e404SJohn Birrell } 349*1673e404SJohn Birrell 350*1673e404SJohn Birrell return (0); 351*1673e404SJohn Birrell } 352*1673e404SJohn Birrell 353*1673e404SJohn Birrell void 354*1673e404SJohn Birrell tdata_label_newmax(tdata_t *td, int newmax) 355*1673e404SJohn Birrell { 356*1673e404SJohn Birrell (void) list_iter(td->td_labels, tdata_label_newmax_cb, &newmax); 357*1673e404SJohn Birrell } 358*1673e404SJohn Birrell 359*1673e404SJohn Birrell /*ARGSUSED1*/ 360*1673e404SJohn Birrell static void 361*1673e404SJohn Birrell tdata_label_free_cb(void *arg, void *private __unused) 362*1673e404SJohn Birrell { 363*1673e404SJohn Birrell labelent_t *le = arg; 364*1673e404SJohn Birrell if (le->le_name) 365*1673e404SJohn Birrell free(le->le_name); 366*1673e404SJohn Birrell free(le); 367*1673e404SJohn Birrell } 368*1673e404SJohn Birrell 369*1673e404SJohn Birrell void 370*1673e404SJohn Birrell tdata_label_free(tdata_t *td) 371*1673e404SJohn Birrell { 372*1673e404SJohn Birrell list_free(td->td_labels, tdata_label_free_cb, NULL); 373*1673e404SJohn Birrell td->td_labels = NULL; 374*1673e404SJohn Birrell } 375*1673e404SJohn Birrell 376*1673e404SJohn Birrell tdata_t * 377*1673e404SJohn Birrell tdata_new(void) 378*1673e404SJohn Birrell { 379*1673e404SJohn Birrell tdata_t *new = xcalloc(sizeof (tdata_t)); 380*1673e404SJohn Birrell 381*1673e404SJohn Birrell new->td_layouthash = hash_new(TDATA_LAYOUT_HASH_SIZE, tdesc_layouthash, 382*1673e404SJohn Birrell tdesc_layoutcmp); 383*1673e404SJohn Birrell new->td_idhash = hash_new(TDATA_ID_HASH_SIZE, tdesc_idhash, 384*1673e404SJohn Birrell tdesc_idcmp); 385*1673e404SJohn Birrell /* 386*1673e404SJohn Birrell * This is also traversed as a list, but amortized O(1) 387*1673e404SJohn Birrell * lookup massively impacts part of the merge phase, so 388*1673e404SJohn Birrell * we store the iidescs as a hash. 389*1673e404SJohn Birrell */ 390*1673e404SJohn Birrell new->td_iihash = hash_new(IIDESC_HASH_SIZE, iidesc_hash, NULL); 391*1673e404SJohn Birrell new->td_nextid = 1; 392*1673e404SJohn Birrell new->td_curvgen = 1; 393*1673e404SJohn Birrell 394*1673e404SJohn Birrell pthread_mutex_init(&new->td_mergelock, NULL); 395*1673e404SJohn Birrell 396*1673e404SJohn Birrell return (new); 397*1673e404SJohn Birrell } 398*1673e404SJohn Birrell 399*1673e404SJohn Birrell void 400*1673e404SJohn Birrell tdata_free(tdata_t *td) 401*1673e404SJohn Birrell { 402*1673e404SJohn Birrell hash_free(td->td_iihash, iidesc_free, NULL); 403*1673e404SJohn Birrell hash_free(td->td_layouthash, tdesc_free_cb, NULL); 404*1673e404SJohn Birrell hash_free(td->td_idhash, NULL, NULL); 405*1673e404SJohn Birrell list_free(td->td_fwdlist, NULL, NULL); 406*1673e404SJohn Birrell 407*1673e404SJohn Birrell tdata_label_free(td); 408*1673e404SJohn Birrell 409*1673e404SJohn Birrell free(td->td_parlabel); 410*1673e404SJohn Birrell free(td->td_parname); 411*1673e404SJohn Birrell 412*1673e404SJohn Birrell pthread_mutex_destroy(&td->td_mergelock); 413*1673e404SJohn Birrell 414*1673e404SJohn Birrell free(td); 415*1673e404SJohn Birrell } 416*1673e404SJohn Birrell 417*1673e404SJohn Birrell /*ARGSUSED1*/ 418*1673e404SJohn Birrell static int 419*1673e404SJohn Birrell build_hashes(tdesc_t *ctdp, tdesc_t **ctdpp __unused, void *private) 420*1673e404SJohn Birrell { 421*1673e404SJohn Birrell tdata_t *td = private; 422*1673e404SJohn Birrell 423*1673e404SJohn Birrell hash_add(td->td_idhash, ctdp); 424*1673e404SJohn Birrell hash_add(td->td_layouthash, ctdp); 425*1673e404SJohn Birrell 426*1673e404SJohn Birrell return (1); 427*1673e404SJohn Birrell } 428*1673e404SJohn Birrell 429*1673e404SJohn Birrell static tdtrav_cb_f build_hashes_cbs[] = { 430*1673e404SJohn Birrell NULL, 431*1673e404SJohn Birrell build_hashes, /* intrinsic */ 432*1673e404SJohn Birrell build_hashes, /* pointer */ 433*1673e404SJohn Birrell build_hashes, /* array */ 434*1673e404SJohn Birrell build_hashes, /* function */ 435*1673e404SJohn Birrell build_hashes, /* struct */ 436*1673e404SJohn Birrell build_hashes, /* union */ 437*1673e404SJohn Birrell build_hashes, /* enum */ 438*1673e404SJohn Birrell build_hashes, /* forward */ 439*1673e404SJohn Birrell build_hashes, /* typedef */ 440*1673e404SJohn Birrell tdtrav_assert, /* typedef_unres */ 441*1673e404SJohn Birrell build_hashes, /* volatile */ 442*1673e404SJohn Birrell build_hashes, /* const */ 443*1673e404SJohn Birrell build_hashes /* restrict */ 444*1673e404SJohn Birrell }; 445*1673e404SJohn Birrell 446*1673e404SJohn Birrell static void 447*1673e404SJohn Birrell tdata_build_hashes_common(tdata_t *td, hash_t *hash) 448*1673e404SJohn Birrell { 449*1673e404SJohn Birrell (void) iitraverse_hash(hash, &td->td_curvgen, NULL, NULL, 450*1673e404SJohn Birrell build_hashes_cbs, td); 451*1673e404SJohn Birrell } 452*1673e404SJohn Birrell 453*1673e404SJohn Birrell void 454*1673e404SJohn Birrell tdata_build_hashes(tdata_t *td) 455*1673e404SJohn Birrell { 456*1673e404SJohn Birrell tdata_build_hashes_common(td, td->td_iihash); 457*1673e404SJohn Birrell } 458*1673e404SJohn Birrell 459*1673e404SJohn Birrell /* Merge td2 into td1. td2 is destroyed by the merge */ 460*1673e404SJohn Birrell void 461*1673e404SJohn Birrell tdata_merge(tdata_t *td1, tdata_t *td2) 462*1673e404SJohn Birrell { 463*1673e404SJohn Birrell td1->td_curemark = MAX(td1->td_curemark, td2->td_curemark); 464*1673e404SJohn Birrell td1->td_curvgen = MAX(td1->td_curvgen, td2->td_curvgen); 465*1673e404SJohn Birrell td1->td_nextid = MAX(td1->td_nextid, td2->td_nextid); 466*1673e404SJohn Birrell 467*1673e404SJohn Birrell hash_merge(td1->td_iihash, td2->td_iihash); 468*1673e404SJohn Birrell 469*1673e404SJohn Birrell /* Add td2's type tree to the hashes */ 470*1673e404SJohn Birrell tdata_build_hashes_common(td1, td2->td_iihash); 471*1673e404SJohn Birrell 472*1673e404SJohn Birrell list_concat(&td1->td_fwdlist, td2->td_fwdlist); 473*1673e404SJohn Birrell td2->td_fwdlist = NULL; 474*1673e404SJohn Birrell 475*1673e404SJohn Birrell slist_merge(&td1->td_labels, td2->td_labels, 476*1673e404SJohn Birrell tdata_label_cmp); 477*1673e404SJohn Birrell td2->td_labels = NULL; 478*1673e404SJohn Birrell 479*1673e404SJohn Birrell /* free the td2 hashes (data is now part of td1) */ 480*1673e404SJohn Birrell 481*1673e404SJohn Birrell hash_free(td2->td_layouthash, NULL, NULL); 482*1673e404SJohn Birrell td2->td_layouthash = NULL; 483*1673e404SJohn Birrell 484*1673e404SJohn Birrell hash_free(td2->td_iihash, NULL, NULL); 485*1673e404SJohn Birrell td2->td_iihash = NULL; 486*1673e404SJohn Birrell 487*1673e404SJohn Birrell tdata_free(td2); 488*1673e404SJohn Birrell } 489