blob: cf84053e190788b260b1d5b3e04951284b450b8d [file] [log] [blame]
Anders Carlsson307846f2009-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 Carrutha3f084c2009-10-26 01:37:10 +000018#include "llvm/System/DataTypes.h"
Anders Carlsson307846f2009-07-23 03:17:50 +000019#include <vector>
20
21namespace llvm {
22 class Type;
23}
24
25namespace clang {
Anders Carlssond681a292009-12-16 17:27:20 +000026 class ASTRecordLayout;
27 class CXXRecordDecl;
Anders Carlsson307846f2009-07-23 03:17:50 +000028 class FieldDecl;
29 class RecordDecl;
Mike Stump11289f42009-09-09 15:08:12 +000030
Anders Carlsson307846f2009-07-23 03:17:50 +000031namespace CodeGen {
32 class CGRecordLayout;
33 class CodeGenTypes;
34
Mike Stump11289f42009-09-09 15:08:12 +000035class CGRecordLayoutBuilder {
Anders Carlsson307846f2009-07-23 03:17:50 +000036 CodeGenTypes &Types;
Mike Stump11289f42009-09-09 15:08:12 +000037
Anders Carlssond78fc892009-07-23 17:24:40 +000038 /// Packed - Whether the resulting LLVM struct will be packed or not.
39 bool Packed;
Anders Carlsson307846f2009-07-23 03:17:50 +000040
Anders Carlssond606de72009-08-23 01:25:01 +000041 /// ContainsMemberPointer - Whether one of the fields is a member pointer
42 /// or is a struct that contains a member pointer.
43 bool ContainsMemberPointer;
Mike Stump11289f42009-09-09 15:08:12 +000044
Anders Carlsson28a5fa22009-08-08 19:38:24 +000045 /// Alignment - Contains the alignment of the RecordDecl.
46 unsigned Alignment;
47
Anders Carlsson307846f2009-07-23 03:17:50 +000048 /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
49 /// LLVM types.
50 unsigned AlignmentAsLLVMStruct;
Mike Stump11289f42009-09-09 15:08:12 +000051
Anders Carlsson307846f2009-07-23 03:17:50 +000052 /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
53 /// this will have the number of bits still available in the field.
54 char BitsAvailableInLastField;
Anders Carlssond5d64132009-07-28 17:56:36 +000055
56 /// NextFieldOffsetInBytes - Holds the next field offset in bytes.
57 uint64_t NextFieldOffsetInBytes;
Mike Stump11289f42009-09-09 15:08:12 +000058
Anders Carlsson307846f2009-07-23 03:17:50 +000059 /// FieldTypes - Holds the LLVM types that the struct is created from.
60 std::vector<const llvm::Type *> FieldTypes;
Mike Stump11289f42009-09-09 15:08:12 +000061
Anders Carlsson307846f2009-07-23 03:17:50 +000062 /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
63 typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
64 llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
65
66 /// LLVMBitFieldInfo - Holds location and size information about a bit field.
67 struct LLVMBitFieldInfo {
Mike Stump11289f42009-09-09 15:08:12 +000068 LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
Anders Carlsson8af896c2009-07-23 17:01:21 +000069 unsigned Size)
70 : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
Mike Stump11289f42009-09-09 15:08:12 +000071
Anders Carlsson307846f2009-07-23 03:17:50 +000072 const FieldDecl *FD;
Mike Stump11289f42009-09-09 15:08:12 +000073
Anders Carlsson8af896c2009-07-23 17:01:21 +000074 unsigned FieldNo;
Anders Carlsson307846f2009-07-23 03:17:50 +000075 unsigned Start;
76 unsigned Size;
77 };
78 llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
Mike Stump11289f42009-09-09 15:08:12 +000079
80 CGRecordLayoutBuilder(CodeGenTypes &Types)
Anders Carlssond606de72009-08-23 01:25:01 +000081 : Types(Types), Packed(false), ContainsMemberPointer(false)
82 , Alignment(0), AlignmentAsLLVMStruct(1)
Anders Carlssond5d64132009-07-28 17:56:36 +000083 , BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }
Anders Carlsson307846f2009-07-23 03:17:50 +000084
85 /// Layout - Will layout a RecordDecl.
86 void Layout(const RecordDecl *D);
87
Anders Carlsson697f6592009-07-23 03:43:54 +000088 /// LayoutUnion - Will layout a union RecordDecl.
89 void LayoutUnion(const RecordDecl *D);
Mike Stump11289f42009-09-09 15:08:12 +000090
Anders Carlsson307846f2009-07-23 03:17:50 +000091 /// LayoutField - try to layout all fields in the record decl.
92 /// Returns false if the operation failed because the struct is not packed.
93 bool LayoutFields(const RecordDecl *D);
Mike Stump11289f42009-09-09 15:08:12 +000094
Anders Carlssond681a292009-12-16 17:27:20 +000095 /// LayoutBases - layout the bases and vtable pointer of a record decl.
96 void LayoutBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout);
97
Anders Carlsson307846f2009-07-23 03:17:50 +000098 /// LayoutField - layout a single field. Returns false if the operation failed
99 /// because the current struct is not packed.
100 bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
Mike Stump11289f42009-09-09 15:08:12 +0000101
Anders Carlsson307846f2009-07-23 03:17:50 +0000102 /// LayoutBitField - layout a single bit field.
103 void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
104
Anders Carlsson6e853bf2009-07-24 02:45:50 +0000105 /// AppendField - Appends a field with the given offset and type.
106 void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
Anders Carlsson307846f2009-07-23 03:17:50 +0000107
108 /// AppendPadding - Appends enough padding bytes so that the total struct
109 /// size matches the alignment of the passed in type.
110 void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);
111
112 /// AppendPadding - Appends enough padding bytes so that the total
113 /// struct size is a multiple of the field alignment.
114 void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);
Mike Stump11289f42009-09-09 15:08:12 +0000115
Anders Carlsson307846f2009-07-23 03:17:50 +0000116 /// AppendBytes - Append a given number of bytes to the record.
117 void AppendBytes(uint64_t NumBytes);
118
Anders Carlssonb97a3ec2009-07-27 14:55:54 +0000119 /// AppendTailPadding - Append enough tail padding so that the type will have
120 /// the passed size.
121 void AppendTailPadding(uint64_t RecordSize);
Mike Stump11289f42009-09-09 15:08:12 +0000122
Anders Carlsson307846f2009-07-23 03:17:50 +0000123 unsigned getTypeAlignment(const llvm::Type *Ty) const;
124 uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;
125
Anders Carlssond606de72009-08-23 01:25:01 +0000126 /// CheckForMemberPointer - Check if the field contains a member pointer.
127 void CheckForMemberPointer(const FieldDecl *FD);
Mike Stump11289f42009-09-09 15:08:12 +0000128
Anders Carlsson307846f2009-07-23 03:17:50 +0000129public:
130 /// ComputeLayout - Return the right record layout for a given record decl.
Mike Stump11289f42009-09-09 15:08:12 +0000131 static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
Anders Carlsson307846f2009-07-23 03:17:50 +0000132 const RecordDecl *D);
133};
Mike Stump11289f42009-09-09 15:08:12 +0000134
Anders Carlsson307846f2009-07-23 03:17:50 +0000135} // end namespace CodeGen
136} // end namespace clang
Anders Carlsson307846f2009-07-23 03:17:50 +0000137
Mike Stump11289f42009-09-09 15:08:12 +0000138
139#endif