| //===--- DebugTypeInfo.h - Type Info for Debugging --------------*- C++ -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://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. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_IRGEN_DEBUGTYPEINFO_H |
| #define SWIFT_IRGEN_DEBUGTYPEINFO_H |
| |
| #include "IRGen.h" |
| #include "swift/AST/Decl.h" |
| #include "swift/AST/Types.h" |
| |
| namespace llvm { |
| class Type; |
| } |
| |
| namespace swift { |
| class SILDebugScope; |
| class SILGlobalVariable; |
| |
| namespace irgen { |
| class TypeInfo; |
| |
| /// This data structure holds everything needed to emit debug info |
| /// for a type. |
| class DebugTypeInfo { |
| public: |
| /// The DeclContext of the function. This might not be the DeclContext of |
| /// the variable if inlining took place. |
| DeclContext *DeclCtx = nullptr; |
| |
| /// The generic environment of the type. Ideally we should need only this and |
| /// retire the DeclCtxt. |
| GenericEnvironment *GenericEnv = nullptr; |
| |
| /// The type we need to emit may be different from the type |
| /// mentioned in the Decl, for example, stripped of qualifiers. |
| TypeBase *Type = nullptr; |
| /// Needed to determine the size of basic types and to determine |
| /// the storage type for undefined variables. |
| llvm::Type *StorageType = nullptr; |
| Size size = Size(0); |
| Alignment align = Alignment(0); |
| bool DefaultAlignment = true; |
| |
| DebugTypeInfo() {} |
| DebugTypeInfo(DeclContext *DC, GenericEnvironment *GE, swift::Type Ty, |
| llvm::Type *StorageTy, Size SizeInBytes, Alignment AlignInBytes, |
| bool HasDefaultAlignment); |
| /// Create type for a local variable. |
| static DebugTypeInfo getLocalVariable(DeclContext *DeclCtx, |
| GenericEnvironment *GE, VarDecl *Decl, |
| swift::Type Ty, const TypeInfo &Info, |
| bool Unwrap); |
| /// Create type for an artificial metadata variable. |
| static DebugTypeInfo getMetadata(swift::Type Ty, llvm::Type *StorageTy, |
| Size size, Alignment align); |
| /// Create a standalone type from a TypeInfo object. |
| static DebugTypeInfo getFromTypeInfo(DeclContext *DC, GenericEnvironment *GE, |
| swift::Type Ty, const TypeInfo &Info); |
| /// Global variables. |
| static DebugTypeInfo getGlobal(SILGlobalVariable *GV, llvm::Type *StorageType, |
| Size size, Alignment align); |
| /// ObjC classes. |
| static DebugTypeInfo getObjCClass(ClassDecl *theClass, |
| llvm::Type *StorageType, Size size, |
| Alignment align); |
| |
| TypeBase *getType() const { return Type; } |
| |
| TypeDecl *getDecl() const; |
| DeclContext *getDeclContext() const { return DeclCtx; } |
| GenericEnvironment *getGenericEnvironment() const { return GenericEnv; } |
| |
| void unwrapLValueOrInOutType() { |
| Type = Type->getWithoutSpecifierType().getPointer(); |
| } |
| |
| // Determine whether this type is an Archetype itself. |
| bool isArchetype() const { |
| return Type->getWithoutSpecifierType()->is<ArchetypeType>(); |
| } |
| |
| /// LValues, inout args, and Archetypes are implicitly indirect by |
| /// virtue of their DWARF type. |
| // |
| // FIXME: Should this check if the lowered SILType is address only |
| // instead? Otherwise optionals of archetypes etc will still have |
| // 'isImplicitlyIndirect()' return false. |
| bool isImplicitlyIndirect() const { |
| return Type->hasLValueType() || isArchetype() || Type->is<InOutType>(); |
| } |
| |
| bool isNull() const { return Type == nullptr; } |
| bool operator==(DebugTypeInfo T) const; |
| bool operator!=(DebugTypeInfo T) const; |
| |
| void dump() const; |
| }; |
| } |
| } |
| |
| namespace llvm { |
| |
| // Dense map specialization. |
| template <> struct DenseMapInfo<swift::irgen::DebugTypeInfo> { |
| static swift::irgen::DebugTypeInfo getEmptyKey() { |
| return {}; |
| } |
| static swift::irgen::DebugTypeInfo getTombstoneKey() { |
| return swift::irgen::DebugTypeInfo( |
| nullptr, nullptr, |
| llvm::DenseMapInfo<swift::TypeBase *>::getTombstoneKey(), nullptr, |
| swift::irgen::Size(0), swift::irgen::Alignment(0), false); |
| } |
| static unsigned getHashValue(swift::irgen::DebugTypeInfo Val) { |
| return DenseMapInfo<swift::CanType>::getHashValue(Val.getType()); |
| } |
| static bool isEqual(swift::irgen::DebugTypeInfo LHS, |
| swift::irgen::DebugTypeInfo RHS) { |
| return LHS == RHS; |
| } |
| }; |
| } |
| |
| #endif |