blob: 0bbbd95cb4c9866b7d6d7fa5a886f4ec5b2afbb0 [file] [log] [blame]
//===--- DebugTypeInfo.h - Type Info for Debugging --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the data structure that holds all the debug info
// we want to emit for types.
//
//===----------------------------------------------------------------------===//
#include "DebugTypeInfo.h"
#include "IRGen.h"
#include "FixedTypeInfo.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)
: DeclOrContext(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)
: DeclOrContext(DC),
Type(Ty.getPointer()),
StorageType(StorageTy),
size(size),
align(align) {
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();
if (Info.isFixedSize()) {
const FixedTypeInfo &FixTy = *cast<const FixedTypeInfo>(&Info);
size = FixTy.getFixedSize();
} else {
// FIXME: Handle NonFixedTypeInfo here or assert that we won't
// 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)
: DeclOrContext(DC),
Type(Ty.getPointer()) {
initFromTypeInfo(size, align, StorageType, Info);
}
DebugTypeInfo::DebugTypeInfo(ValueDecl *Decl, const TypeInfo &Info)
: DeclOrContext(Decl) {
// Use the sugared version of the type, if there is one.
if (auto AliasDecl = dyn_cast<TypeAliasDecl>(Decl))
Type = AliasDecl->getAliasType();
else
Type = Decl->getType().getPointer();
initFromTypeInfo(size, align, StorageType, Info);
}
DebugTypeInfo::DebugTypeInfo(ValueDecl *Decl, llvm::Type *StorageTy,
Size size, Alignment align)
: DeclOrContext(Decl),
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->getAliasType();
else
Type = Decl->getType().getPointer();
assert(StorageType && "StorageType is a nullptr");
assert(align.getValue() != 0);
}
DebugTypeInfo::DebugTypeInfo(ValueDecl *Decl, swift::Type Ty,
const TypeInfo &Info)
: DeclOrContext(Decl) {
// Prefer the original, potentially sugared version of the type if
// the type hasn't been mucked with by an optimization pass.
if (Decl->getType().getCanonicalTypeOrNull() == Ty.getCanonicalTypeOrNull())
Type = Decl->getType().getPointer();
else
Type = Ty.getPointer();
initFromTypeInfo(size, align, StorageType, Info);
}
static bool typesEqual(Type A, Type B) {
if (A.getPointer() == B.getPointer())
return true;
// nullptr.
if (A.isNull() || B.isNull())
return false;
// Tombstone.
auto Tombstone =
llvm::DenseMapInfo<swift::Type>::getTombstoneKey().getPointer();
if ((A.getPointer() == Tombstone) || (B.getPointer() == Tombstone))
return false;
// Pointers are safe, do the real comparison.
return A->isSpelledLike(B.getPointer());
}
bool DebugTypeInfo::operator==(DebugTypeInfo T) const {
return typesEqual(getType(), T.getType())
&& size == T.size
&& align == T.align;
}
bool DebugTypeInfo::operator!=(DebugTypeInfo T) const {
return !operator==(T);
}
void DebugTypeInfo::dump() const {
llvm::errs() << "[Size " << size.getValue()
<< " Alignment " << align.getValue()<<"] ";
if (getDecl())
getDecl()->dump(llvm::errs());
else
getType()->dump();
if (StorageType) {
llvm::errs() << "StorageType=";
StorageType->dump();
}
}