int FileScope::checkType(QualType type, bool used_public) { assert(type.isValid()); const Type* T = type.getTypePtr(); switch (T->getKind()) { case Type::BUILTIN: return 1; case Type::STRUCT: case Type::UNION: assert(0); break; case Type::ENUM: { QualType qt = T->getRefType(); if (qt.isValid()) return checkType(qt, used_public); return 1; } case Type::USER: // TEMP CONST CAST return checkUserType((Type*)T, type->getBaseUserType(), used_public); case Type::FUNC: // TODO assert(0 && "TODO"); break; case Type::POINTER: case Type::ARRAY: return checkType(T->getRefType(), used_public); } }
bool ExprTypeAnalyser::checkCompatible(QualType left, const Expr* expr) const { QualType right = expr->getType(); //right = TypeFinder::findType(expr); assert(left.isValid()); const Type* canon = left.getCanonicalType(); assert(canon); switch (canon->getTypeClass()) { case TC_BUILTIN: return checkBuiltin(left, right, expr, true); case TC_POINTER: return checkPointer(left, right, expr); case TC_ARRAY: break; case TC_UNRESOLVED: break; case TC_ALIAS: break; case TC_STRUCT: break; case TC_ENUM: break; case TC_FUNCTION: return checkFunction(left, expr); case TC_MODULE: assert(0 && "TODO"); break; } return false; }
void ArrayType::setSize(const llvm::APInt& value) { Size = value; arrayTypeBits.hasSize = 1; // also set on Canonical QualType canonical = getCanonicalType(); assert(canonical.isValid()); Type* T = canonical.getTypePtr(); if (T != this) { ArrayType* AT = cast<ArrayType>(T); AT->setSize(value); } }
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); }
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); }