Move getCanonicalType from being a method on ASTContext to being a method on Type.

Swift SVN r314
This commit is contained in:
Chris Lattner
2011-03-22 05:23:51 +00:00
parent e51f356bd6
commit fd2bf74f06
6 changed files with 62 additions and 61 deletions

View File

@@ -100,10 +100,6 @@ public:
// Type manipulation routines.
//===--------------------------------------------------------------------===//
/// getCanonicalType - Get the canonicalized version of a type, stripping off
/// sugar like argument names and type aliases.
Type *getCanonicalType(Type *T);
// Builtin type and simple types that are used frequently.
Type * const TheEmptyTupleType; /// TheEmptyTupleType - This is "()"
Type * const TheUnresolvedType; /// TheUnresolvedType - Not name bound.

View File

@@ -71,6 +71,10 @@ public:
/// canonical version of this type.
bool hasCanonicalTypeComputed() const { return CanonicalType != 0; }
/// getCanonicalType - Return the canonical version of this type, which has
/// sugar from all levels stripped off.
Type *getCanonicalType(ASTContext &Ctx);
/// getDesugaredType - If this type is a sugared type, remove all levels of
/// sugar until we get down to a non-sugar type.
Type *getDesugaredType();

View File

@@ -77,58 +77,6 @@ Identifier ASTContext::getIdentifier(llvm::StringRef Str) {
// Type manipulation routines.
//===----------------------------------------------------------------------===//
/// getCanonicalType - Get the canonicalized version of a type, stripping off
/// sugar like argument names and type aliases.
Type *ASTContext::getCanonicalType(Type *T) {
// If the type is itself canonical or if the canonical type was already
// computed, just return what we have.
if (T->CanonicalType)
return T->CanonicalType;
Type *Result = 0;
switch (T->Kind) {
case UnresolvedTypeKind:
assert(0 && "Cannot call getCanonicalType before name binding is complete");
case BuiltinInt32Kind:
case DependentTypeKind:
case OneOfTypeKind:
assert(0 && "These are always canonical");
case NameAliasTypeKind:
Result = getCanonicalType(llvm::cast<NameAliasType>(T)->getDesugaredType());
break;
case TupleTypeKind: {
llvm::SmallVector<TupleTypeElt, 8> CanElts;
TupleType *TT = llvm::cast<TupleType>(T);
CanElts.resize(TT->Fields.size());
for (unsigned i = 0, e = TT->Fields.size(); i != e; ++i) {
CanElts[i].Name = TT->Fields[i].Name;
assert(TT->Fields[i].Ty &&
"Cannot get canonical type of TypeChecked TupleType!");
CanElts[i].Ty = getCanonicalType(TT->Fields[i].Ty);
}
Result = getTupleType(CanElts);
break;
}
case FunctionTypeKind: {
FunctionType *FT = llvm::cast<FunctionType>(T);
Type *In = getCanonicalType(FT->Input);
Type *Out = getCanonicalType(FT->Result);
Result = getFunctionType(In, Out);
break;
}
case ArrayTypeKind:
ArrayType *AT = llvm::cast<ArrayType>(T);
Type *EltTy = getCanonicalType(AT->Base);
Result = getArrayType(EltTy, AT->Size);
break;
}
assert(Result && "Case not implemented!");
return Result;
}
void TupleType::Profile(llvm::FoldingSetNodeID &ID,
llvm::ArrayRef<TupleTypeElt> Fields) {
ID.AddInteger(Fields.size());

View File

@@ -31,6 +31,59 @@ void *Type::operator new(size_t Bytes, ASTContext &C,
// Various Type Methods.
//===----------------------------------------------------------------------===//
/// getCanonicalType - Return the canonical version of this type, which has
/// sugar from all levels stripped off.
Type *Type::getCanonicalType(ASTContext &Ctx) {
// If the type is itself canonical or if the canonical type was already
// computed, just return what we have.
if (CanonicalType)
return CanonicalType;
Type *Result = 0;
switch (Kind) {
case UnresolvedTypeKind:
assert(0 && "Cannot call getCanonicalType before name binding is complete");
case BuiltinInt32Kind:
case DependentTypeKind:
case OneOfTypeKind:
assert(0 && "These are always canonical");
case NameAliasTypeKind:
Result = llvm::cast<NameAliasType>(this)->
getDesugaredType()->getCanonicalType(Ctx);
break;
case TupleTypeKind: {
llvm::SmallVector<TupleTypeElt, 8> CanElts;
TupleType *TT = llvm::cast<TupleType>(this);
CanElts.resize(TT->Fields.size());
for (unsigned i = 0, e = TT->Fields.size(); i != e; ++i) {
CanElts[i].Name = TT->Fields[i].Name;
assert(TT->Fields[i].Ty &&
"Cannot get canonical type of TypeChecked TupleType!");
CanElts[i].Ty = TT->Fields[i].Ty->getCanonicalType(Ctx);
}
Result = Ctx.getTupleType(CanElts);
break;
}
case FunctionTypeKind: {
FunctionType *FT = llvm::cast<FunctionType>(this);
Type *In = FT->Input->getCanonicalType(Ctx);
Type *Out = FT->Result->getCanonicalType(Ctx);
Result = Ctx.getFunctionType(In, Out);
break;
}
case ArrayTypeKind:
ArrayType *AT = llvm::cast<ArrayType>(this);
Type *EltTy = AT->Base->getCanonicalType(Ctx);
Result = Ctx.getArrayType(EltTy, AT->Size);
break;
}
assert(Result && "Case not implemented!");
return Result;
}
Type *Type::getDesugaredType() {
switch (Kind) {
case DependentTypeKind:

View File

@@ -82,7 +82,7 @@ ActOnScopedIdentifierExpr(Identifier ScopeName, llvm::SMLoc ScopeLoc,
// Note: this is very simplistic support for scoped name lookup, extend when
// needed.
TypeAliasDecl *TypeScopeDecl = S.decl.LookupTypeName(ScopeName, ScopeLoc);
Type *TypeScope = S.Context.getCanonicalType(TypeScopeDecl->UnderlyingTy);
Type *TypeScope = TypeScopeDecl->UnderlyingTy->getCanonicalType(S.Context);
// FIXME: Handle UnresolvedType.

View File

@@ -1146,9 +1146,9 @@ static Expr *HandleScalarConversionToTupleType(Expr *E, Type *DestTy,
/// failure.
static Expr *HandleConversionToType(Expr *E, Type *DestTy, bool IgnoreAnonDecls,
TypeChecker &TC) {
Type *CanDestTy = TC.Context.getCanonicalType(DestTy);
// If we have an exact match, we're done.
if (TC.Context.getCanonicalType(E->Ty) == CanDestTy)
if (E->Ty->getCanonicalType(TC.Context) ==
DestTy->getCanonicalType(TC.Context))
return E;
assert(!isa<DependentType>(DestTy) &&
@@ -1375,7 +1375,7 @@ bool TypeChecker::validateType(Type *&T) {
// that we never reanalyze it again.
// If it is ever a performance win to avoid computing canonical types, we can
// just keep a SmallPtrSet of analyzed Types in TypeChecker.
Context.getCanonicalType(T);
T->getCanonicalType(Context);
// FIXME: This isn't good enough: top-level stuff can have these as well and
// their types need to be resolved at the end of name binding. Perhaps we