Esempio n. 1
0
AString
sp::BuildTypeName(Type *aType, Atom *name, TypeDiagFlags flags)
{
  if (ArrayType *type = aType->asArray()) {
    Vector<ArrayType *> stack;

    Type *cursor = type;
    Type *innermost = nullptr;
    for (;;) {
      if (!cursor->isArray()) {
        innermost = cursor;
        break;
      }
      stack.append(cursor->toArray());
      cursor = cursor->toArray()->contained();
    }

    AutoString builder;
    if (aType->isConst() || !!(flags & TypeDiagFlags::IsConst))
      builder = "const ";

    builder = builder + BuildTypeName(innermost, nullptr, flags & kDiagFlagsInnerMask);

    bool hasFixedLengths = false;
    AutoString brackets;
    for (size_t i = 0; i < stack.length(); i++) {
      if (!stack[i]->hasFixedLength()) {
        brackets = brackets + "[]";
        continue;
      }

      hasFixedLengths = true;
      brackets = brackets + "[" + AutoString(stack[i]->fixedLength()) + "]";
    }

    if (name) {
      if (hasFixedLengths)
        builder = builder + " " + name->chars() + brackets;
      else
        builder = builder + brackets + " " + name->chars();
    } else {
      builder = builder + brackets;
    }
    return AString(builder.ptr());
  }

  AutoString builder;
  if (FunctionType *type = aType->asFunction())
    builder = BuildTypeFromSignature(type->signature(), flags & kDiagFlagsInnerMask);
  else
    builder = GetBaseTypeName(aType);
  if (!!(flags & TypeDiagFlags::IsByRef)) {
    builder = builder + "&";
  }
  if (name)
    builder = builder + " " + name->chars();
  return AString(builder.ptr());
}
Esempio n. 2
0
bool
Preprocessor::enterFile(TokenKind directive,
                        const SourceLocation &from,
                        const char *file,
                        const char *where)
{
  if (disable_includes_)
    return false;

  AutoString path = searchPaths(file, where);
  if (!path.length()) {
    // Try to append '.inc'.
    size_t len = strlen(file);
    if (len < 4 || strcmp(&file[len - 4], ".inc") != 0) {
      AutoString new_file = AutoString(file) + ".inc";
      path = searchPaths(new_file, where);
    }
  }

  if (!path.length()) {
    if (directive == TOK_M_TRYINCLUDE)
      return true;

    cc_.report(from, rmsg::include_not_found)
      << file;
    return false;
  }

  ReportingContext rc(cc_, from);
  Ref<SourceFile> new_file = cc_.source().open(rc, path.ptr());
  if (!new_file)
    return false;

  LREntry tl = cc_.source().trackFile(from, new_file);
  if (!tl.valid()) {
    // Error was already reported.
    return false;
  }

  if (include_depth_ >= kMaxIncludeDepth) {
    cc_.report(from, rmsg::include_depth_exceeded);
    return false;
  }

  include_depth_++;

  assert(!macro_lexer_ && lexer_);
  lexer_stack_.append(SavedLexer(lexer_, nullptr));
  lexer_ = new Lexer(cc_, *this, lexer_->options(), new_file, tl);
  return true;
}
Esempio n. 3
0
static AString
BuildTypeFromSignature(const FunctionSignature *sig, TypeDiagFlags flags)
{
  AutoString base = "function ";
  base = base + BuildTypeFromTypeExpr(sig->returnType(), nullptr, flags & kDiagFlagsInnerMask);
  base = base + "(";

  for (size_t i = 0; i < sig->parameters()->length(); i++) {
    TypeDiagFlags varFlags = flags & kDiagFlagsInnerMask;
    Atom *name = !!(flags & TypeDiagFlags::Names)
                 ? sig->parameters()->at(i)->name()
                 : nullptr;
    if (sig->parameters()->at(i)->sym()->isByRef())
      varFlags |= TypeDiagFlags::IsByRef;
    base = base + BuildTypeFromTypeExpr(sig->parameters()->at(i)->te(), name, varFlags);
    if (i != sig->parameters()->length() - 1)
      base = base + ", ";
  }
  base = base + ")";
  return AString(base.ptr());
}
Esempio n. 4
0
  JsonList *toJson(const ParameterList *params) {
    JsonList *list = new (pool_) JsonList();
    for (size_t i = 0; i < params->length(); i++) {
      VarDecl *decl = params->at(i);
      JsonObject *obj = new (pool_) JsonObject();

      obj->add(atom_type_, toJson(decl, false));

      if (decl->name()) {
        obj->add(atom_name_, toJson(decl->name()));
        obj->add(atom_decl_, toJson(decl, true));
      } else {
        obj->add(atom_name_, toJson("..."));

        AutoString builder = BuildTypeName(decl->te(), nullptr, TypeDiagFlags::Names);
        builder = builder + " ...";
        obj->add(atom_decl_, toJson(builder.ptr()));
      }
      list->add(obj);
    }
    return list;
  }
Esempio n. 5
0
static AString
BuildTypeFromSpecifier(const TypeSpecifier *spec, Atom *name, TypeDiagFlags flags)
{
  AutoString base;
  if (spec->isConst() || !!(flags & TypeDiagFlags::IsConst))
    base = "const ";

  switch (spec->resolver()) {
    case TOK_LABEL:
    {
      // HACK: we should move these atoms into the context.
      const char *chars = spec->proxy()->name()->chars();
      if (strcmp(chars, "Float") == 0)
        base = base + "float";
      else if (strcmp(chars, "String") == 0)
        base = base + "char";
      else if (strcmp(chars, "_") == 0)
        base = base + "int";
      else
        base = base + chars;
      break;
    }
    case TOK_NAME:
      base = base + spec->proxy()->name()->chars();
      break;
    case TOK_IMPLICIT_INT:
      base = base + "int";
      break;
    case TOK_FUNCTION:
      base = base + BuildTypeFromSignature(spec->signature(), flags & kDiagFlagsInnerMask);
      break;
    case TOK_DEFINED:
      base = base + BuildTypeName(spec->getResolvedBase(), nullptr, flags & kDiagFlagsInnerMask);
      break;
    default:
      base = base + TokenNames[spec->resolver()];
      break;
  }

  // We need type analysis to determine the true type, so just make a semi-
  // intelligent guess based on whether or not any rank has a sized dimension.
  bool postDims = (spec->isNewDecl() && spec->hasPostDims()) ||
                  (spec->isOldDecl() && spec->dims());

  if (name && postDims)
    base = base + " " + name->chars();

  for (size_t i = 0; i < spec->rank(); i++) {
    if (Expression *expr = spec->sizeOfRank(i)) {
      if (IntegerLiteral *lit = expr->asIntegerLiteral()) {
        char value[24];
        SafeSprintf(value, sizeof(value), "%d", (int)lit->value());
        base = base + "[" + value + "]";
        continue;
      }
    }

    // Hack. We can do better if it becomes necessary, these types are only
    // for diagnostics.
    base = base + "[]";
  }
  if (name && !postDims) {
    base = base + " ";
    if (spec->isByRef())
      base = base + "&";
    base = base + name->chars();
  } else {
    if (spec->isByRef())
      base = base + "&";
  }

  if (spec->isVariadic())
    base = base + " ...";

  return AString(base.ptr());
}