void TypeResolver::visitTypedefDecl(TypedefDecl *node) { // Re-entrancy guard. if (node->te().resolved()) return; TypedefType *type = node->sym()->type()->toTypedef(); const SourceLocation &baseLoc = node->te().spec()->baseLoc(); // This is our recursion guard. Type *actual = resolveType(node->te()); // Check for a recursive type. There might be a better way to do this, but // for now this is what we've got: just manually check any compound type // that wouldn't be able to handle a self-reference. Type *base = actual; if (ArrayType *array = base->asArray()) { while (array->contained()->isArray()) array = array->contained()->toArray(); base = array->contained(); } if (type == base->canonical()) { type->resolve(&UnresolvableType); cc_.report(baseLoc, rmsg::recursive_type); return; } type->resolve(actual); }
TypedefDecl * NameResolver::HandleTypedefDecl(const SourceLocation &begin, Atom *name, TypeSpecifier &spec) { TypeExpr te = resolve(spec); TypedefDecl *node = new (pool_) TypedefDecl(begin, name, te); TypeSymbol *sym = new (pool_) TypeSymbol(node, getOrCreateScope(), node->name()); TypedefType *type = cc_.types()->newTypedef(node->name()); sym->setType(type); registerSymbol(sym); node->setSymbol(sym); if (te.resolved()) type->resolve(te.resolved()); else tr_.addPending(node); return node; }