summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGRecordLayoutBuilder.h
blob: eb60ed7b5b1dd1945d71ffb49112f5085e88649b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//===--- CGRecordLayoutBuilder.h - Record builder helper --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a helper class used to build CGRecordLayout objects and LLVM types.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H
#define CLANG_CODEGEN_CGRECORDLAYOUTBUILDER_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/System/DataTypes.h"
#include <vector>

namespace llvm {
  class Type;
}

namespace clang {
  class ASTRecordLayout;
  class CXXRecordDecl;
  class FieldDecl;
  class RecordDecl;
  class QualType;

namespace CodeGen {
  class CGRecordLayout;
  class CodeGenTypes;

class CGRecordLayoutBuilder {
  CodeGenTypes &Types;

  /// Packed - Whether the resulting LLVM struct will be packed or not.
  bool Packed;

  /// ContainsPointerToDataMember - Whether one of the fields in this record 
  /// layout is a pointer to data member, or a struct that contains pointer to
  /// data member.
  bool ContainsPointerToDataMember;

  /// Alignment - Contains the alignment of the RecordDecl.
  unsigned Alignment;

  /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
  /// LLVM types.
  unsigned AlignmentAsLLVMStruct;

  /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
  /// this will have the number of bits still available in the field.
  char BitsAvailableInLastField;

  /// NextFieldOffsetInBytes - Holds the next field offset in bytes.
  uint64_t NextFieldOffsetInBytes;

  /// FieldTypes - Holds the LLVM types that the struct is created from.
  std::vector<const llvm::Type *> FieldTypes;

  /// LLVMFieldInfo - Holds a field and its corresponding LLVM field number.
  typedef std::pair<const FieldDecl *, unsigned> LLVMFieldInfo;
  llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;

  /// LLVMBitFieldInfo - Holds location and size information about a bit field.
  struct LLVMBitFieldInfo {
    LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
                     unsigned Size)
      : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }

    const FieldDecl *FD;

    unsigned FieldNo;
    unsigned Start;
    unsigned Size;
  };
  llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;

  CGRecordLayoutBuilder(CodeGenTypes &Types)
    : Types(Types), Packed(false), ContainsPointerToDataMember(false)
    , Alignment(0), AlignmentAsLLVMStruct(1)
    , BitsAvailableInLastField(0), NextFieldOffsetInBytes(0) { }

  /// Layout - Will layout a RecordDecl.
  void Layout(const RecordDecl *D);

  /// LayoutUnion - Will layout a union RecordDecl.
  void LayoutUnion(const RecordDecl *D);

  /// LayoutField - try to layout all fields in the record decl.
  /// Returns false if the operation failed because the struct is not packed.
  bool LayoutFields(const RecordDecl *D);

  /// LayoutBases - layout the bases and vtable pointer of a record decl.
  void LayoutBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout);
  
  /// LayoutField - layout a single field. Returns false if the operation failed
  /// because the current struct is not packed.
  bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);

  /// LayoutBitField - layout a single bit field.
  void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);

  /// AppendField - Appends a field with the given offset and type.
  void AppendField(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);

  /// AppendPadding - Appends enough padding bytes so that the total struct
  /// size matches the alignment of the passed in type.
  void AppendPadding(uint64_t FieldOffsetInBytes, const llvm::Type *FieldTy);

  /// AppendPadding - Appends enough padding bytes so that the total
  /// struct size is a multiple of the field alignment.
  void AppendPadding(uint64_t FieldOffsetInBytes, unsigned FieldAlignment);

  /// AppendBytes - Append a given number of bytes to the record.
  void AppendBytes(uint64_t NumBytes);

  /// AppendTailPadding - Append enough tail padding so that the type will have
  /// the passed size.
  void AppendTailPadding(uint64_t RecordSize);

  unsigned getTypeAlignment(const llvm::Type *Ty) const;
  uint64_t getTypeSizeInBytes(const llvm::Type *Ty) const;

  /// CheckForPointerToDataMember - Check if the given type contains a pointer 
  /// to data member.
  void CheckForPointerToDataMember(QualType T);

public:
  /// ComputeLayout - Return the right record layout for a given record decl.
  static CGRecordLayout *ComputeLayout(CodeGenTypes &Types,
                                       const RecordDecl *D);
};

} // end namespace CodeGen
} // end namespace clang


#endif
OpenPOWER on IntegriCloud