void init_dictionary(scope v){ unsigned int i; keyword_T = newtype(NULL,NULL,TRUE); interntype(keyword_T); type__T = newtype(NULL,NULL,TRUE); interntype(type__T); #define f(name,var) { \ node sym = newsymbol(var##_S = UniqueString(name), \ keyword_T,v, \ intern_F|keyword_F|defined_F); \ var##_K = sym; \ } #define g(var) f(#var,var) #include "keywords.h" keyword_T->body.type.name = keyword__K; type__K->body.symbol.value = type__T; type__T->body.type.name = type__K; init_chk(); int_T = basictype(int_K); one__K->body.symbol.type = int_T; zero__K->body.symbol.type = int_T; one__K->body.symbol.Cname = "1"; zero__K->body.symbol.Cname = "0"; char_T = basictype(char_K); double_T = basictype(double_K); package_T = basictype(package_K); bool_T = basictype(bool_K); bool_T->body.type.Cname = "char"; true_K->body.symbol.type = bool_T; true_K->body.symbol.Cname = "1"; false_K->body.symbol.type = bool_T; false_K->body.symbol.Cname = "0"; void_T = basictype(void_K); returns_T = basictype(returns_K); exits_T = basictype(exits_K); _returnedThing_K->body.symbol.type = returns_T; _returnedThing_K->body.symbol.flags &= ~keyword_F; bad_or_undefined_T = basictype(undefined__K); deferred__T = basictype(deferred__K); /* the type of a symbol whose type is not known yet */ undefine(deferred__K); symbol_T = basictype(symbol__K); null_T = basictype(null_K); null_T->body.type.Cname = "void *"; exits_T->body.type.Cname = "void"; bad__K->body.symbol.type = bad_or_undefined_T; double_T->body.type.flags |= arithmetic_type_F; int_T->body.type.flags |= arithmetic_type_F; char_T->body.type.flags |= arithmetic_type_F; int_T->body.type.flags |= integer_type_F; char_T->body.type.flags |= integer_type_F; for (i=0; i<numberof(Csymbols); i++) uniquify(Csymbols[i]); for (i=0; i<numberof(CXXkeywords); i++) uniquifyCXX(CXXkeywords[i]); }
node chktype2(node e,scope v){ node f, ftype; f = chk(e,v); if (f == bad__K) return bad_or_undefined_T; if (equal(f,type__K)) return type__T; ftype = type(f); if (ftype != type__T) { node sym; if (ftype != deferred__T) { errorpos(e,"not valid type"); return NULL; } sym = unpos(f); assert(issym(sym)); if (sym->body.symbol.value == NULL) { node t = newtype(f,NULL,FALSE); t->body.type.flags = deferred_F; assert(issym(sym)); sym->body.symbol.value = t; t->body.type.name = sym; } return sym->body.symbol.value; } return f; /* was totype(f) */ }
void initmv3tp() { ULmultvec3 = newtype( "Multvec3", sizeof( multvec3typ ), 0, (voidfun)prtmultvec3, 0, 0 ); addcoerce( ULmultvec3, ULreal, (implinst)realtomv3, 0 ); addcoerce( ULmultvec3, ULint, (implinst)inttomv3, 0 ); addcoerce( ULmultvec3, ULreal3, (implinst)real3tomv3, 0 ); addcoerce( ULmultvec3, ULquat, (implinst)quattomv3, 0 ); }
node basictype(node n){ node t; assert(n->tag == symbol_tag); n->body.symbol.type = type__T; t = newtype(NULL,n,TRUE); interntype(t); n->body.symbol.value = t; assert(n->body.symbol.name->tag == unique_string_tag); return t; }
static CTy * declaratortail(CTy *basety) { SrcPos *p; CTy *t, *newt; Const *c; t = basety; for(;;) { c = 0; switch (tok->k) { case '[': newt = newtype(CARR); newt->Arr.subty = t; newt->Arr.dim = -1; next(); if(tok->k != ']') { p = &tok->pos; c = constexpr(); if(c->p) errorposf(p, "pointer derived constant in array size"); newt->Arr.dim = c->v; newt->size = newt->Arr.dim * newt->Arr.subty->size; } newt->align = newt->Arr.subty->align; expect(']'); t = newt; break; case '(': newt = newtype(CFUNC); newt->Func.rtype = basety; newt->Func.params = vec(); next(); params(newt); if(tok->k != ')') errorposf(&tok->pos, "expected valid parameter or )"); next(); t = newt; break; default: return t; } }
static CTy * mkptr(CTy *t) { CTy *p; p = newtype(CPTR); p->Ptr.subty = t; p->size = 8; p->align = 8; return p; }
void initvectp() { ULint2 = newtype( "Int2", sizeof( int2typ ), 0, (voidfun)prtint2, 0, 0 ); ULint3 = newtype( "Int3", sizeof( int3typ ), 0, (voidfun)prtint3, 0, 0 ); ULreal2 = newtype( "Real2", sizeof( real2typ ), 0, (voidfun)prtreal2, 0, 0 ); ULreal3 = newtype( "Real3", sizeof( real3typ ), 0, (voidfun)prtreal3, 0, 0 ); ULreal4 = newtype( "Real4", sizeof( real4typ ), 0, (voidfun)prtreal4, 0, 0 ); ULintl2 = newtype( "Intl2", sizeof( intl2typ ), 0, (voidfun)prtintl2, 0, 0 ); ULintl3 = newtype( "Intl3", sizeof( intl3typ ), 0, (voidfun)prtintl3, 0, 0 ); ULreall2 = newtype( "Reall2", sizeof( reall2typ ), 0, (voidfun)prtreall2, 0, 0 ); ULreall3 = newtype( "Reall3", sizeof( reall3typ ), 0, (voidfun)prtreall3, 0, 0 ); addcoerce( ULreal2, ULint2, (implinst)inttoreal2, 0 ); addcoerce( ULreal3, ULint3, (implinst)inttoreal3, 0 ); addcoerce( ULint2, ULreal2, (implinst)realtoint2, 1 ); addcoerce( ULint3, ULreal3, (implinst)realtoint3, 1 ); addcoerce( ULcmplx, ULreal2, (implinst)real2tocmplx, 1 ); addcoerce( ULreal2, ULcmplx, (implinst)cmplxtoreal2, 1 ); addcoerce( ULreal3, ULreal2, (implinst)real2toreal3, 1 ); addcoerce( ULquat, ULreal3, (implinst)real3toquat, 1 ); addcoerce( ULquat, ULreal4, (implinst)real4toquat, 1 ); addcoerce( ULreal4, ULquat, (implinst)quattoreal4, 1 ); }
node ExpandType(node t, node *f) { /* t should be a type expression that might need expanding. Its expanded form gets returned, and also put on the top of the list f unless it's already a type or basic type */ switch(t->tag) { case position_tag: return ExpandType(t->body.position.contents,f); case type_tag: return t; case symbol_tag: { if (t->body.symbol.type == type__T) { assert(istype(t->body.symbol.value)); return t->body.symbol.value; } if (t == bad__K) return bad_or_undefined_T; assert(FALSE); return NULL; } case cons_tag: { node fun = CAR(t); if (ispos(fun)) fun = fun->body.position.contents; t = CDR(t); if (fun == or_K) { /* here we should sort! */ /* we should also merge sub-or's in, and eliminate duplicates */ /* we really only handle (or null (object)) now! */ node newN = NULL; node mems = NULL; while (t != NULL) { node u = ExpandType(CAR(t),f); push(mems,u); t = CDR(t); } apply(reverse,mems); newN = newtype(cons(fun,mems),NULL,FALSE); push(*f,newN); return newN; } else if (fun == object__K || fun == tagged_object_K /* ? */ ) { node newN = NULL; while (t != NULL) { node name = CAAR(t); node u = CADAR(t); push(newN, list(2, unpos(name), ExpandType(u,f))); t = CDR(t); } apply(reverse,newN); newN = newtype(cons(fun,newN),NULL,FALSE); push(*f,newN); return newN; } else if (fun == array_K || fun == tarray_K) { node newN; newN = cons(fun,cons(ExpandType(car(t),f),cdr(t))); newN = newtype(newN,NULL,FALSE); *f = cons(newN,*f); return newN; } else if (fun == function_S) { node argtypes = car(t); node rettype = cadr(t); node newargtypes = NULL; node newN; while (argtypes != NULL) { newargtypes = cons( ExpandType(car(argtypes),f), newargtypes); argtypes = cdr(argtypes); } newargtypes = reverse(newargtypes); rettype = ExpandType(rettype,f); newN = list(3,fun,newargtypes,rettype); newN = newtype(newN,NULL,FALSE); *f = cons(newN,*f); return newN; } else assert(FALSE); return NULL; } default: assert(FALSE); return NULL; } }
// Convert one type to another. // // Returns the node representing the conversion, which could be the same // node passed in if no conversion was needed. Returns NULL if conversion can't be done. TIntermTyped* ir_add_conversion(TOperator op, const TType& type, TIntermTyped* node, TInfoSink& infoSink) { if (!node) return 0; // // Does the base type allow operation? // switch (node->getBasicType()) { case EbtVoid: case EbtSampler1D: case EbtSampler2D: case EbtSampler3D: case EbtSamplerCube: case EbtSampler1DShadow: case EbtSampler2DShadow: case EbtSamplerRect: // ARB_texture_rectangle case EbtSamplerRectShadow: // ARB_texture_rectangle return 0; default: break; } // // Otherwise, if types are identical, no problem // if (type == node->getType()) return node; // if basic types are identical, promotions will handle everything if (type.getBasicType() == node->getTypePointer()->getBasicType()) return node; // // If one's a structure, then no conversions. // if (type.getStruct() || node->getType().getStruct()) return 0; // // If one's an array, then no conversions. // if (type.isArray() || node->getType().isArray()) return 0; TBasicType promoteTo; switch (op) { // // Explicit conversions // case EOpConstructBool: promoteTo = EbtBool; break; case EOpConstructFloat: promoteTo = EbtFloat; break; case EOpConstructInt: promoteTo = EbtInt; break; default: // // implicit conversions are required for hlsl // promoteTo = type.getBasicType(); } if (node->getAsConstant()) { return ir_promote_constant(promoteTo, node->getAsConstant(), infoSink); } else { // // Add a new newNode for the conversion. // TIntermUnary* newNode = 0; TOperator newOp = EOpNull; switch (promoteTo) { case EbtFloat: switch (node->getBasicType()) { case EbtInt: newOp = EOpConvIntToFloat; break; case EbtBool: newOp = EOpConvBoolToFloat; break; default: infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); return 0; } break; case EbtBool: switch (node->getBasicType()) { case EbtInt: newOp = EOpConvIntToBool; break; case EbtFloat: newOp = EOpConvFloatToBool; break; default: infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); return 0; } break; case EbtInt: switch (node->getBasicType()) { case EbtBool: newOp = EOpConvBoolToInt; break; case EbtFloat: newOp = EOpConvFloatToInt; break; default: infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); return 0; } break; default: infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine()); return 0; } TType newtype(promoteTo, node->getPrecision(), EvqTemporary, node->getColsCount(), node->getRowsCount(), node->isMatrix(), node->isArray()); newNode = new TIntermUnary(newOp, newtype); newNode->setLine(node->getLine()); newNode->setOperand(node); return newNode; } }
void initsolidtp() { ULsol = newtype( "Solid", sizeof( solidtyp ), (voidfun)soldel, (voidfun)prtsol, (voidenvfun)tchsol, (copyfun)solcpy ); }
/* ============ idProgram::AllocDef ============ */ idVarDef *idProgram::AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant ) { idVarDef *def; idStr element; idVarDef *def_x; idVarDef *def_y; idVarDef *def_z; // allocate a new def def = new idVarDef( type ); def->scope = scope; def->numUsers = 1; def->num = varDefs.Append( def ); // add the def to the list with defs with this name and set the name pointer AddDefToNameList( def, name ); if( ( type->Type() == ev_vector ) || ( ( type->Type() == ev_field ) && ( type->FieldType()->Type() == ev_vector ) ) ) { // // vector // if( !strcmp( name, RESULT_STRING ) ) { // <RESULT> vector defs don't need the _x, _y and _z components assert( scope->Type() == ev_function ); def->value.stackOffset = scope->value.functionPtr->locals; def->initialized = idVarDef::stackVariable; scope->value.functionPtr->locals += type->Size(); } else if( scope->TypeDef()->Inherits( &type_object ) ) { idTypeDef newtype( ev_field, NULL, "float field", 0, &type_float ); idTypeDef *type = GetType( newtype, true ); // set the value to the variable's position in the object def->value.ptrOffset = scope->TypeDef()->Size(); // make automatic defs for the vectors elements // origin can be accessed as origin_x, origin_y, and origin_z sprintf( element, "%s_x", def->Name() ); def_x = AllocDef( type, element, scope, constant ); sprintf( element, "%s_y", def->Name() ); def_y = AllocDef( type, element, scope, constant ); def_y->value.ptrOffset = def_x->value.ptrOffset + type_float.Size(); sprintf( element, "%s_z", def->Name() ); def_z = AllocDef( type, element, scope, constant ); def_z->value.ptrOffset = def_y->value.ptrOffset + type_float.Size(); } else { // make automatic defs for the vectors elements // origin can be accessed as origin_x, origin_y, and origin_z sprintf( element, "%s_x", def->Name() ); def_x = AllocDef( &type_float, element, scope, constant ); sprintf( element, "%s_y", def->Name() ); def_y = AllocDef( &type_float, element, scope, constant ); sprintf( element, "%s_z", def->Name() ); def_z = AllocDef( &type_float, element, scope, constant ); // point the vector def to the x coordinate def->value = def_x->value; def->initialized = def_x->initialized; } } else if( scope->TypeDef()->Inherits( &type_object ) ) { // // object variable // // set the value to the variable's position in the object def->value.ptrOffset = scope->TypeDef()->Size(); } else if( scope->Type() == ev_function ) { // // stack variable // // since we don't know how many local variables there are, // we have to have them go backwards on the stack def->value.stackOffset = scope->value.functionPtr->locals; def->initialized = idVarDef::stackVariable; if( type->Inherits( &type_object ) ) { // objects only have their entity number on the stack, not the entire object scope->value.functionPtr->locals += type_object.Size(); } else { scope->value.functionPtr->locals += type->Size(); } } else { // // global variable // def->value.bytePtr = &variables[ numVariables ]; numVariables += def->TypeDef()->Size(); if( numVariables > sizeof( variables ) ) { throw idCompileError( va( "Exceeded global memory size (%d bytes)", sizeof( variables ) ) ); } memset( def->value.bytePtr, 0, def->TypeDef()->Size() ); } return def; }
//----------------------------------------------------------------------------- // Functions required by the tree traversal mechanism ClasshierarchyInhAttr ClasshierarchyTraversal::evaluateInheritedAttribute ( SgNode* astNode, ClasshierarchyInhAttr inheritedAttribute ) { GlobalDatabaseConnection *gdb; // db connection //long funcId; // id of a function declaration Classhierarchy *classhier = getClasshierarchy(); gdb = getDB(); switch(astNode->variantT()) { case V_SgMemberFunctionDeclaration: { SgMemberFunctionDeclaration *funcDec = isSgMemberFunctionDeclaration( astNode ); //funcDec = funcDef->get_declaration(); //if(isSgMemberFunctionDeclaration(funcDec)) { // add to class hierarchy if member function definition //if(isSgMemberFunctionDeclaration()) { //cerr << " adding CHvinf for MembFunc " << endl; SgClassDefinition *classDef = isSgClassDefinition( funcDec->get_scope() ); //assert(classDef); if(classDef) { string classname = classDef->get_qualified_name().str(); // get the classhier. vertex Classhierarchy::dbgVertex chVert = 0; //?? init necessary bool foundClass = false; Classhierarchy::dbgVertexIterator chvi,chvend; boost::tie(chvi,chvend) = boost::vertices( *getClasshierarchy() ); for(; chvi!=chvend; chvi++) { if( boost::get( vertex_dbg_data, *getClasshierarchy() , *chvi).get_typeName() == classname ) { chVert = *chvi; foundClass = true; } } if(foundClass) { property_map< Classhierarchy::dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *getClasshierarchy() ); chMap[ chVert ].defined.insert( funcDec ); //get type? //cerr << " added! "; // debug } } //} cerr << " found V_SgMemberFunctionDeclaration done for " <<funcDec->get_mangled_name().str()<< " " << endl; // debug } break; case V_SgClassDefinition: { cerr << " found V_SgClassDef of "; // debug SgClassDefinition *classDef = isSgClassDefinition( astNode ); assert( classDef ); SgName classname = classDef->get_qualified_name(); // make db entry long typeId = UNKNOWNID; typesTableAccess types( gdb ); typesRowdata newtype( typeId, getProjectId(), classname.str() ); typeId = types.retrieveCreateByColumn( &newtype, "typeName", newtype.get_typeName(), newtype.get_projectId() ); cerr << classname.str()<< ", id:" << newtype.get_id() << endl; // debug //classhier->addNode( newtype, newtype.get_typeName() ); //classhier->insertWithName( newtype, newtype.get_typeName() ); classhier->insertVertex( newtype, newtype.get_typeName() ); SgBaseClassList inherits = classDef->get_inheritances(); for( SgBaseClassList::iterator i=inherits.begin(); i!=inherits.end(); i++) { SgClassDeclaration *parentDecl = (*i).get_base_class(); cerr << " found inheritance from " ; // debug assert( parentDecl ); // add new edge typesRowdata partype( UNKNOWNID, getProjectId(), parentDecl->get_name().str() ); // MANGLE long parentId = types.retrieveCreateByColumn( &partype, "typeName", partype.get_typeName(), partype.get_projectId() ); cerr << parentDecl->get_name().str() << ", id: " << parentId << endl; // add to class hierarchy graph, allow only one edge per inheritance //A classhier->addNode( partype, partype.get_typeName() ); //A classhier->addEdge( newtype, partype, false ); classhier->insertEdge( newtype, partype ); } } break; } // switch node type // Note that we have to use a particular constructor (to pass on context information about source code position). // This allows the Rewrite mechanism to position new source code relative to the current position using a simple interface. ClasshierarchyInhAttr returnAttribute(inheritedAttribute,astNode); // FIXME why not return inheritedAttribute??? return returnAttribute; }
int stabs2acid(Stab *stabs, Biobuf *b) { volatile int fno, i; char c, *desc, *p; char *volatile dir, *volatile fn, *volatile name; Ftypes *f; Type *t, *tt; StabSym sym; dir = nil; fno = 0; fn = nil; for(i=0; stabsym(stabs, i, &sym)>=0; i++){ if(verbose) print("%d %s\n", sym.type, sym.name); switch(sym.type){ case N_SO: if(sym.name){ if(sym.name[0] && sym.name[strlen(sym.name)-1] == '/') dir = sym.name; } denumber(); fstack = nil; fno = 0; break; case N_BINCL: fno++; f = mkftypes(dir, sym.name); f->down = fstack; fstack = f; break; case N_EINCL: if(fstack) fstack = fstack->down; break; case N_EXCL: fno++; if((f = findftypes(dir, sym.name)) == nil){ static int cannotprint; if(cannotprint++ == 0) fprint(2, "cannot find remembered %s\n", sym.name); continue; } renumber(f->list, fno); break; case N_GSYM: case N_FUN: case N_PSYM: case N_LSYM: case N_LCSYM: case N_STSYM: case N_RSYM: name = sym.name; if(name == nil){ if(sym.type==N_FUN) fn = nil; continue; } if((p = findcolon(name)) == nil) continue; name = estrndup(name, p-name); desc = ++p; c = *desc; if(c == 'c'){ fprint(2, "skip constant %s\n", name); continue; } if(setjmp(kaboom)){ static int cannotparse; if(cannotparse++ == 0) fprint(2, "cannot parse %s\n", name); continue; } t = parsename(desc, &p); if(t == nil) continue; if(*p != 0){ static int extradesc; if(extradesc++ == 0) fprint(2, "extra desc '%s' in '%s'\n", p, desc); } /* void is defined as itself */ if(t->ty==Defer && t->sub==t && strcmp(name, "void")==0){ t->ty = Base; t->xsizeof = 0; t->printfmt = '0'; } if(*name==' ' && *(name+1) == 0) *name = 0; /* attach names to structs, unions, enums */ if(c=='T' && *name && t->sue){ t->suename = name; if(t->name == nil) t->name = name; tt = typebysue(t->sue, name); tt->ty = Defer; tt->sub = t; } if(c=='t'){ tt = newtype(); tt->ty = Typedef; tt->name = name; tt->sub = t; } /* define base c types */ if(t->ty==None || t->ty==Range){ if(strcmp(name, "char") == 0){ t->ty = Base; t->xsizeof = 1; t->printfmt = 'x'; } if(strcmp(name, "int") == 0){ t->ty = Base; t->xsizeof = 4; t->printfmt = 'd'; } } /* record declaration in list for later. */ if(c != 't' && c != 'T') switch(sym.type){ case N_GSYM: addsymx(nil, name, t); break; case N_FUN: fn = name; break; case N_PSYM: case N_LSYM: case N_LCSYM: case N_STSYM: case N_RSYM: addsymx(fn, name, t); break; } break; } if(1) print(""); } printtypes(b); dumpsyms(b); freetypes(); return 0; }
static Type* parsedefn(char *p, Type *t, char **pp) { char c, *name; int ischar, namelen, n, wid, offset, bits, sign; long val; Type *tt; if(*p == '(' || isdigit((uchar)*p)){ t->ty = Defer; t->sub = parseinfo(p, pp); return t; } switch(c = *p){ case '-': /* builtin */ n = strtol(p+1, &p, 10); if(n >= nelem(baseints) || n < 0) n = 0; t->ty = Base; t->xsizeof = baseints[n].size; t->printfmt = baseints[n].fmt; break; case 'b': /* builtin */ p++; if(*p != 'u' && *p != 's') oops(); sign = (*p == 's'); p++; ischar = 0; if(*p == 'c'){ ischar = 1; p++; } wid = parseint(&p); semi(&p); offset = parseint(&p); semi(&p); bits = parseint(&p); semi(&p); t->ty = Base; t->xsizeof = wid; if(sign == 1) t->printfmt = 'd'; else t->printfmt = 'x'; USED(bits); USED(ischar); break; case 'R': /* fp type */ n = parseint(&p); semi(&p); wid = parseint(&p); semi(&p); t->ty = Base; t->xsizeof = wid; if(n < 0 || n >= nelem(basefloats)) n = 0; t->xsizeof = basefloats[n].size; t->printfmt = basefloats[n].fmt; break; case 'r': /* subrange */ t->ty = Range; t->sub = parseinfo(p+1, &p); if(*(p-1) == ';' && *p != ';') p--; semi(&p); t->lo = parsebound(&p); semi(&p); t->hi = parsebound(&p); semi(&p); break; case 'B': /* volatile */ case 'k': /* const */ t->ty = Defer; t->sub = parseinfo(p+1, &p); break; case '*': /* pointer */ case 'A': /* open array */ case '&': /* reference */ /* guess - C++? (rob) */ t->ty = Pointer; t->sub = parseinfo(p+1, &p); break; case 'a': /* array */ case 'P': /* packed array */ t->ty = Pointer; tt = newtype(); parsedefn(p+1, tt, &p); /* index type */ if(*p == ';') p++; tt = newtype(); t->sub = tt; parsedefn(p, tt, &p); /* element type */ break; case 'e': /* enum listing */ p++; t->sue = 'e'; t->ty = Enum; while(*p != ';'){ name = p; p = findcolon(p)+1; namelen = (p-name)-1; val = parsebigint(&p); comma(&p); if(t->n%32 == 0){ t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0])); t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0])); } t->tname[t->n] = estrndup(name, namelen); t->val[t->n] = val; t->n++; } semi(&p); break; case 's': /* struct */ case 'u': /* union */ p++; t->sue = c; t->ty = Aggr; n = parseint(&p); while(*p != ';'){ name = p; p = findcolon(p)+1; namelen = (p-name)-1; tt = parseinfo(p, &p); comma(&p); offset = parseint(&p); comma(&p); bits = parseint(&p); semi(&p); if(t->n%32 == 0){ t->tname = erealloc(t->tname, (t->n+32)*sizeof(t->tname[0])); t->val = erealloc(t->val, (t->n+32)*sizeof(t->val[0])); t->t = erealloc(t->t, (t->n+32)*sizeof(t->t[0])); } t->tname[t->n] = estrndup(name, namelen); t->val[t->n] = offset; t->t[t->n] = tt; t->n++; } semi(&p); break; case 'x': /* struct, union, enum reference */ p++; t->ty = Defer; if(*p != 's' && *p != 'u' && *p != 'e') oops(); c = *p; name = p+1; p = findcolon(p+1); name = estrndup(name, p-name); t->sub = typebysue(c, name); p++; break; #if 0 /* AIX */ case 'f': /* function */ case 'p': /* procedure */ case 'F': /* Pascal function */ /* case 'R': /* Pascal procedure */ /* * Even though we don't use the info, we have * to parse it in case it is embedded in other descriptions. */ t->ty = Function; p++; if(c == 'f' || c == 'F'){ t->sub = parseinfo(p, &p); if(*p != ','){ if(*p == ';') p++; break; } comma(&p); } n = parseint(&p); /* number of params */ semi(&p); while(*p != ';'){ if(c == 'F' || c == 'R'){ name = p; /* parameter name */ p = findcolon(p)+1; } parseinfo(p, &p); /* param type */ comma(&p); parseint(&p); /* bool: passed by value? */ semi(&p); } semi(&p); break; #endif case 'f': /* static function */ case 'F': /* global function */ t->ty = Function; p++; t->sub = parseinfo(p, &p); break; /* * We'll never see any of this stuff. * When we do, we can worry about it. */ case 'D': /* n-dimensional array */ case 'E': /* subarray of n-dimensional array */ case 'M': /* fortran multiple instance type */ case 'N': /* pascal string ptr */ case 'S': /* set */ case 'c': /* aix complex */ case 'd': /* file of */ case 'g': /* aix float */ case 'n': /* max length string */ case 'w': /* aix wide char */ case 'z': /* another max length string */ default: fprint(2, "unsupported type char %c (%d)\n", *p, *p); oops(); } *pp = p; return t; }