@@ -34,7 +34,7 @@ using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
3434// / needed for parsing.
3535class MCExpr {
3636public:
37- enum ExprKind {
37+ enum ExprKind : uint8_t {
3838 Binary, // /< Binary expressions.
3939 Constant, // /< Constant expressions.
4040 SymbolRef, // /< References to labels and assigned expressions.
@@ -43,21 +43,34 @@ class MCExpr {
4343 };
4444
4545private:
46+ static const unsigned NumSubclassDataBits = 24 ;
47+ static_assert (
48+ NumSubclassDataBits == CHAR_BIT * (sizeof (unsigned ) - sizeof (ExprKind)),
49+ " ExprKind and SubclassData together should take up one word" );
50+
4651 ExprKind Kind;
52+ // / Field reserved for use by MCExpr subclasses.
53+ unsigned SubclassData : NumSubclassDataBits;
4754 SMLoc Loc;
4855
4956 bool evaluateAsAbsolute (int64_t &Res, const MCAssembler *Asm,
5057 const MCAsmLayout *Layout,
5158 const SectionAddrMap *Addrs, bool InSet) const ;
5259
5360protected:
54- explicit MCExpr (ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
61+ explicit MCExpr (ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0 )
62+ : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
63+ assert (SubclassData < (1 << NumSubclassDataBits) &&
64+ " Subclass data too large" );
65+ }
5566
5667 bool evaluateAsRelocatableImpl (MCValue &Res, const MCAssembler *Asm,
5768 const MCAsmLayout *Layout,
5869 const MCFixup *Fixup,
5970 const SectionAddrMap *Addrs, bool InSet) const ;
6071
72+ unsigned getSubclassData () const { return SubclassData; }
73+
6174public:
6275 MCExpr (const MCExpr &) = delete ;
6376 MCExpr &operator =(const MCExpr &) = delete ;
@@ -130,19 +143,20 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
130143// // Represent a constant integer expression.
131144class MCConstantExpr : public MCExpr {
132145 int64_t Value;
133- bool PrintInHex = false ;
134- unsigned SizeInBytes = 0 ;
135146
136- explicit MCConstantExpr (int64_t Value)
137- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
147+ // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
148+ static const unsigned SizeInBytesBits = 8 ;
149+ static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1 ;
150+ static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
138151
139- MCConstantExpr (int64_t Value, bool PrintInHex)
140- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value),
141- PrintInHex (PrintInHex) {}
152+ static unsigned encodeSubclassData (bool PrintInHex, unsigned SizeInBytes) {
153+ assert (SizeInBytes <= sizeof (int64_t ) && " Excessive size" );
154+ return SizeInBytes | (PrintInHex ? PrintInHexBit : 0 );
155+ }
142156
143157 MCConstantExpr (int64_t Value, bool PrintInHex, unsigned SizeInBytes)
144- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value), PrintInHex(PrintInHex) ,
145- SizeInBytes( SizeInBytes) {}
158+ : MCExpr(MCExpr::Constant, SMLoc(),
159+ encodeSubclassData (PrintInHex, SizeInBytes)), Value(Value ) {}
146160
147161public:
148162 // / \name Construction
@@ -157,9 +171,11 @@ class MCConstantExpr : public MCExpr {
157171 // / @{
158172
159173 int64_t getValue () const { return Value; }
160- unsigned getSizeInBytes () const { return SizeInBytes; }
174+ unsigned getSizeInBytes () const {
175+ return getSubclassData () & SizeInBytesMask;
176+ }
161177
162- bool useHexFormat () const { return PrintInHex ; }
178+ bool useHexFormat () const { return ( getSubclassData () & PrintInHexBit) != 0 ; }
163179
164180 // / @}
165181
@@ -315,17 +331,32 @@ class MCSymbolRefExpr : public MCExpr {
315331 };
316332
317333private:
318- // / The symbol reference modifier.
319- const VariantKind Kind;
334+ // / The symbol being referenced.
335+ const MCSymbol *Symbol;
336+
337+ // Subclass data stores VariantKind in bits 0..15, UseParensForSymbolVariant
338+ // in bit 16 and HasSubsectionsViaSymbols in bit 17.
339+ static const unsigned VariantKindBits = 16 ;
340+ static const unsigned VariantKindMask = (1 << VariantKindBits) - 1 ;
320341
321342 // / Specifies how the variant kind should be printed.
322- const unsigned UseParensForSymbolVariant : 1 ;
343+ static const unsigned UseParensForSymbolVariantBit = 1 << VariantKindBits ;
323344
324345 // FIXME: Remove this bit.
325- const unsigned HasSubsectionsViaSymbols : 1 ;
346+ static const unsigned HasSubsectionsViaSymbolsBit =
347+ 1 << (VariantKindBits + 1 );
348+
349+ static unsigned encodeSubclassData (VariantKind Kind,
350+ bool UseParensForSymbolVariant,
351+ bool HasSubsectionsViaSymbols) {
352+ return (unsigned )Kind |
353+ (UseParensForSymbolVariant ? UseParensForSymbolVariantBit : 0 ) |
354+ (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0 );
355+ }
326356
327- // / The symbol being referenced.
328- const MCSymbol *Symbol;
357+ bool useParensForSymbolVariant () const {
358+ return (getSubclassData () & UseParensForSymbolVariantBit) != 0 ;
359+ }
329360
330361 explicit MCSymbolRefExpr (const MCSymbol *Symbol, VariantKind Kind,
331362 const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
@@ -349,11 +380,15 @@ class MCSymbolRefExpr : public MCExpr {
349380
350381 const MCSymbol &getSymbol () const { return *Symbol; }
351382
352- VariantKind getKind () const { return Kind; }
383+ VariantKind getKind () const {
384+ return (VariantKind)(getSubclassData () & VariantKindMask);
385+ }
353386
354387 void printVariantKind (raw_ostream &OS) const ;
355388
356- bool hasSubsectionsViaSymbols () const { return HasSubsectionsViaSymbols; }
389+ bool hasSubsectionsViaSymbols () const {
390+ return (getSubclassData () & HasSubsectionsViaSymbolsBit) != 0 ;
391+ }
357392
358393 // / @}
359394 // / \name Static Utility Functions
@@ -381,11 +416,10 @@ class MCUnaryExpr : public MCExpr {
381416 };
382417
383418private:
384- Opcode Op;
385419 const MCExpr *Expr;
386420
387421 MCUnaryExpr (Opcode Op, const MCExpr *Expr, SMLoc Loc)
388- : MCExpr(MCExpr::Unary, Loc), Op( Op), Expr(Expr) {}
422+ : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
389423
390424public:
391425 // / \name Construction
@@ -415,7 +449,7 @@ class MCUnaryExpr : public MCExpr {
415449 // / @{
416450
417451 // / Get the kind of this unary expression.
418- Opcode getOpcode () const { return Op ; }
452+ Opcode getOpcode () const { return (Opcode) getSubclassData () ; }
419453
420454 // / Get the child of this unary expression.
421455 const MCExpr *getSubExpr () const { return Expr; }
@@ -457,12 +491,11 @@ class MCBinaryExpr : public MCExpr {
457491 };
458492
459493private:
460- Opcode Op;
461494 const MCExpr *LHS, *RHS;
462495
463496 MCBinaryExpr (Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
464497 SMLoc Loc = SMLoc())
465- : MCExpr(MCExpr::Binary, Loc), Op( Op), LHS(LHS), RHS(RHS) {}
498+ : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
466499
467500public:
468501 // / \name Construction
@@ -572,7 +605,7 @@ class MCBinaryExpr : public MCExpr {
572605 // / @{
573606
574607 // / Get the kind of this binary expression.
575- Opcode getOpcode () const { return Op ; }
608+ Opcode getOpcode () const { return (Opcode) getSubclassData () ; }
576609
577610 // / Get the left-hand side expression of the binary operator.
578611 const MCExpr *getLHS () const { return LHS; }
0 commit comments