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.
|
// 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.
|
// Builtin type and simple types that are used frequently.
|
||||||
Type * const TheEmptyTupleType; /// TheEmptyTupleType - This is "()"
|
Type * const TheEmptyTupleType; /// TheEmptyTupleType - This is "()"
|
||||||
Type * const TheUnresolvedType; /// TheUnresolvedType - Not name bound.
|
Type * const TheUnresolvedType; /// TheUnresolvedType - Not name bound.
|
||||||
|
|||||||
@@ -70,7 +70,11 @@ public:
|
|||||||
/// hasCanonicalTypeComputed - Return true if we've already computed a
|
/// hasCanonicalTypeComputed - Return true if we've already computed a
|
||||||
/// canonical version of this type.
|
/// canonical version of this type.
|
||||||
bool hasCanonicalTypeComputed() const { return CanonicalType != 0; }
|
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
|
/// getDesugaredType - If this type is a sugared type, remove all levels of
|
||||||
/// sugar until we get down to a non-sugar type.
|
/// sugar until we get down to a non-sugar type.
|
||||||
Type *getDesugaredType();
|
Type *getDesugaredType();
|
||||||
|
|||||||
@@ -77,58 +77,6 @@ Identifier ASTContext::getIdentifier(llvm::StringRef Str) {
|
|||||||
// Type manipulation routines.
|
// 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,
|
void TupleType::Profile(llvm::FoldingSetNodeID &ID,
|
||||||
llvm::ArrayRef<TupleTypeElt> Fields) {
|
llvm::ArrayRef<TupleTypeElt> Fields) {
|
||||||
ID.AddInteger(Fields.size());
|
ID.AddInteger(Fields.size());
|
||||||
|
|||||||
@@ -31,6 +31,59 @@ void *Type::operator new(size_t Bytes, ASTContext &C,
|
|||||||
// Various Type Methods.
|
// 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() {
|
Type *Type::getDesugaredType() {
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case DependentTypeKind:
|
case DependentTypeKind:
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ ActOnScopedIdentifierExpr(Identifier ScopeName, llvm::SMLoc ScopeLoc,
|
|||||||
// Note: this is very simplistic support for scoped name lookup, extend when
|
// Note: this is very simplistic support for scoped name lookup, extend when
|
||||||
// needed.
|
// needed.
|
||||||
TypeAliasDecl *TypeScopeDecl = S.decl.LookupTypeName(ScopeName, ScopeLoc);
|
TypeAliasDecl *TypeScopeDecl = S.decl.LookupTypeName(ScopeName, ScopeLoc);
|
||||||
Type *TypeScope = S.Context.getCanonicalType(TypeScopeDecl->UnderlyingTy);
|
Type *TypeScope = TypeScopeDecl->UnderlyingTy->getCanonicalType(S.Context);
|
||||||
|
|
||||||
// FIXME: Handle UnresolvedType.
|
// FIXME: Handle UnresolvedType.
|
||||||
|
|
||||||
|
|||||||
@@ -1146,9 +1146,9 @@ static Expr *HandleScalarConversionToTupleType(Expr *E, Type *DestTy,
|
|||||||
/// failure.
|
/// failure.
|
||||||
static Expr *HandleConversionToType(Expr *E, Type *DestTy, bool IgnoreAnonDecls,
|
static Expr *HandleConversionToType(Expr *E, Type *DestTy, bool IgnoreAnonDecls,
|
||||||
TypeChecker &TC) {
|
TypeChecker &TC) {
|
||||||
Type *CanDestTy = TC.Context.getCanonicalType(DestTy);
|
|
||||||
// If we have an exact match, we're done.
|
// 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;
|
return E;
|
||||||
|
|
||||||
assert(!isa<DependentType>(DestTy) &&
|
assert(!isa<DependentType>(DestTy) &&
|
||||||
@@ -1375,7 +1375,7 @@ bool TypeChecker::validateType(Type *&T) {
|
|||||||
// that we never reanalyze it again.
|
// that we never reanalyze it again.
|
||||||
// If it is ever a performance win to avoid computing canonical types, we can
|
// If it is ever a performance win to avoid computing canonical types, we can
|
||||||
// just keep a SmallPtrSet of analyzed Types in TypeChecker.
|
// 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
|
// 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
|
// their types need to be resolved at the end of name binding. Perhaps we
|
||||||
|
|||||||
Reference in New Issue
Block a user