Skip to content

Clean up the constructors of DebugTypeInfo #6632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 85 additions & 30 deletions lib/IDE/TypeReconstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,45 @@ static void VisitNodeFunction(
}
}

static void CreateFunctionType(ASTContext *ast,
const VisitNodeResult &arg_type_result,
const VisitNodeResult &return_type_result,
bool throws,
VisitNodeResult &result) {
Type arg_clang_type;
Type return_clang_type;

switch (arg_type_result._types.size()) {
case 0:
arg_clang_type = TupleType::getEmpty(*ast);
break;
case 1:
arg_clang_type = arg_type_result._types.front().getPointer();
break;
default:
result._error = "too many argument types for a function type";
break;
}

switch (return_type_result._types.size()) {
case 0:
return_clang_type = TupleType::getEmpty(*ast);
break;
case 1:
return_clang_type = return_type_result._types.front().getPointer();
break;
default:
result._error = "too many return types for a function type";
break;
}

if (arg_clang_type && return_clang_type) {
result._types.push_back(
FunctionType::get(arg_clang_type, return_clang_type,
FunctionType::ExtInfo().withThrows(throws)));
}
}

static void VisitNodeFunctionType(
ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
Demangle::NodePointer &cur_node, VisitNodeResult &result,
Expand Down Expand Up @@ -1395,40 +1434,52 @@ static void VisitNodeFunctionType(
break;
}
}
Type arg_clang_type;
Type return_clang_type;

switch (arg_type_result._types.size()) {
case 0:
arg_clang_type = TupleType::getEmpty(*ast);
break;
case 1:
arg_clang_type = arg_type_result._types.front().getPointer();
break;
default:
result._error = "too many argument types for a function type";
break;
}

switch (return_type_result._types.size()) {
case 0:
return_clang_type = TupleType::getEmpty(*ast);
break;
case 1:
return_clang_type = return_type_result._types.front().getPointer();
break;
default:
result._error = "too many return types for a function type";
break;
}
CreateFunctionType(ast, arg_type_result, return_type_result, throws, result);
}

