7
7
// ===----------------------------------------------------------------------===//
8
8
#include " clang/Frontend/LayoutOverrideSource.h"
9
9
#include " clang/AST/Decl.h"
10
+ #include " clang/AST/DeclCXX.h"
10
11
#include " clang/Basic/CharInfo.h"
11
12
#include " llvm/Support/raw_ostream.h"
12
13
#include < fstream>
@@ -26,6 +27,18 @@ static std::string parseName(StringRef S) {
26
27
return S.substr (0 , Offset).str ();
27
28
}
28
29
30
+ // / Parse an unsigned integer and move S to the next non-digit character.
31
+ static bool parseUnsigned (StringRef &S, unsigned long long &ULL) {
32
+ if (S.empty () || !isDigit (S[0 ]))
33
+ return false ;
34
+ unsigned Idx = 1 ;
35
+ while (Idx < S.size () && isDigit (S[Idx]))
36
+ ++Idx;
37
+ (void )S.substr (0 , Idx).getAsInteger (10 , ULL);
38
+ S = S.substr (Idx);
39
+ return true ;
40
+ }
41
+
29
42
LayoutOverrideSource::LayoutOverrideSource (StringRef Filename) {
30
43
std::ifstream Input (Filename.str ().c_str ());
31
44
if (!Input.is_open ())
@@ -80,8 +93,8 @@ LayoutOverrideSource::LayoutOverrideSource(StringRef Filename) {
80
93
LineStr = LineStr.substr (Pos + strlen (" Size:" ));
81
94
82
95
unsigned long long Size = 0 ;
83
- ( void )LineStr. getAsInteger ( 10 , Size);
84
- CurrentLayout.Size = Size;
96
+ if ( parseUnsigned (LineStr , Size))
97
+ CurrentLayout.Size = Size;
85
98
continue ;
86
99
}
87
100
@@ -92,21 +105,22 @@ LayoutOverrideSource::LayoutOverrideSource(StringRef Filename) {
92
105
LineStr = LineStr.substr (Pos + strlen (" Alignment:" ));
93
106
94
107
unsigned long long Alignment = 0 ;
95
- ( void )LineStr. getAsInteger ( 10 , Alignment);
96
- CurrentLayout.Align = Alignment;
108
+ if ( parseUnsigned (LineStr , Alignment))
109
+ CurrentLayout.Align = Alignment;
97
110
continue ;
98
111
}
99
112
100
- // Check for the size/alignment of the type.
113
+ // Check for the size/alignment of the type. The number follows "size=" or
114
+ // "align=" indicates number of bytes.
101
115
Pos = LineStr.find (" sizeof=" );
102
116
if (Pos != StringRef::npos) {
103
117
/* Skip past the sizeof= prefix. */
104
118
LineStr = LineStr.substr (Pos + strlen (" sizeof=" ));
105
119
106
120
// Parse size.
107
121
unsigned long long Size = 0 ;
108
- ( void )LineStr. getAsInteger ( 10 , Size);
109
- CurrentLayout.Size = Size;
122
+ if ( parseUnsigned (LineStr , Size))
123
+ CurrentLayout.Size = Size * 8 ;
110
124
111
125
Pos = LineStr.find (" align=" );
112
126
if (Pos != StringRef::npos) {
@@ -115,34 +129,59 @@ LayoutOverrideSource::LayoutOverrideSource(StringRef Filename) {
115
129
116
130
// Parse alignment.
117
131
unsigned long long Alignment = 0 ;
118
- ( void )LineStr. getAsInteger ( 10 , Alignment);
119
- CurrentLayout.Align = Alignment;
132
+ if ( parseUnsigned (LineStr , Alignment))
133
+ CurrentLayout.Align = Alignment * 8 ;
120
134
}
121
135
122
136
continue ;
123
137
}
124
138
125
139
// Check for the field offsets of the type.
126
140
Pos = LineStr.find (" FieldOffsets: [" );
127
- if (Pos == StringRef::npos)
128
- continue ;
141
+ if (Pos != StringRef::npos) {
142
+ LineStr = LineStr.substr (Pos + strlen (" FieldOffsets: [" ));
143
+ while (!LineStr.empty () && isDigit (LineStr[0 ])) {
144
+ unsigned long long Offset = 0 ;
145
+ if (parseUnsigned (LineStr, Offset))
146
+ CurrentLayout.FieldOffsets .push_back (Offset);
147
+
148
+ // Skip over this offset, the following comma, and any spaces.
149
+ LineStr = LineStr.substr (1 );
150
+ while (!LineStr.empty () && isWhitespace (LineStr[0 ]))
151
+ LineStr = LineStr.substr (1 );
152
+ }
153
+ }
129
154
130
- LineStr = LineStr.substr (Pos + strlen (" FieldOffsets: [" ));
131
- while (!LineStr.empty () && isDigit (LineStr[0 ])) {
132
- // Parse this offset.
133
- unsigned Idx = 1 ;
134
- while (Idx < LineStr.size () && isDigit (LineStr[Idx]))
135
- ++Idx;
155
+ // Check for the base offsets.
156
+ Pos = LineStr.find (" BaseOffsets: [" );
157
+ if (Pos != StringRef::npos) {
158
+ LineStr = LineStr.substr (Pos + strlen (" BaseOffsets: [" ));
159
+ while (!LineStr.empty () && isDigit (LineStr[0 ])) {
160
+ unsigned long long Offset = 0 ;
161
+ if (parseUnsigned (LineStr, Offset))
162
+ CurrentLayout.BaseOffsets .push_back (CharUnits::fromQuantity (Offset));
136
163
137
- unsigned long long Offset = 0 ;
138
- (void )LineStr.substr (0 , Idx).getAsInteger (10 , Offset);
164
+ // Skip over this offset, the following comma, and any spaces.
165
+ LineStr = LineStr.substr (1 );
166
+ while (!LineStr.empty () && isWhitespace (LineStr[0 ]))
167
+ LineStr = LineStr.substr (1 );
168
+ }
169
+ }
139
170
140
- CurrentLayout.FieldOffsets .push_back (Offset);
171
+ // Check for the virtual base offsets.
172
+ Pos = LineStr.find (" VBaseOffsets: [" );
173
+ if (Pos != StringRef::npos) {
174
+ LineStr = LineStr.substr (Pos + strlen (" VBaseOffsets: [" ));
175
+ while (!LineStr.empty () && isDigit (LineStr[0 ])) {
176
+ unsigned long long Offset = 0 ;
177
+ if (parseUnsigned (LineStr, Offset))
178
+ CurrentLayout.VBaseOffsets .push_back (CharUnits::fromQuantity (Offset));
141
179
142
- // Skip over this offset, the following comma, and any spaces.
143
- LineStr = LineStr.substr (Idx + 1 );
144
- while (!LineStr.empty () && isWhitespace (LineStr[0 ]))
180
+ // Skip over this offset, the following comma, and any spaces.
145
181
LineStr = LineStr.substr (1 );
182
+ while (!LineStr.empty () && isWhitespace (LineStr[0 ]))
183
+ LineStr = LineStr.substr (1 );
184
+ }
146
185
}
147
186
}
148
187
@@ -182,6 +221,24 @@ LayoutOverrideSource::layoutRecordType(const RecordDecl *Record,
182
221
if (NumFields != Known->second .FieldOffsets .size ())
183
222
return false ;
184
223
224
+ // Provide base offsets.
225
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(Record)) {
226
+ unsigned NumNB = 0 ;
227
+ unsigned NumVB = 0 ;
228
+ for (const auto &I : RD->vbases ()) {
229
+ if (NumVB >= Known->second .VBaseOffsets .size ())
230
+ continue ;
231
+ const CXXRecordDecl *VBase = I.getType ()->getAsCXXRecordDecl ();
232
+ VirtualBaseOffsets[VBase] = Known->second .VBaseOffsets [NumVB++];
233
+ }
234
+ for (const auto &I : RD->bases ()) {
235
+ if (I.isVirtual () || NumNB >= Known->second .BaseOffsets .size ())
236
+ continue ;
237
+ const CXXRecordDecl *Base = I.getType ()->getAsCXXRecordDecl ();
238
+ BaseOffsets[Base] = Known->second .BaseOffsets [NumNB++];
239
+ }
240
+ }
241
+
185
242
Size = Known->second .Size ;
186
243
Alignment = Known->second .Align ;
187
244
return true ;
0 commit comments