mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Move getCanonicalType from being a method on ASTContext to being a method on Type.
Swift SVN r314
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -70,7 +70,11 @@ public:
|
||||
/// hasCanonicalTypeComputed - Return true if we've already computed a
|
||||
/// 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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user