@@ -141,15 +141,17 @@ class ObjCBoxedExpr : public Expr {
141
141
142
142
// / ObjCArrayLiteral - used for objective-c array containers; as in:
143
143
// / @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
144
- class ObjCArrayLiteral : public Expr {
144
+ class ObjCArrayLiteral final
145
+ : public Expr,
146
+ private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
145
147
unsigned NumElements;
146
148
SourceRange Range;
147
149
ObjCMethodDecl *ArrayWithObjectsMethod;
148
-
150
+
149
151
ObjCArrayLiteral (ArrayRef<Expr *> Elements,
150
152
QualType T, ObjCMethodDecl * Method,
151
153
SourceRange SR);
152
-
154
+
153
155
explicit ObjCArrayLiteral (EmptyShell Empty, unsigned NumElements)
154
156
: Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
155
157
@@ -171,11 +173,11 @@ class ObjCArrayLiteral : public Expr {
171
173
}
172
174
173
175
// / \brief Retrieve elements of array of literals.
174
- Expr **getElements () { return reinterpret_cast <Expr **>( this + 1 ); }
176
+ Expr **getElements () { return getTrailingObjects <Expr *>( ); }
175
177
176
178
// / \brief Retrieve elements of array of literals.
177
- const Expr * const *getElements () const {
178
- return reinterpret_cast < const Expr * const *>( this + 1 );
179
+ const Expr * const *getElements () const {
180
+ return getTrailingObjects< Expr *>();
179
181
}
180
182
181
183
// / getNumElements - Return number of elements of objective-c array literal.
@@ -196,11 +198,12 @@ class ObjCArrayLiteral : public Expr {
196
198
}
197
199
198
200
// Iterators
199
- child_range children () {
200
- return child_range (( Stmt **) getElements (),
201
- ( Stmt **) getElements () + NumElements);
201
+ child_range children () {
202
+ return child_range (reinterpret_cast < Stmt **>( getElements ()),
203
+ reinterpret_cast < Stmt **>( getElements () ) + NumElements);
202
204
}
203
-
205
+
206
+ friend TrailingObjects;
204
207
friend class ASTStmtReader ;
205
208
};
206
209
@@ -230,32 +233,35 @@ template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
230
233
}
231
234
232
235
namespace clang {
233
- // / ObjCDictionaryLiteral - AST node to represent objective-c dictionary
234
- // / literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
235
- class ObjCDictionaryLiteral : public Expr {
236
- // / \brief Key/value pair used to store the key and value of a given element.
237
- // /
238
- // / Objects of this type are stored directly after the expression.
239
- struct KeyValuePair {
240
- Expr *Key;
241
- Expr *Value;
242
- };
243
-
244
- // / \brief Data that describes an element that is a pack expansion, used if any
245
- // / of the elements in the dictionary literal are pack expansions.
246
- struct ExpansionData {
247
- // / \brief The location of the ellipsis, if this element is a pack
248
- // / expansion.
249
- SourceLocation EllipsisLoc;
250
-
251
- // / \brief If non-zero, the number of elements that this pack
252
- // / expansion will expand to (+1).
253
- unsigned NumExpansionsPlusOne;
254
- };
236
+ // / \brief Internal struct for storing Key/value pair.
237
+ struct ObjCDictionaryLiteral_KeyValuePair {
238
+ Expr *Key;
239
+ Expr *Value;
240
+ };
241
+
242
+ // / \brief Internal struct to describes an element that is a pack
243
+ // / expansion, used if any of the elements in the dictionary literal
244
+ // / are pack expansions.
245
+ struct ObjCDictionaryLiteral_ExpansionData {
246
+ // / \brief The location of the ellipsis, if this element is a pack
247
+ // / expansion.
248
+ SourceLocation EllipsisLoc;
255
249
250
+ // / \brief If non-zero, the number of elements that this pack
251
+ // / expansion will expand to (+1).
252
+ unsigned NumExpansionsPlusOne;
253
+ };
254
+
255
+ // / ObjCDictionaryLiteral - AST node to represent objective-c dictionary
256
+ // / literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
257
+ class ObjCDictionaryLiteral final
258
+ : public Expr,
259
+ private llvm::TrailingObjects<ObjCDictionaryLiteral,
260
+ ObjCDictionaryLiteral_KeyValuePair,
261
+ ObjCDictionaryLiteral_ExpansionData> {
256
262
// / \brief The number of elements in this dictionary literal.
257
263
unsigned NumElements : 31 ;
258
-
264
+
259
265
// / \brief Determine whether this dictionary literal has any pack expansions.
260
266
// /
261
267
// / If the dictionary literal has pack expansions, then there will
@@ -264,10 +270,17 @@ class ObjCDictionaryLiteral : public Expr {
264
270
// / any) and number of elements in the expansion (if known). If
265
271
// / there are no pack expansions, we optimize away this storage.
266
272
unsigned HasPackExpansions : 1 ;
267
-
273
+
268
274
SourceRange Range;
269
275
ObjCMethodDecl *DictWithObjectsMethod;
270
-
276
+
277
+ typedef ObjCDictionaryLiteral_KeyValuePair KeyValuePair;
278
+ typedef ObjCDictionaryLiteral_ExpansionData ExpansionData;
279
+
280
+ size_t numTrailingObjects (OverloadToken<KeyValuePair>) const {
281
+ return NumElements;
282
+ }
283
+
271
284
ObjCDictionaryLiteral (ArrayRef<ObjCDictionaryElement> VK,
272
285
bool HasPackExpansions,
273
286
QualType T, ObjCMethodDecl *method,
@@ -278,28 +291,6 @@ class ObjCDictionaryLiteral : public Expr {
278
291
: Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
279
292
HasPackExpansions(HasPackExpansions) {}
280
293
281
- KeyValuePair *getKeyValues () {
282
- return reinterpret_cast <KeyValuePair *>(this + 1 );
283
- }
284
-
285
- const KeyValuePair *getKeyValues () const {
286
- return reinterpret_cast <const KeyValuePair *>(this + 1 );
287
- }
288
-
289
- ExpansionData *getExpansionData () {
290
- if (!HasPackExpansions)
291
- return nullptr ;
292
-
293
- return reinterpret_cast <ExpansionData *>(getKeyValues () + NumElements);
294
- }
295
-
296
- const ExpansionData *getExpansionData () const {
297
- if (!HasPackExpansions)
298
- return nullptr ;
299
-
300
- return reinterpret_cast <const ExpansionData *>(getKeyValues ()+NumElements);
301
- }
302
-
303
294
public:
304
295
static ObjCDictionaryLiteral *Create (const ASTContext &C,
305
296
ArrayRef<ObjCDictionaryElement> VK,
@@ -317,10 +308,11 @@ class ObjCDictionaryLiteral : public Expr {
317
308
318
309
ObjCDictionaryElement getKeyValueElement (unsigned Index) const {
319
310
assert ((Index < NumElements) && " Arg access out of range!" );
320
- const KeyValuePair &KV = getKeyValues ()[Index];
311
+ const KeyValuePair &KV = getTrailingObjects<KeyValuePair> ()[Index];
321
312
ObjCDictionaryElement Result = { KV.Key , KV.Value , SourceLocation (), None };
322
313
if (HasPackExpansions) {
323
- const ExpansionData &Expansion = getExpansionData ()[Index];
314
+ const ExpansionData &Expansion =
315
+ getTrailingObjects<ExpansionData>()[Index];
324
316
Result.EllipsisLoc = Expansion.EllipsisLoc ;
325
317
if (Expansion.NumExpansionsPlusOne > 0 )
326
318
Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1 ;
@@ -340,17 +332,20 @@ class ObjCDictionaryLiteral : public Expr {
340
332
}
341
333
342
334
// Iterators
343
- child_range children () {
335
+ child_range children () {
344
336
// Note: we're taking advantage of the layout of the KeyValuePair struct
345
337
// here. If that struct changes, this code will need to change as well.
346
338
static_assert (sizeof (KeyValuePair) == sizeof (Stmt *) * 2 ,
347
339
" KeyValuePair is expected size" );
348
- return child_range (reinterpret_cast <Stmt **>(this + 1 ),
349
- reinterpret_cast <Stmt **>(this + 1 ) + NumElements * 2 );
340
+ return child_range (
341
+ reinterpret_cast <Stmt **>(getTrailingObjects<KeyValuePair>()),
342
+ reinterpret_cast <Stmt **>(getTrailingObjects<KeyValuePair>()) +
343
+ NumElements * 2 );
350
344
}
351
345
352
346
friend class ASTStmtReader ;
353
347
friend class ASTStmtWriter ;
348
+ friend TrailingObjects;
354
349
};
355
350
356
351
@@ -797,13 +792,6 @@ class ObjCSubscriptRefExpr : public Expr {
797
792
explicit ObjCSubscriptRefExpr (EmptyShell Empty)
798
793
: Expr(ObjCSubscriptRefExprClass, Empty) {}
799
794
800
- static ObjCSubscriptRefExpr *Create (const ASTContext &C,
801
- Expr *base,
802
- Expr *key, QualType T,
803
- ObjCMethodDecl *getMethod,
804
- ObjCMethodDecl *setMethod,
805
- SourceLocation RB);
806
-
807
795
SourceLocation getRBracket () const { return RBracket; }
808
796
void setRBracket (SourceLocation RB) { RBracket = RB; }
809
797
@@ -865,7 +853,13 @@ class ObjCSubscriptRefExpr : public Expr {
865
853
// / All four kinds of message sends are modeled by the ObjCMessageExpr
866
854
// / class, and can be distinguished via \c getReceiverKind(). Example:
867
855
// /
868
- class ObjCMessageExpr : public Expr {
856
+ // / The "void *" trailing objects are actually ONE void * (the
857
+ // / receiver pointer), and NumArgs Expr *. But due to the
858
+ // / implementation of children(), these must be together contiguously.
859
+
860
+ class ObjCMessageExpr final
861
+ : public Expr,
862
+ private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
869
863
// / \brief Stores either the selector that this message is sending
870
864
// / to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
871
865
// / referring to the method that we type-checked against.
@@ -877,11 +871,6 @@ class ObjCMessageExpr : public Expr {
877
871
// / including the receiver.
878
872
unsigned NumArgs : NumArgsBitWidth;
879
873
880
- void setNumArgs (unsigned Num) {
881
- assert ((Num >> NumArgsBitWidth) == 0 && " Num of args is out of range!" );
882
- NumArgs = Num;
883
- }
884
-
885
874
// / \brief The kind of message send this is, which is one of the
886
875
// / ReceiverKind values.
887
876
// /
@@ -915,6 +904,13 @@ class ObjCMessageExpr : public Expr {
915
904
// / brackets ('[' and ']', respectively).
916
905
SourceLocation LBracLoc, RBracLoc;
917
906
907
+ size_t numTrailingObjects (OverloadToken<void *>) const { return NumArgs + 1 ; }
908
+
909
+ void setNumArgs (unsigned Num) {
910
+ assert ((Num >> NumArgsBitWidth) == 0 && " Num of args is out of range!" );
911
+ NumArgs = Num;
912
+ }
913
+
918
914
ObjCMessageExpr (EmptyShell Empty, unsigned NumArgs)
919
915
: Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0 ), Kind(0 ),
920
916
HasMethod (0 ), IsDelegateInitCall(0 ), IsImplicit(0 ), SelLocsKind(0 ) {
@@ -959,14 +955,11 @@ class ObjCMessageExpr : public Expr {
959
955
SelectorLocationsKind SelLocsK);
960
956
961
957
// / \brief Retrieve the pointer value of the message receiver.
962
- void *getReceiverPointer () const {
963
- return *const_cast <void **>(
964
- reinterpret_cast <const void * const *>(this + 1 ));
965
- }
958
+ void *getReceiverPointer () const { return *getTrailingObjects<void *>(); }
966
959
967
960
// / \brief Set the pointer value of the message receiver.
968
961
void setReceiverPointer (void *Value) {
969
- *reinterpret_cast <void **>( this + 1 ) = Value;
962
+ *getTrailingObjects <void *>( ) = Value;
970
963
}
971
964
972
965
SelectorLocationsKind getSelLocsKind () const {
@@ -979,10 +972,10 @@ class ObjCMessageExpr : public Expr {
979
972
// / \brief Get a pointer to the stored selector identifiers locations array.
980
973
// / No locations will be stored if HasStandardSelLocs is true.
981
974
SourceLocation *getStoredSelLocs () {
982
- return reinterpret_cast <SourceLocation*>( getArgs () + getNumArgs () );
975
+ return getTrailingObjects <SourceLocation>( );
983
976
}
984
977
const SourceLocation *getStoredSelLocs () const {
985
- return reinterpret_cast < const SourceLocation*>( getArgs () + getNumArgs () );
978
+ return getTrailingObjects< SourceLocation>( );
986
979
}
987
980
988
981
// / \brief Get the number of stored selector identifiers locations.
@@ -1286,20 +1279,21 @@ class ObjCMessageExpr : public Expr {
1286
1279
// / \brief Retrieve the arguments to this message, not including the
1287
1280
// / receiver.
1288
1281
Expr **getArgs () {
1289
- return reinterpret_cast <Expr **>(this + 1 ) + 1 ;
1282
+ return reinterpret_cast <Expr **>(getTrailingObjects< void *>( ) + 1 ) ;
1290
1283
}
1291
1284
const Expr * const *getArgs () const {
1292
- return reinterpret_cast <const Expr * const *>(this + 1 ) + 1 ;
1285
+ return reinterpret_cast <const Expr *const *>(getTrailingObjects<void *>() +
1286
+ 1 );
1293
1287
}
1294
1288
1295
1289
// / getArg - Return the specified argument.
1296
1290
Expr *getArg (unsigned Arg) {
1297
1291
assert (Arg < NumArgs && " Arg access out of range!" );
1298
- return cast<Expr>( getArgs ()[Arg]) ;
1292
+ return getArgs ()[Arg];
1299
1293
}
1300
1294
const Expr *getArg (unsigned Arg) const {
1301
1295
assert (Arg < NumArgs && " Arg access out of range!" );
1302
- return cast<Expr>( getArgs ()[Arg]) ;
1296
+ return getArgs ()[Arg];
1303
1297
}
1304
1298
// / setArg - Set the specified argument.
1305
1299
void setArg (unsigned Arg, Expr *ArgExpr) {
@@ -1379,6 +1373,7 @@ class ObjCMessageExpr : public Expr {
1379
1373
return reinterpret_cast <Stmt const * const *>(getArgs () + NumArgs);
1380
1374
}
1381
1375
1376
+ friend TrailingObjects;
1382
1377
friend class ASTStmtReader ;
1383
1378
friend class ASTStmtWriter ;
1384
1379
};
0 commit comments