Пример #1
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;
}
Пример #2
0
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;
}