Beispiel #1
0
QualType TypeResolver::resolveCanonical(QualType Q) 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 = resolveCanonical(t1);
            assert(t2.isValid());
            if (t1 == t2) {
                Q->setCanonicalType(Q);
                return Q;
            } else {
                // TODO qualifiers
                QualType Canon = typeContext.getPointerType(t2);
                if (!Canon->hasCanonicalType()) Canon->setCanonicalType(Canon);
                Q->setCanonicalType(Canon);
                return Canon;
            }
        }
    case TC_ARRAY:
        {
            const ArrayType* A = cast<ArrayType>(T);
            QualType t1 = A->getElementType();
            // NOTE: qualifiers are lost here!
            QualType t2 = resolveCanonical(t1);
            if (t1 == t2) {
                Q->setCanonicalType(Q);
                return Q;
            } else  {
                // NOTE: need size Expr, but set ownership to none
                QualType Canon = typeContext.getArrayType(t2, A->getSizeExpr(), false, A->isIncremental());
                if (!Canon->hasCanonicalType()) Canon->setCanonicalType(Canon);
                Q->setCanonicalType(Canon);
                return Canon;
            }
        }
    case TC_UNRESOLVED:
        assert(0 && "should not get here");
        return QualType();
    case TC_ALIAS:
    case TC_STRUCT:
    case TC_ENUM:
    case TC_FUNCTION:
        return Q.getCanonicalType();
    case TC_MODULE:
        assert(0 && "TBD");
        return Q;
    }
    assert(0);
}
Beispiel #2
0
QualType TypeResolver::resolveType(QualType Q, bool usedPublic) {
    if (Q->hasCanonicalType()) return Q;    // should be ok already

    // basic resolving of Unresolved
    if (checkType(Q, usedPublic)) return QualType();
    QualType resolved = resolveUnresolved(Q);

    resolveCanonical(resolved);
    return resolved;
}
Beispiel #3
0
QualType TypeContext::getPointerType(QualType ref) {
    assert(ref.isValid());
    for (unsigned i=0; i<types.size(); i++) {
        Type* t = types[i];
        if (isa<PointerType>(t)) {
            PointerType* P = cast<PointerType>(t);
            if (P->getPointeeType() == ref) return t;
        }
    }
    Type* N = new PointerType(ref);
    if (ref->hasCanonicalType()) N->setCanonicalType(N);
    return add(N);
}
Beispiel #4
0
EnumTypeDecl* C2Sema::ActOnEnumType(const char* name, SourceLocation loc, Expr* implType, bool is_public) {
    assert(implType);
    TypeExpr* T = cast<TypeExpr>(implType);
    QualType impl = T->getType();
    assert(impl->hasCanonicalType());
    delete T;

    QualType qt = typeContext.getEnumType();
    EnumTypeDecl* E = new EnumTypeDecl(name, loc, impl, qt, is_public);
    EnumType* ET = cast<EnumType>(qt.getTypePtr());
    ET->setCanonicalType(impl);
    ET->setDecl(E);
    ast.addType(E);
    addSymbol(E);
    return E;
}
Beispiel #5
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);
}
Beispiel #6
0
QualType TypeContext::getArrayType(QualType element, Expr* size, bool ownSize, bool isIncremental) {
    Type* N = new ArrayType(element, size, ownSize, isIncremental);
    if (element->hasCanonicalType()) N->setCanonicalType(N);
    return add(N);
}