// We make a reasonable effort to resolve types early, since TypeSpecifier is // quite a large structure (48 bytes on x86, as of this writing, and it will // only get bigger). We want to eliminate it from the AST, as well as reduce // dependence on TypeResolver which is a rather expensive pass. TypeExpr NameResolver::resolve(TypeSpecifier &spec, TypeSpecHelper *helper) { Type *type = resolveBase(spec); if (!type) return delay(spec); // Note: we are only updating the base type! We can't overwrite the whole // spec because it gets reused for parsing some decls. spec.setResolvedBaseType(type); // If the base type is an unresolved typedef, we have to wait. if (type->isUnresolvedTypedef()) return delay(spec); // If we have an array, but it's not a valid construction, then we just error // and delay (we'll never reach type resolution after we error). if (spec.rank()) { if (!tr_.checkArrayInnerType(&spec, type)) return delay(spec); } if (spec.dims()) { // If we have explicit dimension sizes, we have to bail out and wait for // type resolution (which also does constant resolution). We do special // case the very common integer literal, single-dimension case. if (spec.rank() != 1) return delay(spec); Expression *expr = spec.sizeOfRank(0); if (!expr || !expr->isIntegerLiteral()) return delay(spec); IntegerLiteral *lit = expr->toIntegerLiteral(); if (lit->value() < 1 || lit->value() > ArrayType::kMaxSize) return delay(spec); type = cc_.types()->newArray(type, (int32_t)lit->value()); } else if (spec.rank()) { for (size_t i = 0; i < spec.rank(); i++) type = cc_.types()->newArray(type, ArrayType::kUnsized); } if (spec.isConst()) type = tr_.applyConstQualifier(&spec, type, helper); return TypeExpr(type); }