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
|
//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the RecordLayout interface.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
#define LLVM_CLANG_AST_LAYOUTINFO_H
#include "llvm/Support/DataTypes.h"
namespace clang {
class ASTContext;
class RecordDecl;
/// ASTRecordLayout -
/// This class contains layout information for one RecordDecl,
/// which is a struct/union/class. The decl represented must be a definition,
/// not a forward declaration.
/// This class is also used to contain layout information for one
/// ObjCInterfaceDecl. FIXME - Find appropriate name.
/// These objects are managed by ASTContext.
class ASTRecordLayout {
uint64_t Size; // Size of record in bits.
uint64_t NextOffset; // Next available offset
uint64_t *FieldOffsets;
unsigned Alignment; // Alignment of record in bits.
unsigned FieldCount; // Number of fields
friend class ASTContext;
ASTRecordLayout(uint64_t S = 0, unsigned A = 8)
: Size(S), NextOffset(S), Alignment(A), FieldCount(0) {}
~ASTRecordLayout() {
delete [] FieldOffsets;
}
/// Initialize record layout. N is the number of fields in this record.
void InitializeLayout(unsigned N) {
FieldCount = N;
FieldOffsets = new uint64_t[N];
}
/// Finalize record layout. Adjust record size based on the alignment.
void FinalizeLayout(bool ForceNonEmpty = false) {
// In C++, records cannot be of size 0.
if (ForceNonEmpty && Size == 0)
Size = 8;
// Finally, round the size of the record up to the alignment of the
// record itself.
Size = (Size + (Alignment-1)) & ~(Alignment-1);
}
void SetFieldOffset(unsigned FieldNo, uint64_t Offset) {
assert (FieldNo < FieldCount && "Invalid Field No");
FieldOffsets[FieldNo] = Offset;
}
void SetAlignment(unsigned A) { Alignment = A; }
/// LayoutField - Field layout. StructPacking is the specified
/// packing alignment (maximum alignment) in bits to use for the
/// structure, or 0 if no packing alignment is specified.
void LayoutField(const FieldDecl *FD, unsigned FieldNo,
bool IsUnion, unsigned StructPacking,
ASTContext &Context);
ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
public:
/// getAlignment - Get the record alignment in bits.
unsigned getAlignment() const { return Alignment; }
/// getSize - Get the record size in bits.
uint64_t getSize() const { return Size; }
/// getFieldCount - Get the number of fields in the layout.
unsigned getFieldCount() const { return FieldCount; }
/// getFieldOffset - Get the offset of the given field index, in
/// bits.
uint64_t getFieldOffset(unsigned FieldNo) const {
assert (FieldNo < FieldCount && "Invalid Field No");
return FieldOffsets[FieldNo];
}
/// getNextOffset - Get the next available (unused) offset in the
/// structure, in bits.
uint64_t getNextOffset() const {
return NextOffset;
}
};
} // end namespace clang
#endif
|