summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/RecordLayout.h
blob: ab184563da23dd954500a3f6b6f36e0af0a48eee (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
//===--- 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
OpenPOWER on IntegriCloud