if (arg_clang_type && return_clang_type) {
result._types.push_back(
FunctionType::get(arg_clang_type, return_clang_type,
FunctionType::ExtInfo().withThrows(throws)));
static void VisitNodeImplFunctionType(
ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
Demangle::NodePointer &cur_node, VisitNodeResult &result,
const VisitNodeResult &generic_context) { // set by GenericType case
VisitNodeResult arg_type_result;
VisitNodeResult return_type_result;
Demangle::Node::iterator end = cur_node->end();
bool throws = false;
for (Demangle::Node::iterator pos = cur_node->begin(); pos != end; ++pos) {
const Demangle::Node::Kind child_node_kind = (*pos)->getKind();
switch (child_node_kind) {
case Demangle::Node::Kind::Class: {
VisitNodeResult class_type_result;
nodes.push_back(*pos);
VisitNode(ast, nodes, class_type_result, generic_context);
} break;
case Demangle::Node::Kind::Structure: {
VisitNodeResult class_type_result;
nodes.push_back(*pos);
VisitNode(ast, nodes, class_type_result, generic_context);
} break;
case Demangle::Node::Kind::ImplConvention:
// Ignore the ImplConvention it is only a hint for the SIL ARC optimizer.
break;
case Demangle::Node::Kind::ImplParameter:
nodes.push_back(*pos);
VisitNode(ast, nodes, arg_type_result, generic_context);
break;
case Demangle::Node::Kind::ThrowsAnnotation:
throws = true;
break;
case Demangle::Node::Kind::ImplResult:
nodes.push_back(*pos);
VisitNode(ast, nodes, return_type_result, generic_context);
break;
default:
break;
}
}
CreateFunctionType(ast, arg_type_result, return_type_result, throws, result);
}


static void VisitNodeSetterGetter(
ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
Demangle::NodePointer &cur_node, VisitNodeResult &result,
Expand Down Expand Up @@ -2072,6 +2123,10 @@ static void visitNodeImpl(
VisitNodeFunctionType(ast, nodes, node, result, genericContext);
break;

case Demangle::Node::Kind::ImplFunctionType:
VisitNodeImplFunctionType(ast, nodes, node, result, genericContext);
break;

case Demangle::Node::Kind::DidSet:
case Demangle::Node::Kind::Getter:
case Demangle::Node::Kind::Setter:
Expand Down
152 changes: 68 additions & 84 deletions lib/IRGen/DebugTypeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,28 @@
//===----------------------------------------------------------------------===//

#include "DebugTypeInfo.h"
#include "IRGen.h"
#include "FixedTypeInfo.h"
#include "IRGen.h"
#include "swift/SIL/SILGlobalVariable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;
using namespace irgen;

DebugTypeInfo::DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy,
uint64_t SizeInBytes, uint32_t AlignInBytes,
DeclContext *DC)
: DeclCtx(DC), Type(Ty.getPointer()), StorageType(StorageTy),
size(SizeInBytes), align(AlignInBytes) {
assert(StorageType && "StorageType is a nullptr");
assert(align.getValue() != 0);
}

DebugTypeInfo::DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy, Size size,
Alignment align, DeclContext *DC)
: DeclCtx(DC), Type(Ty.getPointer()), StorageType(StorageTy),
size(size), align(align) {
DebugTypeInfo::DebugTypeInfo(DeclContext *DC, swift::Type Ty,
llvm::Type *StorageTy, Size size, Alignment align)
: DeclCtx(DC), Type(Ty.getPointer()), StorageType(StorageTy), size(size),
align(align) {
assert((!isArchetype() || (isArchetype() && DC)) &&
"archetype without a declcontext");
assert(StorageType && "StorageType is a nullptr");
assert(align.getValue() != 0);
}

static void
initFromTypeInfo(Size &size, Alignment &align, llvm::Type *&StorageType,
const TypeInfo &Info) {
StorageType = Info.getStorageType();
DebugTypeInfo DebugTypeInfo::getFromTypeInfo(DeclContext *DC, swift::Type Ty,
const TypeInfo &Info) {
Size size;
if (Info.isFixedSize()) {
const FixedTypeInfo &FixTy = *cast<const FixedTypeInfo>(&Info);
size = FixTy.getFixedSize();
Expand All @@ -53,50 +46,20 @@ initFromTypeInfo(Size &size, Alignment &align, llvm::Type *&StorageType,
// encounter one.
size = Size(0);
}
align = Info.getBestKnownAlignment();
assert(align.getValue() != 0);
assert(StorageType && "StorageType is a nullptr");
}

DebugTypeInfo::DebugTypeInfo(swift::Type Ty, const TypeInfo &Info,
DeclContext *DC)
: DeclCtx(DC), Type(Ty.getPointer()) {
initFromTypeInfo(size, align, StorageType, Info);
return DebugTypeInfo(DC, Ty.getPointer(), Info.getStorageType(), size,
Info.getBestKnownAlignment());
}

DebugTypeInfo::DebugTypeInfo(TypeDecl *Decl, const TypeInfo &Info)
: DeclCtx(Decl->getDeclContext()) {
// Use the sugared version of the type, if there is one.
if (auto AliasDecl = dyn_cast<TypeAliasDecl>(Decl))
Type = AliasDecl->getDeclaredInterfaceType().getPointer();
else
Type = Decl->getInterfaceType().getPointer();

initFromTypeInfo(size, align, StorageType, Info);
}

DebugTypeInfo::DebugTypeInfo(ValueDecl *Decl, llvm::Type *StorageTy, Size size,
Alignment align)
: DeclCtx(Decl->getDeclContext()), StorageType(StorageTy), size(size),
align(align) {
// Use the sugared version of the type, if there is one.
if (auto AliasDecl = dyn_cast<TypeAliasDecl>(Decl))
Type = AliasDecl->getDeclaredInterfaceType().getPointer();
else
Type = Decl->getInterfaceType().getPointer();

assert(StorageType && "StorageType is a nullptr");
assert(align.getValue() != 0);
}
DebugTypeInfo DebugTypeInfo::getLocalVariable(DeclContext *DeclCtx,
VarDecl *Decl, swift::Type Ty,
const TypeInfo &Info,
bool Unwrap) {

DebugTypeInfo::DebugTypeInfo(VarDecl *Decl, swift::Type Ty,
const TypeInfo &Info, bool Unwrap)
: DeclCtx(Decl->getDeclContext()) {
// Prefer the original, potentially sugared version of the type if
// the type hasn't been mucked with by an optimization pass.
auto DeclType = (Decl->hasType()
? Decl->getType()
: DeclCtx->mapTypeIntoContext(Decl->getInterfaceType()));
auto DeclType = Ty;
if (DeclCtx)
DeclType = (Decl->hasType()
? Decl->getType()
: DeclCtx->mapTypeIntoContext(Decl->getInterfaceType()));
auto RealType = Ty;
if (Unwrap) {
DeclType = DeclType->getInOutObjectType();
Expand All @@ -108,27 +71,51 @@ DebugTypeInfo::DebugTypeInfo(VarDecl *Decl, swift::Type Ty,
if (auto DynSelfTy = DeclType->getAs<DynamicSelfType>())
DeclSelfType = DynSelfTy->getSelfType();

if (DeclSelfType->isEqual(RealType) || DeclType->getAs<FunctionType>())
Type = DeclType.getPointer();
else
Type = RealType.getPointer();
// Prefer the original, potentially sugared version of the type if
// the type hasn't been mucked with by an optimization pass.
auto *Type = DeclSelfType->isEqual(RealType) ? DeclType.getPointer()
: RealType.getPointer();
return getFromTypeInfo(DeclCtx, Type, Info);
}

initFromTypeInfo(size, align, StorageType, Info);
DebugTypeInfo DebugTypeInfo::getMetadata(swift::Type Ty, llvm::Type *StorageTy,
Size size, Alignment align) {
DebugTypeInfo DbgTy = {nullptr, Ty.getPointer(), StorageTy, size, align};
assert(!DbgTy.isArchetype() && "type metadata cannot contain an archetype");
return DbgTy;
}

DebugTypeInfo::DebugTypeInfo(VarDecl *Decl, swift::Type Ty,
llvm::Type *StorageTy, Size size, Alignment align)
: DeclCtx(Decl->getDeclContext()), StorageType(StorageTy), size(size),
align(align) {
DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
llvm::Type *StorageTy, Size size,
Alignment align) {
// Prefer the original, potentially sugared version of the type if
// the type hasn't been mucked with by an optimization pass.
auto DeclType = (Decl->hasType()
? Decl->getType()
: DeclCtx->mapTypeIntoContext(Decl->getInterfaceType()));
if (Ty && Decl->getInterfaceType()->isEqual(Ty))
Type = DeclType.getPointer();
else
Type = Ty.getPointer();
auto LowTy = GV->getLoweredType().getSwiftType();
auto *Type = LowTy.getPointer();
if (auto *Decl = GV->getDecl()) {
auto DeclType =
(Decl->hasType() ? Decl->getType()
: Decl->getDeclContext()->mapTypeIntoContext(
Decl->getInterfaceType()));
if (DeclType->isEqual(LowTy))
Type = DeclType.getPointer();
}
DebugTypeInfo DbgTy = {nullptr, Type, StorageTy, size, align};
assert(StorageTy && "StorageType is a nullptr");
assert(!DbgTy.isArchetype() &&
"type of a global var cannot contain an archetype");
assert(align.getValue() != 0);
return DbgTy;
}

DebugTypeInfo DebugTypeInfo::getObjCClass(ClassDecl *theClass,
llvm::Type *StorageType, Size size,
Alignment align) {
DebugTypeInfo DbgTy(nullptr, theClass->getInterfaceType().getPointer(),
StorageType, size, align);
assert(!DbgTy.isArchetype() &&
"type of an objc class cannot contain an archetype");
return DbgTy;
}

static bool typesEqual(Type A, Type B) {
Expand All @@ -141,7 +128,7 @@ static bool typesEqual(Type A, Type B) {

// Tombstone.
auto Tombstone =
llvm::DenseMapInfo<swift::Type>::getTombstoneKey().getPointer();
llvm::DenseMapInfo<swift::Type>::getTombstoneKey().getPointer();
if ((A.getPointer() == Tombstone) || (B.getPointer() == Tombstone))
return false;

Expand All @@ -150,14 +137,11 @@ static bool typesEqual(Type A, Type B) {
}

bool DebugTypeInfo::operator==(DebugTypeInfo T) const {
return typesEqual(getType(), T.getType())
&& size == T.size
&& align == T.align;
return typesEqual(getType(), T.getType()) && size == T.size &&
align == T.align;
}

bool DebugTypeInfo::operator!=(DebugTypeInfo T) const {
return !operator==(T);
}
bool DebugTypeInfo::operator!=(DebugTypeInfo T) const { return !operator==(T); }

TypeDecl *DebugTypeInfo::getDecl() const {
if (auto *N = dyn_cast<NominalType>(Type))
Expand All @@ -172,8 +156,8 @@ TypeDecl *DebugTypeInfo::getDecl() const {
}

void DebugTypeInfo::dump() const {
llvm::errs() << "[Size " << size.getValue()
<< " Alignment " << align.getValue()<<"] ";
llvm::errs() << "[Size " << size.getValue() << " Alignment "
<< align.getValue() << "] ";

getType()->dump();
if (StorageType) {
Expand Down
Loading