/* * Declare a namespace. */ void dclns(NODE *attr, char *n) { struct symtab *sp; struct attr *ap = gcc_attr_parse(attr); if (cppdebug)printf("declaring namespace %s\n", n); n = addname(n); sp = sfind(n, nscur->sup); while (sp != NULL) { if (sp->sname == n && sp->sclass == NSPACE) break; sp = sfind(n, sp->snext); } if (sp == NULL) { /* New namespace */ sp = getsymtab(n, 0); sp->sclass = NSPACE; INSSYM(sp); } nscur = sp; if (cppdebug)printf("declaring namespace2 %s\n", nscur->sname); sp->sap = attr_add(sp->sap, ap); /* XXX check attributes */ }
/* * Set up string and symbol tables from a.out. * and optionally the text space. * On return symbol table is sorted by value. * * Returns 0 on success, -1 on failure. */ int aout_getnfile(const char *filename, char ***defaultEs) { FILE *nfile; int valcmp(); nfile = fopen( filename ,"r"); if (nfile == NULL) err( 1 , "%s", filename ); fread(&xbuf, 1, sizeof(xbuf), nfile); if (N_BADMAG(xbuf)) { fclose(nfile); return -1; } getstrtab(nfile, filename); getsymtab(nfile, filename); gettextspace( nfile ); fclose(nfile); # ifdef DEBUG if ( debug & AOUTDEBUG ) { register int j; for (j = 0; j < nname; j++){ printf("[getnfile] 0X%08lx\t%s\n", nl[j].value, nl[j].name); } } # endif /* DEBUG */ *defaultEs = excludes; return 0; }
/* * Declare a struct (class) based on its name n. * Assumed that nmcur is correctly pointing to either: * - nothing (class at level 0) * - current namespace * - parent class */ struct symtab * cxxdclstr(char *n) { struct symtab *sp; sp = sfind(n, nscur->sup); while (sp && !CLORNS(sp)) sp = sfind(n, sp->snext); if (sp == 0) sp = getsymtab(n, STAGNAME); // else // uerror("class/namespace redefined"); // INSSYM(sp); // nscur = sp; if (cppdebug)printf("declaring2 struct %s %p nscur %s\n", n, sp, nscur->sname); return sp; }
/* * Generate a call tree to function named n. */ static NODE * callftn(char *n, ...) { struct symtab *sp = getsymtab(n, 0); NODE *p, *a, *b; va_list ap; sp->stype = (FTN|VOID) | (PTR << TSHIFT); va_start(ap, n); a = va_arg(ap, NODE *); if (a != NULL) { do { b = va_arg(ap, NODE *); if (b != NULL) a = buildtree(CM, a, b); } while (b != NULL); } p = doacall(sp, nametree(sp), a, 0); va_end(ap); return p; }
/* * Search for correct matching function in a struct depending on * argument list a. Return a call node for this function. * Do not touch neither f nor a. * return a name tree suitable for a function call. * We know here that f is a struct reference. */ NODE * cxxmatchftn(NODE *f, NODE *a) { struct attr *ap; struct symtab *sp; char *n = (char *)f->n_right->n_sp; f = f->n_left; if ((ap = attr_find(f->n_ap, ATTR_STRUCT)) == NULL) { uerror("undefined class"); sp = getsymtab(n, 0); } else sp = ap->amlist; sp = sfind(n, sp); while (sp != NULL) { if (ISFTN(sp->stype) && cxxptreecmp(sp, a) == 0) break; sp = sfind(n, sp->snext); } if (sp == NULL) uerror("undefined class member"); return nametree(sp); }
/* * Search for (and declare) a function. */ struct symtab * cxxftnfind(NODE *p, int flags) { struct symtab *sp, *ns; char *s; if (p->n_op == NAME) { s = (char *)p->n_sp; /* Search for equally named functions */ sp = sfind(s, nscur->sup); while (sp != NULL) { if (cxxpcmp(sp, p)) { if (sp->sclass != NSPACE || sp->sclass == EXTDEF) { uerror("%s redefined", s); return sp; } else break; } sp = sfind(s, sp->snext); } if (sp == NULL) { sp = getsymtab(s, SNORMAL); sp->stype = p->n_type; sp->squal = p->n_qual; sp->sdf = p->n_df; sp->sap = p->n_ap; INSSYM(sp); if (nscur->sclass != NSPACE && nscur != &spole0) uerror("inside struct"); } sp->sclass = EXTDEF; if (sp->soname == 0) sp->soname = decoratename(sp, NM_NORMAL); } else { /* * declared outside class, tree-style reference * Must have been defined already * This will be an external declaration (not spooled). */ s = SPNAME(p); if ((ns = pfind(p->n_left, spole->sup)) == NULL) { uerror("undeclared class in chain"); goto undecl; } /* Search for an EXTERN or EXTDEF declaration within */ /* EXTDEF causes redeclaration. */ sp = sfind(s, ns); while (sp != NULL) { if (sp->sclass == EXTERN || sp->sclass == EXTDEF) { if (cxxpcmp(sp, p->n_right)) { if (sp->sclass == EXTDEF) uerror("%s redefined", s); break; } } sp = sfind(s, sp->snext); } if (sp == NULL) { uerror("%s undeclared", s); goto undecl; } sp->sclass = EXTDEF; } return sp; undecl: return getsymtab(s, SNORMAL); }
/* * Do a name lookup. p can be either just a NAME or NMLIST. * The first symbol instance on its level is returned, which may or * may not be correct. * If no symbol is found, return a new symtab entry. * p should be a NAME after this with n_sp filled in accordingly. * It's the responsibility of the declaration routine to add it to * the symbol table. * nfree() will be called on p after this function. */ struct symtab * cxxlookup(NODE *p, int flags) { struct symtab *sp, *ns; int ftyp = flags & SMASK; NODE *q; char *n, *s; #define SPNAME(p) ((char *)(p->n_op == NAME ? p->n_sp : p->n_right->n_sp)) if (cppdebug){ printf("cxxlookup %s\n", SPNAME(p)); symtree(); } q = p; if (p->n_op == NAME) { s = (char *)p->n_sp; if (blevel) { sp = lookup(s, SNOCREAT); /* check if auto var */ if (sp == NULL) { /* check if in classes */ for (ns = nscur; ns != spole; ns = ns->sdown) if ((sp = sfind(s, ns->sup))) break; if (sp == NULL) sp = sfind(s, spole->sup); } if (sp == NULL) sp = lookup(s, 0); /* fallback */ } else { ns = nscur; sp = sfind(s, ns); while (sp != NULL) { if ((sp->sflags & SMASK) == ftyp) break; sp = sfind(s, sp->snext); } if (sp == NULL) { sp = getsymtab(s, ftyp); if ((flags & SNOCREAT) == 0) { if (cppdebug)printf("cxxlookup: adding %s %s %s at %s\n", symclass[ftyp], s, sp->soname, nscur ? nscur->sname : "base"); INSSYM(sp); cxxsetname(sp); } } } } else { /* Search through namespaces/classes for it */ n = SPNAME(p); ns = pfind(p->n_left, spole->sup); if (ns == NULL) { uerror("undeclared class in chain"); return getsymtab(n, ftyp); } if ((sp = sfind(n, ns)) == NULL) { sp = getsymtab(n, ftyp); if ((flags & SNOCREAT) == 0) { sp->snext = ns->snext; ns->snext = sp; } } } /* make top node a NAME */ if (q->n_op != NAME) { tfree(q->n_left); p = q->n_right; *q = *q->n_right; nfree(p); } q->n_sp = sp; return sp; }