@@ -2364,9 +2364,9 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
2364
2364
// / FieldDecl - An instance of this class is created by Sema::ActOnField to
2365
2365
// / represent a member of a struct/union/class.
2366
2366
class FieldDecl : public DeclaratorDecl , public Mergeable <FieldDecl> {
2367
- // FIXME: This can be packed into the bitfields in Decl.
2367
+ unsigned BitField : 1 ;
2368
2368
unsigned Mutable : 1 ;
2369
- mutable unsigned CachedFieldIndex : 31 ;
2369
+ mutable unsigned CachedFieldIndex : 30 ;
2370
2370
2371
2371
// / The kinds of value we can store in InitializerOrBitWidth.
2372
2372
// /
@@ -2376,7 +2376,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
2376
2376
// / If the pointer is null, there's nothing special. Otherwise,
2377
2377
// / this is a bitfield and the pointer is the Expr* storing the
2378
2378
// / bit-width.
2379
- ISK_BitWidthOrNothing = (unsigned ) ICIS_NoInit,
2379
+ ISK_NoInit = (unsigned ) ICIS_NoInit,
2380
2380
2381
2381
// / The pointer is an (optional due to delayed parsing) Expr*
2382
2382
// / holding the copy-initializer.
@@ -2391,27 +2391,34 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
2391
2391
ISK_CapturedVLAType,
2392
2392
};
2393
2393
2394
- // / \brief Storage for either the bit-width, the in-class
2395
- // / initializer, or the captured variable length array bound.
2396
- // /
2397
- // / We can safely combine these because in-class initializers are
2398
- // / not permitted for bit-fields, and both are exclusive with VLA
2399
- // / captures.
2394
+ // / If this is a bitfield with a default member initializer, this
2395
+ // / structure is used to represent the two expressions.
2396
+ struct InitAndBitWidth {
2397
+ Expr *Init;
2398
+ Expr *BitWidth;
2399
+ };
2400
+
2401
+ // / \brief Storage for either the bit-width, the in-class initializer, or
2402
+ // / both (via InitAndBitWidth), or the captured variable length array bound.
2400
2403
// /
2401
2404
// / If the storage kind is ISK_InClassCopyInit or
2402
2405
// / ISK_InClassListInit, but the initializer is null, then this
2403
- // / field has an in-class initializer which has not yet been parsed
2406
+ // / field has an in-class initializer that has not yet been parsed
2404
2407
// / and attached.
2408
+ // FIXME: Tail-allocate this to reduce the size of FieldDecl in the
2409
+ // overwhelmingly common case that we have none of these things.
2405
2410
llvm::PointerIntPair<void *, 2 , InitStorageKind> InitStorage;
2411
+
2406
2412
protected:
2407
2413
FieldDecl (Kind DK, DeclContext *DC, SourceLocation StartLoc,
2408
2414
SourceLocation IdLoc, IdentifierInfo *Id,
2409
2415
QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
2410
2416
InClassInitStyle InitStyle)
2411
2417
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
2412
- Mutable (Mutable), CachedFieldIndex(0 ),
2413
- InitStorage(BW, (InitStorageKind) InitStyle) {
2414
- assert ((!BW || InitStyle == ICIS_NoInit) && " got initializer for bitfield" );
2418
+ BitField (false ), Mutable(Mutable), CachedFieldIndex(0 ),
2419
+ InitStorage(nullptr , (InitStorageKind) InitStyle) {
2420
+ if (BW)
2421
+ setBitWidth (BW);
2415
2422
}
2416
2423
2417
2424
public:
@@ -2431,10 +2438,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
2431
2438
bool isMutable () const { return Mutable; }
2432
2439
2433
2440
// / \brief Determines whether this field is a bitfield.
2434
- bool isBitField () const {
2435
- return InitStorage.getInt () == ISK_BitWidthOrNothing &&
2436
- InitStorage.getPointer () != nullptr ;
2437
- }
2441
+ bool isBitField () const { return BitField; }
2438
2442
2439
2443
// / @brief Determines whether this is an unnamed bitfield.
2440
2444
bool isUnnamedBitfield () const { return isBitField () && !getDeclName (); }
@@ -2446,66 +2450,76 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
2446
2450
bool isAnonymousStructOrUnion () const ;
2447
2451
2448
2452
Expr *getBitWidth () const {
2449
- return isBitField ()
2450
- ? static_cast <Expr *>(InitStorage.getPointer ())
2451
- : nullptr ;
2453
+ if (!BitField)
2454
+ return nullptr ;
2455
+ void *Ptr = InitStorage.getPointer ();
2456
+ if (getInClassInitStyle ())
2457
+ return static_cast <InitAndBitWidth*>(Ptr)->BitWidth ;
2458
+ return static_cast <Expr*>(Ptr);
2452
2459
}
2453
2460
unsigned getBitWidthValue (const ASTContext &Ctx) const ;
2454
2461
2455
2462
// / setBitWidth - Set the bit-field width for this member.
2456
2463
// Note: used by some clients (i.e., do not remove it).
2457
2464
void setBitWidth (Expr *Width) {
2458
- assert (InitStorage.getInt () == ISK_BitWidthOrNothing &&
2459
- InitStorage.getPointer () == nullptr &&
2460
- " bit width, initializer or captured type already set" );
2461
- InitStorage.setPointerAndInt (Width, ISK_BitWidthOrNothing);
2465
+ assert (!hasCapturedVLAType () && !BitField &&
2466
+ " bit width or captured type already set" );
2467
+ assert (Width && " no bit width specified" );
2468
+ InitStorage.setPointer (
2469
+ InitStorage.getInt ()
2470
+ ? new (getASTContext ())
2471
+ InitAndBitWidth{getInClassInitializer (), Width}
2472
+ : static_cast <void *>(Width));
2473
+ BitField = true ;
2462
2474
}
2463
2475
2464
2476
// / removeBitWidth - Remove the bit-field width from this member.
2465
2477
// Note: used by some clients (i.e., do not remove it).
2466
2478
void removeBitWidth () {
2467
2479
assert (isBitField () && " no bitfield width to remove" );
2468
- InitStorage.setPointerAndInt (nullptr , ISK_BitWidthOrNothing);
2480
+ InitStorage.setPointer (getInClassInitializer ());
2481
+ BitField = false ;
2469
2482
}
2470
2483
2471
- // / getInClassInitStyle - Get the kind of (C++11) in-class initializer which
2472
- // / this field has.
2484
+ // / Get the kind of (C++11) default member initializer that this field has.
2473
2485
InClassInitStyle getInClassInitStyle () const {
2474
2486
InitStorageKind storageKind = InitStorage.getInt ();
2475
2487
return (storageKind == ISK_CapturedVLAType
2476
2488
? ICIS_NoInit : (InClassInitStyle) storageKind);
2477
2489
}
2478
2490
2479
- // / hasInClassInitializer - Determine whether this member has a C++11 in-class
2480
- // / initializer.
2491
+ // / Determine whether this member has a C++11 default member initializer.
2481
2492
bool hasInClassInitializer () const {
2482
2493
return getInClassInitStyle () != ICIS_NoInit;
2483
2494
}
2484
2495
2485
- // / getInClassInitializer - Get the C++11 in-class initializer for this
2486
- // / member, or null if one has not been set. If a valid declaration has an
2487
- // / in-class initializer, but this returns null, then we have not parsed and
2488
- // / attached it yet.
2496
+ // / Get the C++11 default member initializer for this member, or null if one
2497
+ // / has not been set. If a valid declaration has a default member initializer,
2498
+ // / but this returns null, then we have not parsed and attached it yet.
2489
2499
Expr *getInClassInitializer () const {
2490
- return hasInClassInitializer ()
2491
- ? static_cast <Expr *>(InitStorage.getPointer ())
2492
- : nullptr ;
2500
+ if (!hasInClassInitializer ())
2501
+ return nullptr ;
2502
+ void *Ptr = InitStorage.getPointer ();
2503
+ if (BitField)
2504
+ return static_cast <InitAndBitWidth*>(Ptr)->Init ;
2505
+ return static_cast <Expr*>(Ptr);
2493
2506
}
2494
2507
2495
2508
// / setInClassInitializer - Set the C++11 in-class initializer for this
2496
2509
// / member.
2497
2510
void setInClassInitializer (Expr *Init) {
2498
- assert (hasInClassInitializer () &&
2499
- InitStorage.getPointer () == nullptr &&
2500
- " bit width, initializer or captured type already set" );
2501
- InitStorage.setPointer (Init);
2511
+ assert (hasInClassInitializer () && !getInClassInitializer ());
2512
+ if (BitField)
2513
+ static_cast <InitAndBitWidth*>(InitStorage.getPointer ())->Init = Init;
2514
+ else
2515
+ InitStorage.setPointer (Init);
2502
2516
}
2503
2517
2504
2518
// / removeInClassInitializer - Remove the C++11 in-class initializer from this
2505
2519
// / member.
2506
2520
void removeInClassInitializer () {
2507
2521
assert (hasInClassInitializer () && " no initializer to remove" );
2508
- InitStorage.setPointerAndInt (nullptr , ISK_BitWidthOrNothing );
2522
+ InitStorage.setPointerAndInt (getBitWidth (), ISK_NoInit );
2509
2523
}
2510
2524
2511
2525
// / \brief Determine whether this member captures the variable length array
0 commit comments