blob: eb60ed7b5b1dd1945d71ffb49112f5085e88649b [file] [log] [blame]
Anders Carlsson45372a62009-07-23 03:17:50 +00001//===--- CGRecordLayoutBuilder.h - Record builder helper --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is a helper class used to build CGRecordLayout objects and LLVM types.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
15#define CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
16
17#include "llvm/ADT/SmallVector.h"
Chandler Carruth9f8eb202009-10-26 01:37:10 +000018#include "llvm/System/DataTypes.h"
Anders Carlsson45372a62009-07-23 03:17:50 +000019#include <vector>
20
21namespace llvm {
22 class Type;
23}
24
25namespace clang {
Anders Carlsson4b3e5be2009-12-16 17:27:20 +000026 class ASTRecordLayout;
27 class CXXRecordDecl;
Anders Carlsson45372a62009-07-23 03:17:50 +000028 class FieldDecl;
29 class RecordDecl;
Anders Carlsson2c12d032010-02-02 05:17:25 +000030 class QualType;
Mike Stump1eb44332009-09-09 15:08:12 +000031
Anders Carlsson45372a62009-07-23 03:17:50 +000032namespace CodeGen {
33 class CGRecordLayout;
34 class CodeGenTypes;
35
Mike Stump1eb44332009-09-09 15:08:12 +000036class CGRecordLayoutBuilder {
Anders Carlsson45372a62009-07-23 03:17:50 +000037 CodeGenTypes &Types;
Mike Stump1eb44332009-09-09 15:08:12 +000038
Anders Carlsson4b5584b2009-07-23 17:24:40 +000039 /// Packed - Whether the resulting LLVM struct will be packed or not.
40 bool Packed;
Anders Carlsson45372a62009-07-23 03:17:50 +000041
Anders Carlsson2c12d032010-02-02 05:17:25 +000042 /// ContainsPointerToDataMember - Whether one of the fields in this record
43 /// layout is a pointer to data member, or a struct that contains pointer to
44 /// data member.
45 bool ContainsPointerToDataMember;
Mike Stump1eb44332009-09-09 15:08:12 +000046
Anders Carlssona5dd7222009-08-08 19:38:24 +000047 /// Alignment - Contains the alignment of the RecordDecl.
48 unsigned Alignment;
49
Anders Carlsson45372a62009-07-23 03:17:50 +000050 /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
51 /// LLVM types.
52 unsigned AlignmentAsLLVMStruct;
Mike Stump1eb44332009-09-09 15:08:12 +000053
Anders Carlsson45372a62009-07-23 03:17:50 +000054 /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
55 /// this will have the number of bits still available in the field.
56 char BitsAvailableInLastField;
Anders Carlssonc2cc1d52009-07-28 17:56:36 +000057
58 /// NextFieldOffsetInBytes - Holds the next field offset in bytes.
59 uint64_t NextFieldOffsetInBytes;
Mike Stump1eb44332009-09-09 15:08:12 +000060
Anders Carlsson45372a62009-07-23 03:17:50 +000061 /// FieldTypes - Holds the LLVM types that the struct is created from.
62 std::vector<const llvm::Type *> FieldTypes;
Mike Stump1eb44332009-09-09 15:08:12 +000063
Anders Carlsson45372a62009-07-23 03:17:50 +000064 /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
65 typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
66 llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
67
68 /// LLVMBitFieldInfo - Holds location and size information about a bit field.
69 struct LLVMBitFieldInfo {
Mike Stump1eb44332009-09-09 15:08:12 +000070 LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
Anders Carlsson8330cee2009-07-23 17:01:21 +000071 unsigned Size)
72 : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
Mike Stump1eb44332009-09-09 15:08:12 +000073
Anders Carlsson45372a62009-07-23 03:17:50 +000074 const FieldDecl *FD;
Mike Stump1eb44332009-09-09 15:08:12 +000075
Anders Carlsson8330cee2009-07-23 17:01:21 +000076 unsigned FieldNo;
Anders Carlsson45372a62009-07-23 03:17:50 +000077 unsigned Start;
78 unsigned Size;
79 };
80 llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
Mike Stump1eb44332009-09-09 15:08:12 +000081
82 CGRecordLayoutBuilder(CodeGenTypes &Types)
Anders Carlsson2c12d032010-02-02 05:17:25 +000083 : Types(Types), Packed(false), ContainsPointerToDataMember(false)
Anders Carlssonfc3eaa42009-08-23 01:25:01 +000084 , Alignment(0), AlignmentAsLLVMStruct(1)
Anders Carlssonc2cc1d52009-07-28 17:56:36 +000085 , BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
Anders Carlsson45372a62009-07-23 03:17:50 +000086
87 /// Layout - Will layout a RecordDecl.
88 void Layout(const RecordDecl *D);
89
Anders Carlsson5a6e3982009-07-23 03:43:54 +000090 /// LayoutUnion - Will layout a union RecordDecl.
91 void LayoutUnion(const RecordDecl *D);
Mike Stump1eb44332009-09-09 15:08:12 +000092
Anders Carlsson45372a62009-07-23 03:17:50 +000093 /// LayoutField - try to layout all fields in the record decl.
94 /// Returns false if the operation failed because the struct is not packed.
95 bool LayoutFields(const RecordDecl *D);
Mike Stump1eb44332009-09-09 15:08:12 +000096
Anders Carlsson4b3e5be2009-12-16 17:27:20 +000097 /// LayoutBases - layout the bases and vtable pointer of a record decl.
98 void LayoutBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout);
99
Anders Carlsson45372a62009-07-23 03:17:50 +0000100 /// LayoutField - layout a single field. Returns false if the operation failed
101 /// because the current struct is not packed.
102 bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
Mike Stump1eb44332009-09-09 15:08:12 +0000103
Anders Carlsson45372a62009-07-23 03:17:50 +0000104 /// LayoutBitField - layout a single bit field.
105 void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
106
Anders Carlsson728d7cd2009-07-24 02:45:50 +0000107 /// AppendField - Appends a field with the given offset and type.
108 void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
Anders Carlsson45372a62009-07-23 03:17:50 +0000109
110 /// AppendPadding - Appends enough padding bytes so that the total struct
111 /// size matches the alignment of the passed in type.
112 void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
113
114 /// AppendPadding - Appends enough padding bytes so that the total
115 /// struct size is a multiple of the field alignment.
116 void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
Mike Stump1eb44332009-09-09 15:08:12 +0000117
Anders Carlsson45372a62009-07-23 03:17:50 +0000118 /// AppendBytes - Append a given number of bytes to the record.
119 void AppendBytes(uint64_t NumBytes);
120
Anders Carlssonc1efe362009-07-27 14:55:54 +0000121 /// AppendTailPadding - Append enough tail padding so that the type will have
122 /// the passed size.
123 void AppendTailPadding(uint64_t RecordSize);
Mike Stump1eb44332009-09-09 15:08:12 +0000124
Anders Carlsson45372a62009-07-23 03:17:50 +0000125 unsigned getTypeAlignment(const llvm::Type *Ty) const;
126 uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
127
Anders Carlsson2c12d032010-02-02 05:17:25 +0000128 /// CheckForPointerToDataMember - Check if the given type contains a pointer
129 /// to data member.
130 void CheckForPointerToDataMember(QualType T);
Mike Stump1eb44332009-09-09 15:08:12 +0000131
Anders Carlsson45372a62009-07-23 03:17:50 +0000132public:
133 /// ComputeLayout - Return the right record layout for a given record decl.
Mike Stump1eb44332009-09-09 15:08:12 +0000134 static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
Anders Carlsson45372a62009-07-23 03:17:50 +0000135 const RecordDecl *D);
136};
Mike Stump1eb44332009-09-09 15:08:12 +0000137
Anders Carlsson45372a62009-07-23 03:17:50 +0000138} // end namespace CodeGen
139} // end namespace clang
Anders Carlsson45372a62009-07-23 03:17:50 +0000140
Mike Stump1eb44332009-09-09 15:08:12 +0000141
142#endif