blob: 730ee4c438e7e0e241b19b7062af56b66a1742c1 [file] [log] [blame]
Daniel Dunbar072d0bb2010-03-30 22:26:10 +00001//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Daniel Dunbar072d0bb2010-03-30 22:26:10 +00006//
7//===----------------------------------------------------------------------===//
8
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +00009#ifndef LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H
10#define LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H
Daniel Dunbar072d0bb2010-03-30 22:26:10 +000011
Ken Dyckf76759c2011-04-24 10:04:59 +000012#include "clang/AST/CharUnits.h"
Benjamin Kramerff2e3232016-02-02 16:05:18 +000013#include "clang/AST/DeclCXX.h"
Chris Lattner95c664b2011-07-23 10:35:09 +000014#include "clang/Basic/LLVM.h"
15#include "llvm/ADT/DenseMap.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000016#include "llvm/IR/DerivedTypes.h"
Chris Lattner95c664b2011-07-23 10:35:09 +000017
Daniel Dunbar23ee4b72010-03-31 00:11:27 +000018namespace llvm {
Anders Carlsson36e2fa82010-11-24 19:37:16 +000019 class StructType;
Daniel Dunbar23ee4b72010-03-31 00:11:27 +000020}
21
Daniel Dunbar072d0bb2010-03-30 22:26:10 +000022namespace clang {
23namespace CodeGen {
24
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000025/// Structure with information about how a bitfield should be accessed.
Daniel Dunbarb935b932010-04-13 20:58:55 +000026///
Chandler Carruthff0e3a12012-12-06 11:14:44 +000027/// 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 type
29/// as either a sequence of i8 members or a byte array to reserve the number of
30/// bytes touched without forcing any particular alignment beyond the basic
31/// character alignment.
32///
33/// Then accessing a particular bitfield involves converting this byte array
34/// into a single integer of that size (i24 or i40 -- may not be power-of-two
35/// size), loading it, and shifting and masking to extract the particular
36/// subsequence of bits which make up that particular bitfield. This structure
37/// encodes the information used to construct the extraction code sequences.
38/// The CGRecordLayout also has a field index which encodes which byte-sequence
39/// 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 the
49/// bitfield, and the second is the padding out to a 4-byte alignmnet.
50///
51/// %t = type { i8, i8, i8, i8, i8, [3 x i8] }
52///
53/// When generating code to access more_bits, we'll generate something
54/// essentially like this:
55///
56/// define i32 @foo(%t* %base) {
57/// %0 = gep %t* %base, i32 0, i32 3
58/// %2 = load i8* %1
59/// %3 = lshr i8 %2, 3
60/// %4 = and i8 %3, 15
61/// %5 = zext i8 %4 to i32
62/// ret i32 %i
63/// }
64///
65struct CGBitFieldInfo {
66 /// The offset within a contiguous run of bitfields that are represented as
67 /// a single "field" within the LLVM struct type. This offset is in bits.
68 unsigned Offset : 16;
Daniel Dunbarb935b932010-04-13 20:58:55 +000069
Daniel Dunbarbb138452010-04-15 05:09:28 +000070 /// The total size of the bit-field, in bits.
Chandler Carruthff0e3a12012-12-06 11:14:44 +000071 unsigned Size : 15;
Daniel Dunbarbb138452010-04-15 05:09:28 +000072
73 /// Whether the bit-field is signed.
Chandler Carruthff0e3a12012-12-06 11:14:44 +000074 unsigned IsSigned : 1;
Daniel Dunbarb97bff92010-04-12 18:14:18 +000075
Chandler Carruthff0e3a12012-12-06 11:14:44 +000076 /// The storage size in bits which should be used when accessing this
77 /// bitfield.
78 unsigned StorageSize;
Daniel Dunbar9c78d632010-04-15 05:09:32 +000079
Ulrich Weigand03ce2a12015-07-10 17:30:00 +000080 /// The offset of the bitfield storage from the start of the struct.
81 CharUnits StorageOffset;
Daniel Dunbar9c78d632010-04-15 05:09:32 +000082
Chandler Carruthff0e3a12012-12-06 11:14:44 +000083 CGBitFieldInfo()
Ulrich Weigand03ce2a12015-07-10 17:30:00 +000084 : Offset(), Size(), IsSigned(), StorageSize(), StorageOffset() {}
Daniel Dunbar9c78d632010-04-15 05:09:32 +000085
Chandler Carruthff0e3a12012-12-06 11:14:44 +000086 CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned,
Ulrich Weigand03ce2a12015-07-10 17:30:00 +000087 unsigned StorageSize, CharUnits StorageOffset)
Chandler Carruthff0e3a12012-12-06 11:14:44 +000088 : Offset(Offset), Size(Size), IsSigned(IsSigned),
Ulrich Weigand03ce2a12015-07-10 17:30:00 +000089 StorageSize(StorageSize), StorageOffset(StorageOffset) {}
Daniel Dunbarb2b40a42010-04-14 04:07:59 +000090
Chris Lattner62ff6e82011-07-20 07:06:53 +000091 void print(raw_ostream &OS) const;
Daniel Dunbarb97bff92010-04-12 18:14:18 +000092 void dump() const;
Daniel Dunbarc7f9bba2010-09-02 23:53:28 +000093
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000094 /// Given a bit-field decl, build an appropriate helper object for
Daniel Dunbarc7f9bba2010-09-02 23:53:28 +000095 /// accessing that field (which is expected to have the given offset and
96 /// size).
Chandler Carruthff0e3a12012-12-06 11:14:44 +000097 static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types,
98 const FieldDecl *FD,
99 uint64_t Offset, uint64_t Size,
100 uint64_t StorageSize,
Ulrich Weigand03ce2a12015-07-10 17:30:00 +0000101 CharUnits StorageOffset);
Daniel Dunbarcd3d5e72010-04-05 16:20:44 +0000102};
103
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000104/// CGRecordLayout - This class handles struct and union layout info while
105/// lowering AST types to LLVM types.
Daniel Dunbar034299e2010-03-31 01:09:11 +0000106///
107/// These layout objects are only created on demand as IR generation requires.
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000108class CGRecordLayout {
Daniel Dunbar034299e2010-03-31 01:09:11 +0000109 friend class CodeGenTypes;
110
Aaron Ballmanabc18922015-02-15 22:54:08 +0000111 CGRecordLayout(const CGRecordLayout &) = delete;
112 void operator=(const CGRecordLayout &) = delete;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000113
Daniel Dunbar034299e2010-03-31 01:09:11 +0000114private:
John McCall0217dfc22011-02-15 06:40:56 +0000115 /// The LLVM type corresponding to this record layout; used when
116 /// laying it out as a complete object.
Chris Lattnera5f58b02011-07-09 17:41:47 +0000117 llvm::StructType *CompleteObjectType;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000118
John McCall0217dfc22011-02-15 06:40:56 +0000119 /// The LLVM type for the non-virtual part of this record layout;
120 /// used when laying it out as a base subobject.
Chris Lattnera5f58b02011-07-09 17:41:47 +0000121 llvm::StructType *BaseSubobjectType;
Anders Carlssonc1351ca2010-11-09 05:25:47 +0000122
Daniel Dunbar034299e2010-03-31 01:09:11 +0000123 /// Map from (non-bit-field) struct field to the corresponding llvm struct
124 /// type field no. This info is populated by record builder.
125 llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
126
127 /// Map from (bit-field) struct field to the corresponding llvm struct type
128 /// field no. This info is populated by record builder.
Daniel Dunbarcd3d5e72010-04-05 16:20:44 +0000129 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
Daniel Dunbar034299e2010-03-31 01:09:11 +0000130
Anders Carlsson061ca522010-05-18 05:22:06 +0000131 // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
Alp Tokerd4733632013-12-05 04:47:09 +0000132 // map for both virtual and non-virtual bases.
John McCall0217dfc22011-02-15 06:40:56 +0000133 llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
Anders Carlsson061ca522010-05-18 05:22:06 +0000134
John McCall0217dfc22011-02-15 06:40:56 +0000135 /// Map from virtual bases to their field index in the complete object.
136 llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;
137
138 /// False if any direct or indirect subobject of this class, when
139 /// considered as a complete object, requires a non-zero bitpattern
140 /// when zero-initialized.
John McCall614dbdc2010-08-22 21:01:12 +0000141 bool IsZeroInitializable : 1;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000142
John McCall0217dfc22011-02-15 06:40:56 +0000143 /// False if any direct or indirect subobject of this class, when
144 /// considered as a base subobject, requires a non-zero bitpattern
145 /// when zero-initialized.
146 bool IsZeroInitializableAsBase : 1;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000147
John McCall0217dfc22011-02-15 06:40:56 +0000148public:
Chris Lattnera5f58b02011-07-09 17:41:47 +0000149 CGRecordLayout(llvm::StructType *CompleteObjectType,
150 llvm::StructType *BaseSubobjectType,
John McCall0217dfc22011-02-15 06:40:56 +0000151 bool IsZeroInitializable,
152 bool IsZeroInitializableAsBase)
153 : CompleteObjectType(CompleteObjectType),
154 BaseSubobjectType(BaseSubobjectType),
155 IsZeroInitializable(IsZeroInitializable),
156 IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}
157
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000158 /// Return the "complete object" LLVM type associated with
John McCall0217dfc22011-02-15 06:40:56 +0000159 /// this record.
Chris Lattnera5f58b02011-07-09 17:41:47 +0000160 llvm::StructType *getLLVMType() const {
161 return CompleteObjectType;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000162 }
163
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000164 /// Return the "base subobject" LLVM type associated with
John McCall0217dfc22011-02-15 06:40:56 +0000165 /// this record.
Chris Lattnera5f58b02011-07-09 17:41:47 +0000166 llvm::StructType *getBaseSubobjectLLVMType() const {
167 return BaseSubobjectType;
Anders Carlssonc1351ca2010-11-09 05:25:47 +0000168 }
169
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000170 /// Check whether this struct can be C++ zero-initialized
John McCall614dbdc2010-08-22 21:01:12 +0000171 /// with a zeroinitializer.
172 bool isZeroInitializable() const {
173 return IsZeroInitializable;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000174 }
Daniel Dunbar034299e2010-03-31 01:09:11 +0000175
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000176 /// Check whether this struct can be C++ zero-initialized
John McCall0217dfc22011-02-15 06:40:56 +0000177 /// with a zeroinitializer when considered as a base subobject.
178 bool isZeroInitializableAsBase() const {
179 return IsZeroInitializableAsBase;
180 }
181
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000182 /// Return llvm::StructType element number that corresponds to the
Daniel Dunbar19d63552010-04-27 14:51:07 +0000183 /// field FD.
Daniel Dunbar034299e2010-03-31 01:09:11 +0000184 unsigned getLLVMFieldNo(const FieldDecl *FD) const {
Richard Smithcd45dbc2014-04-19 03:48:30 +0000185 FD = FD->getCanonicalDecl();
Daniel Dunbar034299e2010-03-31 01:09:11 +0000186 assert(FieldInfo.count(FD) && "Invalid field for record!");
187 return FieldInfo.lookup(FD);
188 }
189
Anders Carlsson061ca522010-05-18 05:22:06 +0000190 unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
John McCall0217dfc22011-02-15 06:40:56 +0000191 assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");
192 return NonVirtualBases.lookup(RD);
193 }
194
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000195 /// Return the LLVM field index corresponding to the given
John McCall0217dfc22011-02-15 06:40:56 +0000196 /// virtual base. Only valid when operating on the complete object.
197 unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {
198 assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");
199 return CompleteObjectVirtualBases.lookup(base);
Anders Carlsson061ca522010-05-18 05:22:06 +0000200 }
201
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000202 /// Return the BitFieldInfo that corresponds to the field FD.
Daniel Dunbarcd3d5e72010-04-05 16:20:44 +0000203 const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
Richard Smithcd45dbc2014-04-19 03:48:30 +0000204 FD = FD->getCanonicalDecl();
Alp Tokerd4733632013-12-05 04:47:09 +0000205 assert(FD->isBitField() && "Invalid call for non-bit-field decl!");
Daniel Dunbarcd3d5e72010-04-05 16:20:44 +0000206 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
Daniel Dunbar034299e2010-03-31 01:09:11 +0000207 it = BitFields.find(FD);
John McCall0217dfc22011-02-15 06:40:56 +0000208 assert(it != BitFields.end() && "Unable to find bitfield info");
Daniel Dunbar034299e2010-03-31 01:09:11 +0000209 return it->second;
210 }
Daniel Dunbarb97bff92010-04-12 18:14:18 +0000211
Chris Lattner62ff6e82011-07-20 07:06:53 +0000212 void print(raw_ostream &OS) const;
Daniel Dunbarb97bff92010-04-12 18:14:18 +0000213 void dump() const;
Daniel Dunbar072d0bb2010-03-30 22:26:10 +0000214};
215
216} // end namespace CodeGen
217} // end namespace clang
218
219#endif