Beispiel #1
0
// 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);
}