예제 #1
0
static Type lookupDefaultLiteralType(TypeChecker &TC, DeclContext *dc,
                                     StringRef name) {
  auto lookupOptions = defaultUnqualifiedLookupOptions;
  if (isa<AbstractFunctionDecl>(dc))
    lookupOptions |= NameLookupFlags::KnownPrivate;
  auto lookup = TC.lookupUnqualified(dc->getModuleScopeContext(),
                                     TC.Context.getIdentifier(name),
                                     SourceLoc(),
                                     lookupOptions);
  TypeDecl *TD = lookup.getSingleTypeResult();
  if (!TD)
    return Type();
  TC.validateDecl(TD);
  return TD->getDeclaredType();
}
예제 #2
0
QualType TypeResolver::resolveUnresolved(QualType Q) const {
    const Type* T = Q.getTypePtr();
    switch (Q->getTypeClass()) {
    case TC_BUILTIN:
        return Q;
    case TC_POINTER:
        {
            // Dont return new type if not needed
            const PointerType* P = cast<PointerType>(T);
            QualType t1 = P->getPointeeType();
            QualType Result = resolveUnresolved(t1);
            if (t1 == Result) return Q;
            // TODO qualifiers
            return typeContext.getPointerType(Result);
        }
    case TC_ARRAY:
        {
            const ArrayType* A = cast<ArrayType>(T);
            QualType t1 = A->getElementType();
            QualType Result = resolveUnresolved(t1);
            if (t1 == Result) return Q;
            // TODO qualifiers
            return typeContext.getArrayType(Result, A->getSizeExpr(), false, A->isIncremental());

        }
    case TC_UNRESOLVED:
        {
            const UnresolvedType* U = cast<UnresolvedType>(T);
            TypeDecl* TD = U->getDecl();
            assert(TD);
            QualType result = TD->getType();
            if (Q.isConstQualified()) result.addConst();
            if (Q.isVolatileQualified()) result.addVolatile();
            return result;
        }
    case TC_ALIAS:
    case TC_STRUCT:
    case TC_ENUM:
    case TC_FUNCTION:
        return Q;
    case TC_MODULE:
        assert(0 && "TBD");
        return Q;
    }
    return Q;
}
예제 #3
0
unsigned TypeResolver::checkUnresolvedType(const UnresolvedType* type, bool used_public) {
    IdentifierExpr* moduleName = type->getModuleName();
    IdentifierExpr* typeName = type->getTypeName();
    SourceLocation tLoc = typeName->getLocation();
    const std::string& tName = typeName->getName();

    Decl* D = 0;
    if (moduleName) {   // mod.type
        const std::string& mName = moduleName->getName();
        const Module* mod = globals.findUsedModule(mName, moduleName->getLocation(), used_public);
        if (!mod) return 1;
        Decl* modDecl = globals.findSymbol(mName, moduleName->getLocation(), true, used_public);
        assert(modDecl);
        moduleName->setDecl(modDecl);

        D =  globals.findSymbolInModule(tName, tLoc, mod);
    } else {
        D = globals.findSymbol(tName, tLoc, true, used_public);
    }
    if (!D) return 1;
    TypeDecl* TD = dyncast<TypeDecl>(D);
    if (!TD) {
        StringBuilder name;
        type->printLiteral(name);
        Diags.Report(tLoc, diag::err_not_a_typename) << name.c_str();
        return 1;
    }
    bool external = globals.isExternal(D->getModule());
    if (used_public &&!external && !TD->isPublic()) {
        StringBuilder name;
        type->printLiteral(name);
        Diags.Report(tLoc, diag::err_non_public_type) << AnalyserUtils::fullName(TD->getModule()->getName(), TD->getName());
        //Diags.Report(tLoc, diag::err_non_public_type) << name;
        return 1;
    }
    D->setUsed();
    if (used_public || external) D->setUsedPublic();
    typeName->setDecl(TD);
    return 0;
}
예제 #4
0
QualType TypeResolver::checkCanonicals(Decls& decls, QualType Q, bool set) const {
    if (Q->hasCanonicalType()) return Q.getCanonicalType();

    const Type* T = Q.getTypePtr();
    switch (Q->getTypeClass()) {
    case TC_BUILTIN:
        return Q;
    case TC_POINTER:
        {
            const PointerType* P = cast<PointerType>(T);
            QualType t1 = P->getPointeeType();
            // Pointee will always be in same TypeContext (file), since it's either built-in or UnresolvedType
            QualType t2 = checkCanonicals(decls, t1, set);
            if (!t2.isValid()) return t2;
            QualType canon;
            if (t1 == t2) canon = Q;
            else {
                canon = typeContext.getPointerType(t2);
                if (!canon->hasCanonicalType()) canon->setCanonicalType(canon);
            }
            assert(Q.isValid());
            if (set) P->setCanonicalType(canon);
            return canon;
        }
    case TC_ARRAY:
        {
            const ArrayType* A = cast<ArrayType>(T);
            QualType t1 = A->getElementType();
            // NOTE: qualifiers are lost here!
            QualType t2 = checkCanonicals(decls, t1, set);
            if (!t2.isValid()) return t2;
            QualType canon;
            if (t1 == t2) canon = Q;
            // NOTE: need size Expr, but set ownership to none
            else {
                canon = typeContext.getArrayType(t2, A->getSizeExpr(), false, A->isIncremental());
                if (!canon->hasCanonicalType()) canon->setCanonicalType(canon);
            }

            if (set) A->setCanonicalType(canon);
            return canon;
        }
    case TC_UNRESOLVED:
        {
            const UnresolvedType* U = cast<UnresolvedType>(T);
            TypeDecl* TD = U->getDecl();
            assert(TD);
            // check if exists
            if (!checkDecls(decls, TD)) {
                return QualType();
            }
            QualType canonical = checkCanonicals(decls, TD->getType(), false);
            if (set) U->setCanonicalType(canonical);
            return canonical;
        }
    case TC_ALIAS:
        {
            const AliasType* A = cast<AliasType>(T);
            if (!checkDecls(decls, A->getDecl())) {
                return QualType();
            }
            QualType canonical = checkCanonicals(decls, A->getRefType(), set);
            assert(Q.isValid());
            if (set) A->setCanonicalType(canonical);
            return canonical;
        }
    case TC_STRUCT:
        return Q.getCanonicalType();
    case TC_ENUM:
        {
            assert(0 && "TODO");
            return 0;
        }
    case TC_FUNCTION:
        return Q.getCanonicalType();
    case TC_MODULE:
        assert(0 && "TBD");
        return 0;
    }
    assert(0);
}
예제 #5
0
파일: Scope.cpp 프로젝트: vfr-nl/c2compiler
int FileScope::checkUserType(Type* type, Expr* id, bool used_public) {
    // TODO refactor
    const Package* pkg = 0;
    switch (id->getKind()) {
    case EXPR_IDENTIFIER:   // unqualified
        {
            IdentifierExpr* I = cast<IdentifierExpr>(id);
            ScopeResult res = findSymbol(I->getName());
            if (!res.decl) {
                Diags.Report(I->getLocation(), diag::err_unknown_typename) << I->getName();
                return 1;
            }
            if (res.ambiguous) {
                Diags.Report(I->getLocation(), diag::err_ambiguous_symbol) << I->getName();
                // TODO show alternatives
                return 1;
            }
            if (res.external && !res.decl->isPublic()) {
                Diags.Report(I->getLocation(), diag::err_not_public) << I->getName();
                return 1;
            }
            TypeDecl* td = dyncast<TypeDecl>(res.decl);
            if (!td) {
                Diags.Report(I->getLocation(), diag::err_not_a_typename) << I->getName();
                return 1;
            }
            if (used_public && !res.external && !td->isPublic()) {
                Diags.Report(I->getLocation(), diag::err_non_public_type) << I->getName();
                return 1;
            }
            // ok
            assert(res.pkg && "pkg should be set");
            I->setPackage(res.pkg);
            I->setDecl(res.decl);
            type->setRefType(td->getType());
        }
        break;
    case EXPR_MEMBER:   // fully qualified
        {
            MemberExpr* M = cast<MemberExpr>(id);
            Expr* base = M->getBase();
            IdentifierExpr* pkg_id = cast<IdentifierExpr>(base);
            const std::string& pkgName = pkg_id->getName();
            // check if package exists
            pkg = findPackage(pkgName);
            if (!pkg) {
                // check if used with alias (then fullname is forbidden)
                for (PackagesConstIter iter = packages.begin(); iter != packages.end(); ++iter) {
                    const Package* p = iter->second;
                    if (p->getName() == pkgName) {
                        Diags.Report(pkg_id->getLocation(), diag::err_package_has_alias) << pkgName << iter->first;
                        return 1;
                    }
                }
                // TODO use function
                PkgsConstIter iter = allPackages.find(pkgName);
                if (iter == allPackages.end()) {
                    Diags.Report(pkg_id->getLocation(), diag::err_unknown_package) << pkgName;
                } else {
                    Diags.Report(pkg_id->getLocation(), diag::err_package_not_used) << pkgName;
                }
                return 1;
            }
            // check member
            Expr* member = M->getMember();
            IdentifierExpr* member_id = cast<IdentifierExpr>(member);
            // check Type
            Decl* symbol = pkg->findSymbol(member_id->getName());
            if (!symbol) {
                Diags.Report(member_id->getLocation(), diag::err_unknown_typename) << M->getFullName();
                return 1;
            }
            TypeDecl* td = dyncast<TypeDecl>(symbol);
            if (!td) {
                Diags.Report(member_id->getLocation(), diag::err_not_a_typename) << M->getFullName();
                return 1;
            }
            // if external package, check visibility
            if (isExternal(pkg) && !td->isPublic()) {
                Diags.Report(member_id->getLocation(), diag::err_not_public) << M->getFullName();
                return 1;
            }
            if (used_public && !isExternal(pkg) && !td->isPublic()) {
                Diags.Report(member_id->getLocation(), diag::err_non_public_type) << M->getFullName();
                return 1;
            }
            // ok
            member_id->setPackage(pkg);
            type->setRefType(td->getType());
        }
        break;
    default:
        assert(0);
    }
    return 0;
}