244 lines · c
1//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H10#define LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H11 12#include "clang/AST/CharUnits.h"13#include "clang/AST/DeclCXX.h"14#include "clang/Basic/LLVM.h"15#include "llvm/ADT/DenseMap.h"16#include "llvm/IR/DerivedTypes.h"17 18namespace llvm {19 class StructType;20}21 22namespace clang {23namespace CodeGen {24 25/// Structure with information about how a bitfield should be accessed.26///27/// Often we layout a sequence of bitfields as a contiguous sequence of bits.28/// When the AST record layout does this, we represent it in the LLVM IR's type29/// as either a sequence of i8 members or a byte array to reserve the number of30/// bytes touched without forcing any particular alignment beyond the basic31/// character alignment.32///33/// Then accessing a particular bitfield involves converting this byte array34/// into a single integer of that size (i24 or i40 -- may not be power-of-two35/// size), loading it, and shifting and masking to extract the particular36/// subsequence of bits which make up that particular bitfield. This structure37/// encodes the information used to construct the extraction code sequences.38/// The CGRecordLayout also has a field index which encodes which byte-sequence39/// this bitfield falls within. Let's assume the following C struct:40///41/// struct S {42/// char a, b, c;43/// unsigned bits : 3;44/// unsigned more_bits : 4;45/// unsigned still_more_bits : 7;46/// };47///48/// This will end up as the following LLVM type. The first array is the49/// bitfield, and the second is the padding out to a 4-byte alignment.50///51/// %t = type { i8, i8, i8, i8, i8, [3 x i8] }52///53/// When generating code to access more_bits, we'll generate something54/// essentially like this:55///56/// define i32 @foo(%t* %base) {57/// %0 = gep %t* %base, i32 0, i32 358/// %2 = load i8* %159/// %3 = lshr i8 %2, 360/// %4 = and i8 %3, 1561/// %5 = zext i8 %4 to i3262/// ret i32 %i63/// }64///65struct CGBitFieldInfo {66 /// The offset within a contiguous run of bitfields that are represented as67 /// a single "field" within the LLVM struct type. This offset is in bits.68 unsigned Offset : 16;69 70 /// The total size of the bit-field, in bits.71 unsigned Size : 15;72 73 /// Whether the bit-field is signed.74 LLVM_PREFERRED_TYPE(bool)75 unsigned IsSigned : 1;76 77 /// The storage size in bits which should be used when accessing this78 /// bitfield.79 unsigned StorageSize;80 81 /// The offset of the bitfield storage from the start of the struct.82 CharUnits StorageOffset;83 84 /// The offset within a contiguous run of bitfields that are represented as a85 /// single "field" within the LLVM struct type, taking into account the AAPCS86 /// rules for volatile bitfields. This offset is in bits.87 unsigned VolatileOffset : 16;88 89 /// The storage size in bits which should be used when accessing this90 /// bitfield.91 unsigned VolatileStorageSize;92 93 /// The offset of the bitfield storage from the start of the struct.94 CharUnits VolatileStorageOffset;95 96 CGBitFieldInfo()97 : Offset(), Size(), IsSigned(), StorageSize(), VolatileOffset(),98 VolatileStorageSize() {}99 100 CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned,101 unsigned StorageSize, CharUnits StorageOffset)102 : Offset(Offset), Size(Size), IsSigned(IsSigned),103 StorageSize(StorageSize), StorageOffset(StorageOffset) {}104 105 void print(raw_ostream &OS) const;106 void dump() const;107 108 /// Given a bit-field decl, build an appropriate helper object for109 /// accessing that field (which is expected to have the given offset and110 /// size).111 static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types,112 const FieldDecl *FD,113 uint64_t Offset, uint64_t Size,114 uint64_t StorageSize,115 CharUnits StorageOffset);116};117 118/// CGRecordLayout - This class handles struct and union layout info while119/// lowering AST types to LLVM types.120///121/// These layout objects are only created on demand as IR generation requires.122class CGRecordLayout {123 friend class CodeGenTypes;124 125 CGRecordLayout(const CGRecordLayout &) = delete;126 void operator=(const CGRecordLayout &) = delete;127 128private:129 /// The LLVM type corresponding to this record layout; used when130 /// laying it out as a complete object.131 llvm::StructType *CompleteObjectType;132 133 /// The LLVM type for the non-virtual part of this record layout;134 /// used when laying it out as a base subobject.135 llvm::StructType *BaseSubobjectType;136 137 /// Map from (non-bit-field) struct field to the corresponding llvm struct138 /// type field no. This info is populated by record builder.139 llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;140 141 /// Map from (bit-field) struct field to the corresponding llvm struct type142 /// field no. This info is populated by record builder.143 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;144 145 // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single146 // map for both virtual and non-virtual bases.147 llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;148 149 /// Map from virtual bases to their field index in the complete object.150 llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;151 152 /// False if any direct or indirect subobject of this class, when153 /// considered as a complete object, requires a non-zero bitpattern154 /// when zero-initialized.155 bool IsZeroInitializable : 1;156 157 /// False if any direct or indirect subobject of this class, when158 /// considered as a base subobject, requires a non-zero bitpattern159 /// when zero-initialized.160 bool IsZeroInitializableAsBase : 1;161 162public:163 CGRecordLayout(llvm::StructType *CompleteObjectType,164 llvm::StructType *BaseSubobjectType,165 bool IsZeroInitializable,166 bool IsZeroInitializableAsBase)167 : CompleteObjectType(CompleteObjectType),168 BaseSubobjectType(BaseSubobjectType),169 IsZeroInitializable(IsZeroInitializable),170 IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}171 172 /// Return the "complete object" LLVM type associated with173 /// this record.174 llvm::StructType *getLLVMType() const {175 return CompleteObjectType;176 }177 178 /// Return the "base subobject" LLVM type associated with179 /// this record.180 llvm::StructType *getBaseSubobjectLLVMType() const {181 return BaseSubobjectType;182 }183 184 /// Check whether this struct can be C++ zero-initialized185 /// with a zeroinitializer.186 bool isZeroInitializable() const {187 return IsZeroInitializable;188 }189 190 /// Check whether this struct can be C++ zero-initialized191 /// with a zeroinitializer when considered as a base subobject.192 bool isZeroInitializableAsBase() const {193 return IsZeroInitializableAsBase;194 }195 196 bool containsFieldDecl(const FieldDecl *FD) const {197 return FieldInfo.count(FD) != 0;198 }199 200 /// Return llvm::StructType element number that corresponds to the201 /// field FD.202 unsigned getLLVMFieldNo(const FieldDecl *FD) const {203 FD = FD->getCanonicalDecl();204 assert(FieldInfo.count(FD) && "Invalid field for record!");205 return FieldInfo.lookup(FD);206 }207 208 // Return whether the following non virtual base has a corresponding209 // entry in the LLVM struct.210 bool hasNonVirtualBaseLLVMField(const CXXRecordDecl *RD) const {211 return NonVirtualBases.count(RD);212 }213 214 unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {215 assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");216 return NonVirtualBases.lookup(RD);217 }218 219 /// Return the LLVM field index corresponding to the given220 /// virtual base. Only valid when operating on the complete object.221 unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {222 assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");223 return CompleteObjectVirtualBases.lookup(base);224 }225 226 /// Return the BitFieldInfo that corresponds to the field FD.227 const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {228 FD = FD->getCanonicalDecl();229 assert(FD->isBitField() && "Invalid call for non-bit-field decl!");230 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator231 it = BitFields.find(FD);232 assert(it != BitFields.end() && "Unable to find bitfield info");233 return it->second;234 }235 236 void print(raw_ostream &OS) const;237 void dump() const;238};239 240} // end namespace CodeGen241} // end namespace clang242 243#endif244