Bug 1585806 - Make SideBits an enum class, add casting where necessary. r=botond
authorJames Hooks <james.hooks@mail.utoronto.ca>
Sat, 16 Nov 2019 20:59:34 +0000
changeset 502326 8921129925a8621b6a6ce593be136c8a98aac421
parent 502325 449f5545954f8bde849fcc372b4b87a6338739c1
child 502327 bfddca445c5e55ed06544655dbd8e5d89bbf9897
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1585806
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1585806 - Make SideBits an enum class, add casting where necessary. r=botond Differential Revision: https://phabricator.services.mozilla.com/D51291
gfx/2d/BaseMargin.h
gfx/2d/Types.h
gfx/layers/LayerAttributes.h
gfx/layers/Layers.cpp
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/wr/WebRenderScrollDataWrapper.h
layout/base/nsLayoutUtils.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsCSSRenderingBorders.h
--- a/gfx/2d/BaseMargin.h
+++ b/gfx/2d/BaseMargin.h
@@ -12,44 +12,47 @@
 #include "Types.h"
 
 namespace mozilla {
 
 /**
  * Sides represents a set of physical sides.
  */
 struct Sides final {
-  Sides() : mBits(0) {}
+  Sides() : mBits(SideBits::eNone) {}
   explicit Sides(SideBits aSideBits) {
-    MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits");
+    MOZ_ASSERT((aSideBits & ~SideBits::eAll) == SideBits::eNone,
+               "illegal side bits");
     mBits = aSideBits;
   }
-  bool IsEmpty() const { return mBits == 0; }
-  bool Top() const { return (mBits & eSideBitsTop) != 0; }
-  bool Right() const { return (mBits & eSideBitsRight) != 0; }
-  bool Bottom() const { return (mBits & eSideBitsBottom) != 0; }
-  bool Left() const { return (mBits & eSideBitsLeft) != 0; }
+  bool IsEmpty() const { return mBits == SideBits::eNone; }
+  bool Top() const { return (mBits & SideBits::eTop) == SideBits::eTop; }
+  bool Right() const { return (mBits & SideBits::eRight) == SideBits::eRight; }
+  bool Bottom() const {
+    return (mBits & SideBits::eBottom) == SideBits::eBottom;
+  }
+  bool Left() const { return (mBits & SideBits::eLeft) == SideBits::eLeft; }
   bool Contains(SideBits aSideBits) const {
-    MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits");
+    MOZ_ASSERT(!(aSideBits & ~SideBits::eAll), "illegal side bits");
     return (mBits & aSideBits) == aSideBits;
   }
   Sides operator|(Sides aOther) const {
     return Sides(SideBits(mBits | aOther.mBits));
   }
   Sides operator|(SideBits aSideBits) const { return *this | Sides(aSideBits); }
   Sides& operator|=(Sides aOther) {
     mBits |= aOther.mBits;
     return *this;
   }
   Sides& operator|=(SideBits aSideBits) { return *this |= Sides(aSideBits); }
   bool operator==(Sides aOther) const { return mBits == aOther.mBits; }
   bool operator!=(Sides aOther) const { return !(*this == aOther); }
 
  private:
-  uint8_t mBits;
+  SideBits mBits;
 };
 
 namespace gfx {
 
 /**
  * Do not use this class directly. Subclass it, pass that subclass as the
  * Sub parameter, and only use that subclass.
  */
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -508,33 +508,27 @@ typedef mozilla::gfx::SurfaceFormat gfxI
 #  define GFX2D_API
 #endif
 
 namespace mozilla {
 
 // Side constants for use in various places.
 enum Side { eSideTop, eSideRight, eSideBottom, eSideLeft };
 
-enum SideBits {
-  eSideBitsNone = 0,
-  eSideBitsTop = 1 << eSideTop,
-  eSideBitsRight = 1 << eSideRight,
-  eSideBitsBottom = 1 << eSideBottom,
-  eSideBitsLeft = 1 << eSideLeft,
-  eSideBitsTopBottom = eSideBitsTop | eSideBitsBottom,
-  eSideBitsLeftRight = eSideBitsLeft | eSideBitsRight,
-  eSideBitsAll = eSideBitsTopBottom | eSideBitsLeftRight
+enum class SideBits {
+  eNone = 0,
+  eTop = 1 << eSideTop,
+  eRight = 1 << eSideRight,
+  eBottom = 1 << eSideBottom,
+  eLeft = 1 << eSideLeft,
+  eTopBottom = SideBits::eTop | SideBits::eBottom,
+  eLeftRight = SideBits::eLeft | SideBits::eRight,
+  eAll = SideBits::eTopBottom | SideBits::eLeftRight
 };
 
-// Even though SideBits isn't an enum class, bitwise operators for it are
-// necessary for things like `a = a | b` to compile. This is because non-class
-// enums will implicitly convert to int (causing the right hand side to match
-// the built-in `operator|(int, int)` and have result type int), but int will
-// not implicitly convert back to the enum type.
-// TODO: Make SideBits an enum class.
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SideBits)
 
 // Creates a for loop that walks over the four mozilla::Side values.
 // We use an int32_t helper variable (instead of a Side) for our loop counter,
 // to avoid triggering undefined behavior just before we exit the loop (at
 // which point the counter is incremented beyond the largest valid Side value).
 #define NS_FOR_CSS_SIDES(var_)                                               \
   int32_t MOZ_CONCAT(var_, __LINE__) = mozilla::eSideTop;                    \
--- a/gfx/layers/LayerAttributes.h
+++ b/gfx/layers/LayerAttributes.h
@@ -324,17 +324,17 @@ class SimpleLayerAttributes final {
                : ScrollableLayerGuid::NULL_SCROLL_ID;
   }
 
   LayerPoint GetFixedPositionAnchor() const {
     return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint();
   }
 
   SideBits GetFixedPositionSides() const {
-    return mFixedPositionData ? mFixedPositionData->mSides : eSideBitsNone;
+    return mFixedPositionData ? mFixedPositionData->mSides : SideBits::eNone;
   }
 
   bool IsStickyPosition() const { return !!mStickyPositionData; }
 
   ScrollableLayerGuid::ViewID GetStickyScrollContainerId() const {
     return mStickyPositionData->mScrollId;
   }
 
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1717,21 +1717,22 @@ void Layer::PrintInfo(std::stringstream&
         aStream << nsPrintfCString(" [hscrollbar=%" PRIu64 "]",
                                    GetScrollbarData().mTargetViewId)
                        .get();
       }
     }
   }
   if (GetIsFixedPosition()) {
     LayerPoint anchor = GetFixedPositionAnchor();
-    aStream << nsPrintfCString(" [isFixedPosition scrollId=%" PRIu64
-                               " sides=0x%x anchor=%s]",
-                               GetFixedPositionScrollContainerId(),
-                               GetFixedPositionSides(),
-                               ToString(anchor).c_str())
+    aStream << nsPrintfCString(
+                   " [isFixedPosition scrollId=%" PRIu64
+                   " sides=0x%x anchor=%s]",
+                   GetFixedPositionScrollContainerId(),
+                   static_cast<unsigned int>(GetFixedPositionSides()),
+                   ToString(anchor).c_str())
                    .get();
   }
   if (GetIsStickyPosition()) {
     aStream << nsPrintfCString(" [isStickyPosition scrollId=%" PRIu64
                                " outer=(%.3f,%.3f)-(%.3f,%.3f) "
                                "inner=(%.3f,%.3f)-(%.3f,%.3f)]",
                                GetStickyScrollContainerId(),
                                GetStickyScrollRangeOuter().X(),
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1877,17 +1877,17 @@ APZEventResult APZCTreeManager::ProcessT
         SingleTouchData& touchData = aInput.mTouches[i];
         Maybe<ScreenIntPoint> untransformedScreenPoint =
             UntransformBy(outTransform, touchData.mScreenPoint);
         if (!untransformedScreenPoint) {
           result.mStatus = nsEventStatus_eIgnore;
           return result;
         }
         touchData.mScreenPoint = *untransformedScreenPoint;
-        if (mFixedPosSidesForInputBlock != eSideBitsNone) {
+        if (mFixedPosSidesForInputBlock != SideBits::eNone) {
           RecursiveMutexAutoLock lock(mTreeLock);
           touchData.mScreenPoint -=
               RoundedToInt(AsyncCompositionManager::ComputeFixedMarginsOffset(
                   mFixedLayerMargins, mFixedPosSidesForInputBlock));
         }
       }
     }
   }
@@ -3172,17 +3172,17 @@ already_AddRefed<AsyncPanZoomController>
 Maybe<ScreenIntPoint> APZCTreeManager::ConvertToGecko(
     const ScreenIntPoint& aPoint, AsyncPanZoomController* aApzc) {
   RecursiveMutexAutoLock lock(mTreeLock);
   ScreenToScreenMatrix4x4 transformScreenToGecko =
       GetScreenToApzcTransform(aApzc) * GetApzcToGeckoTransform(aApzc);
   Maybe<ScreenIntPoint> geckoPoint =
       UntransformBy(transformScreenToGecko, aPoint);
   if (geckoPoint) {
-    if (mFixedPosSidesForInputBlock != eSideBitsNone) {
+    if (mFixedPosSidesForInputBlock != SideBits::eNone) {
       *geckoPoint -=
           RoundedToInt(AsyncCompositionManager::ComputeFixedMarginsOffset(
               mFixedLayerMargins, mFixedPosSidesForInputBlock));
     }
   }
   return geckoPoint;
 }
 
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -561,17 +561,17 @@ class APZCTreeManager : public IAPZCTree
     // Fission purposes.
     LayersId mLayersId;
     // If a scrollbar was hit, this will be populated with the
     // scrollbar node. The AutoLock allows accessing the scrollbar
     // node without having to hold the tree lock.
     HitTestingTreeNodeAutoLock mScrollbarNode;
     // If content that is fixed to the root-content APZC was hit,
     // the sides of the viewport to which the content is fixed.
-    SideBits mFixedPosSides = eSideBitsNone;
+    SideBits mFixedPosSides = SideBits::eNone;
 
     HitTestResult() = default;
     // Make it move-only.
     HitTestResult(HitTestResult&&) = default;
     HitTestResult& operator=(HitTestResult&&) = default;
   };
 
   /* Some helper functions to find an APZC given some identifying input. These
@@ -867,17 +867,17 @@ class APZCTreeManager : public IAPZCTree
    */
   gfx::CompositorHitTestInfo mHitResultForInputBlock;
   /* If the current input event block is targeting an element that is fixed to
    * the viewport, the sides of the viewport to which the element is fixed.
    * Such elements may have been shifted to the dynamic toolbar, and this is
    * used to offset event coordinates accordingly.
    * This should be in sync with mApzcForInputBlock.
    */
-  SideBits mFixedPosSidesForInputBlock = eSideBitsNone;
+  SideBits mFixedPosSidesForInputBlock = SideBits::eNone;
   /* Sometimes we want to ignore all touches except one. In such cases, this
    * is set to the identifier of the touch we are not ignoring; in other cases,
    * this is set to -1.
    */
   int32_t mRetainedTouchIdentifier;
   /* This tracks whether the current input block represents a touch-drag of
    * a scrollbar. In this state, touch events are forwarded to content as touch
    * events, but converted to mouse events before going into InputQueue and
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -1471,29 +1471,29 @@ ScreenMargin AsyncCompositionManager::Ge
 }
 
 /*static*/
 ScreenPoint AsyncCompositionManager::ComputeFixedMarginsOffset(
     const ScreenMargin& aFixedMargins, SideBits aFixedSides) {
   // Work out the necessary translation, in screen space.
   ScreenPoint translation;
 
-  if ((aFixedSides & eSideBitsLeftRight) == eSideBitsLeftRight) {
+  if ((aFixedSides & SideBits::eLeftRight) == SideBits::eLeftRight) {
     translation.x += (aFixedMargins.left - aFixedMargins.right) / 2;
-  } else if (aFixedSides & eSideBitsRight) {
+  } else if (aFixedSides & SideBits::eRight) {
     translation.x -= aFixedMargins.right;
-  } else if (aFixedSides & eSideBitsLeft) {
+  } else if (aFixedSides & SideBits::eLeft) {
     translation.x += aFixedMargins.left;
   }
 
-  if ((aFixedSides & eSideBitsTopBottom) == eSideBitsTopBottom) {
+  if ((aFixedSides & SideBits::eTopBottom) == SideBits::eTopBottom) {
     translation.y += (aFixedMargins.top - aFixedMargins.bottom) / 2;
-  } else if (aFixedSides & eSideBitsBottom) {
+  } else if (aFixedSides & SideBits::eBottom) {
     translation.y -= aFixedMargins.bottom;
-  } else if (aFixedSides & eSideBitsTop) {
+  } else if (aFixedSides & SideBits::eTop) {
     translation.y += aFixedMargins.top;
   }
 
   return translation;
 }
 
 }  // namespace layers
 }  // namespace mozilla
--- a/gfx/layers/wr/WebRenderScrollDataWrapper.h
+++ b/gfx/layers/wr/WebRenderScrollDataWrapper.h
@@ -363,17 +363,17 @@ class MOZ_STACK_CLASS WebRenderScrollDat
     MOZ_ASSERT(IsValid());
     return mLayer->GetFixedPositionScrollContainerId();
   }
 
   SideBits GetFixedPositionSides() const {
     MOZ_ASSERT(IsValid());
 
     // TODO: Implement for WebRender.
-    return eSideBitsNone;
+    return SideBits::eNone;
   }
 
   Maybe<uint64_t> GetZoomAnimationId() const {
     MOZ_ASSERT(IsValid());
     return mLayer->GetZoomAnimationId();
   }
 
   bool IsBackfaceHidden() const {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1888,40 +1888,40 @@ void nsLayoutUtils::SetFixedPositionLaye
   }
 
   // Work out the anchor point for this fixed position layer. We assume that
   // any positioning set (left/top/right/bottom) indicates that the
   // corresponding side of its container should be the anchor point,
   // defaulting to top-left.
   LayerPoint anchor(anchorRect.x, anchorRect.y);
 
-  SideBits sides = eSideBitsNone;
+  SideBits sides = SideBits::eNone;
   if (aFixedPosFrame != aViewportFrame) {
     const nsStylePosition* position = aFixedPosFrame->StylePosition();
     if (!position->mOffset.Get(eSideRight).IsAuto()) {
-      sides |= eSideBitsRight;
+      sides |= SideBits::eRight;
       if (!position->mOffset.Get(eSideLeft).IsAuto()) {
-        sides |= eSideBitsLeft;
+        sides |= SideBits::eLeft;
         anchor.x = anchorRect.x + anchorRect.width / 2.f;
       } else {
         anchor.x = anchorRect.XMost();
       }
     } else if (!position->mOffset.Get(eSideLeft).IsAuto()) {
-      sides |= eSideBitsLeft;
+      sides |= SideBits::eLeft;
     }
     if (!position->mOffset.Get(eSideBottom).IsAuto()) {
-      sides |= eSideBitsBottom;
+      sides |= SideBits::eBottom;
       if (!position->mOffset.Get(eSideTop).IsAuto()) {
-        sides |= eSideBitsTop;
+        sides |= SideBits::eTop;
         anchor.y = anchorRect.y + anchorRect.height / 2.f;
       } else {
         anchor.y = anchorRect.YMost();
       }
     } else if (!position->mOffset.Get(eSideTop).IsAuto()) {
-      sides |= eSideBitsTop;
+      sides |= SideBits::eTop;
     }
   }
 
   ViewID id = ScrollIdForRootScrollFrame(aPresContext);
   aLayer->SetFixedPositionData(id, anchor, sides);
 }
 
 ScrollableLayerGuid::ViewID nsLayoutUtils::ScrollIdForRootScrollFrame(
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -210,24 +210,24 @@ void nsColumnSetFrame::CreateBorderRende
   // for us, so we not only save an enormous amount of code but we'll support
   // all the line styles that we support on borders!
   nsStyleBorder border(*presContext->Document());
   Sides skipSides;
   if (isVertical) {
     border.SetBorderWidth(eSideTop, ruleWidth);
     border.SetBorderStyle(eSideTop, ruleStyle);
     border.mBorderTopColor = StyleColor::FromColor(ruleColor);
-    skipSides |= mozilla::eSideBitsLeftRight;
-    skipSides |= mozilla::eSideBitsBottom;
+    skipSides |= mozilla::SideBits::eLeftRight;
+    skipSides |= mozilla::SideBits::eBottom;
   } else {
     border.SetBorderWidth(eSideLeft, ruleWidth);
     border.SetBorderStyle(eSideLeft, ruleStyle);
     border.mBorderLeftColor = StyleColor::FromColor(ruleColor);
-    skipSides |= mozilla::eSideBitsTopBottom;
-    skipSides |= mozilla::eSideBitsRight;
+    skipSides |= mozilla::SideBits::eTopBottom;
+    skipSides |= mozilla::SideBits::eRight;
   }
   // If we use box-decoration-break: slice (the default), the border
   // renderers will require clipping if we have continuations (see the
   // aNeedsClip parameter to ConstructBorderRenderer in nsCSSRendering).
   //
   // Since it doesn't matter which box-decoration-break we use since
   // we're only drawing borders (and not border-images), use 'clone'.
   border.mBoxDecorationBreak = StyleBoxDecorationBreak::Clone;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1614,43 +1614,43 @@ nsIFrame::Sides nsIFrame::GetSkipSides(c
   // Convert the logical skip sides to physical sides using the frame's
   // writing mode
   WritingMode writingMode = GetWritingMode();
   LogicalSides logicalSkip = GetLogicalSkipSides(aReflowInput);
   Sides skip;
 
   if (logicalSkip.BStart()) {
     if (writingMode.IsVertical()) {
-      skip |= writingMode.IsVerticalLR() ? eSideBitsLeft : eSideBitsRight;
+      skip |= writingMode.IsVerticalLR() ? SideBits::eLeft : SideBits::eRight;
     } else {
-      skip |= eSideBitsTop;
+      skip |= SideBits::eTop;
     }
   }
 
   if (logicalSkip.BEnd()) {
     if (writingMode.IsVertical()) {
-      skip |= writingMode.IsVerticalLR() ? eSideBitsRight : eSideBitsLeft;
+      skip |= writingMode.IsVerticalLR() ? SideBits::eRight : SideBits::eLeft;
     } else {
-      skip |= eSideBitsBottom;
+      skip |= SideBits::eBottom;
     }
   }
 
   if (logicalSkip.IStart()) {
     if (writingMode.IsVertical()) {
-      skip |= eSideBitsTop;
+      skip |= SideBits::eTop;
     } else {
-      skip |= writingMode.IsBidiLTR() ? eSideBitsLeft : eSideBitsRight;
+      skip |= writingMode.IsBidiLTR() ? SideBits::eLeft : SideBits::eRight;
     }
   }
 
   if (logicalSkip.IEnd()) {
     if (writingMode.IsVertical()) {
-      skip |= eSideBitsBottom;
+      skip |= SideBits::eBottom;
     } else {
-      skip |= writingMode.IsBidiLTR() ? eSideBitsRight : eSideBitsLeft;
+      skip |= writingMode.IsBidiLTR() ? SideBits::eRight : SideBits::eLeft;
     }
   }
   return skip;
 }
 
 nsRect nsIFrame::GetPaddingRectRelativeToSelf() const {
   nsMargin border(GetUsedBorder());
   border.ApplySkipSides(GetSkipSides());
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1380,17 +1380,17 @@ class nsIFrame : public nsQueryFrame {
    * original value coming from style.
    */
   static void InsetBorderRadii(nscoord aRadii[8], const nsMargin& aOffsets);
   static void OutsetBorderRadii(nscoord aRadii[8], const nsMargin& aOffsets);
 
   /**
    * Fill in border radii for this frame.  Return whether any are nonzero.
    * Indices into aRadii are the enum HalfCorner constants in gfx/2d/Types.h
-   * aSkipSides is a union of eSideBitsLeft/Right/Top/Bottom bits that says
+   * aSkipSides is a union of SideBits::eLeft/Right/Top/Bottom bits that says
    * which side(s) to skip.
    *
    * Note: GetMarginBoxBorderRadii() and GetShapeBoxBorderRadii() work only
    * on frames that establish block formatting contexts since they don't
    * participate in margin-collapsing.
    */
   virtual bool GetBorderRadii(const nsSize& aFrameSize,
                               const nsSize& aBorderArea, Sides aSkipSides,
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -119,19 +119,19 @@ static mozilla::Side GetVerticalSide(Cor
 }
 
 static Corner GetCWCorner(mozilla::Side aSide) {
   return Corner(NEXT_SIDE(aSide));
 }
 
 static Corner GetCCWCorner(mozilla::Side aSide) { return Corner(aSide); }
 
-static bool IsSingleSide(int aSides) {
-  return aSides == eSideBitsTop || aSides == eSideBitsRight ||
-         aSides == eSideBitsBottom || aSides == eSideBitsLeft;
+static bool IsSingleSide(mozilla::SideBits aSides) {
+  return aSides == SideBits::eTop || aSides == SideBits::eRight ||
+         aSides == SideBits::eBottom || aSides == SideBits::eLeft;
 }
 
 static bool IsHorizontalSide(mozilla::Side aSide) {
   return aSide == eSideTop || aSide == eSideBottom;
 }
 
 typedef enum {
   // Normal solid square corner.  Will be rectangular, the size of the
@@ -172,17 +172,17 @@ nsCSSBorderRenderer::nsCSSBorderRenderer
       mBorderStyles[2] != StyleBorderStyle::None ? mBorderWidths[2] : 0,
       mBorderStyles[3] != StyleBorderStyle::None ? mBorderWidths[3] : 0));
 
   ComputeBorderCornerDimensions(mBorderWidths, mBorderRadii,
                                 &mBorderCornerDimensions);
 
   mOneUnitBorder = CheckFourFloatsEqual(mBorderWidths, 1.0);
   mNoBorderRadius = AllCornersZeroSize(mBorderRadii);
-  mAllBordersSameStyle = AreBorderSideFinalStylesSame(eSideBitsAll);
+  mAllBordersSameStyle = AreBorderSideFinalStylesSame(SideBits::eAll);
   mAllBordersSameWidth = AllBordersSameWidth();
   mAvoidStroke = false;
 }
 
 /* static */
 void nsCSSBorderRenderer::ComputeInnerRadii(const RectCornerRadii& aRadii,
                                             const Float* aBorderSizes,
                                             RectCornerRadii* aInnerRadiiRet) {
@@ -272,50 +272,55 @@ void nsCSSBorderRenderer::ComputeOuterRa
                              ceil(std::max(topWidth, aRadii[C_TR].height)));
     (*aDimsRet)[C_BR] = Size(ceil(std::max(rightWidth, aRadii[C_BR].width)),
                              ceil(std::max(bottomWidth, aRadii[C_BR].height)));
     (*aDimsRet)[C_BL] = Size(ceil(std::max(leftWidth, aRadii[C_BL].width)),
                              ceil(std::max(bottomWidth, aRadii[C_BL].height)));
   }
 }
 
-bool nsCSSBorderRenderer::AreBorderSideFinalStylesSame(uint8_t aSides) {
-  NS_ASSERTION(aSides != 0 && (aSides & ~eSideBitsAll) == 0,
+bool nsCSSBorderRenderer::AreBorderSideFinalStylesSame(
+    mozilla::SideBits aSides) {
+  NS_ASSERTION(aSides != SideBits::eNone &&
+                   (aSides & ~SideBits::eAll) == SideBits::eNone,
                "AreBorderSidesSame: invalid whichSides!");
 
   /* First check if the specified styles and colors are the same for all sides
    */
   int firstStyle = 0;
   NS_FOR_CSS_SIDES(i) {
     if (firstStyle == i) {
-      if (((1 << i) & aSides) == 0) {
+      if ((static_cast<mozilla::SideBits>(1 << i) & aSides) ==
+          SideBits::eNone) {
         firstStyle++;
       }
       continue;
     }
 
-    if (((1 << i) & aSides) == 0) {
+    if ((static_cast<mozilla::SideBits>(1 << i) & aSides) == SideBits::eNone) {
       continue;
     }
 
     if (mBorderStyles[firstStyle] != mBorderStyles[i] ||
         mBorderColors[firstStyle] != mBorderColors[i]) {
       return false;
     }
   }
 
   /* Then if it's one of the two-tone styles and we're not
    * just comparing the TL or BR sides */
   switch (mBorderStyles[firstStyle]) {
     case StyleBorderStyle::Groove:
     case StyleBorderStyle::Ridge:
     case StyleBorderStyle::Inset:
     case StyleBorderStyle::Outset:
-      return ((aSides & ~(eSideBitsTop | eSideBitsLeft)) == 0 ||
-              (aSides & ~(eSideBitsBottom | eSideBitsRight)) == 0);
+      return ((aSides & ~(SideBits::eTop | SideBits::eLeft)) ==
+                  SideBits::eNone ||
+              (aSides & ~(SideBits::eBottom | SideBits::eRight)) ==
+                  SideBits::eNone);
     default:
       return true;
   }
 }
 
 bool nsCSSBorderRenderer::IsSolidCornerStyle(StyleBorderStyle aStyle,
                                              Corner aCorner) {
   switch (aStyle) {
@@ -1083,17 +1088,18 @@ void nsCSSBorderRenderer::GetOuterAndInn
 
   GetBezierPointsForCorner(aInnerBezier, aCorner, mInnerRect.AtCorner(aCorner),
                            innerCornerSize);
 }
 
 void nsCSSBorderRenderer::FillSolidBorder(const Rect& aOuterRect,
                                           const Rect& aInnerRect,
                                           const RectCornerRadii& aBorderRadii,
-                                          const Float* aBorderSizes, int aSides,
+                                          const Float* aBorderSizes,
+                                          SideBits aSides,
                                           const ColorPattern& aColor) {
   // Note that this function is allowed to draw more than just the
   // requested sides.
 
   // If we have a border radius, do full rounded rectangles
   // and fill, regardless of what sides we're asked to draw.
   if (!AllCornersZeroSize(aBorderRadii)) {
     RefPtr<PathBuilder> builder = mDrawTarget->CreatePathBuilder();
@@ -1113,88 +1119,88 @@ void nsCSSBorderRenderer::FillSolidBorde
     return;
   }
 
   // If we're asked to draw all sides of an equal-sized border,
   // stroking is fastest.  This is a fairly common path, but partial
   // sides is probably second in the list -- there are a bunch of
   // common border styles, such as inset and outset, that are
   // top-left/bottom-right split.
-  if (aSides == eSideBitsAll &&
+  if (aSides == SideBits::eAll &&
       CheckFourFloatsEqual(aBorderSizes, aBorderSizes[0]) && !mAvoidStroke) {
     Float strokeWidth = aBorderSizes[0];
     Rect r(aOuterRect);
     r.Deflate(strokeWidth / 2.f);
     mDrawTarget->StrokeRect(r, aColor, StrokeOptions(strokeWidth));
     return;
   }
 
   // Otherwise, we have unequal sized borders or we're only
   // drawing some sides; create rectangles for each side
   // and fill them.
 
   Rect r[4];
 
   // compute base rects for each side
-  if (aSides & eSideBitsTop) {
+  if (aSides & SideBits::eTop) {
     r[eSideTop] = Rect(aOuterRect.X(), aOuterRect.Y(), aOuterRect.Width(),
                        aBorderSizes[eSideTop]);
   }
 
-  if (aSides & eSideBitsBottom) {
+  if (aSides & SideBits::eBottom) {
     r[eSideBottom] =
         Rect(aOuterRect.X(), aOuterRect.YMost() - aBorderSizes[eSideBottom],
              aOuterRect.Width(), aBorderSizes[eSideBottom]);
   }
 
-  if (aSides & eSideBitsLeft) {
+  if (aSides & SideBits::eLeft) {
     r[eSideLeft] = Rect(aOuterRect.X(), aOuterRect.Y(), aBorderSizes[eSideLeft],
                         aOuterRect.Height());
   }
 
-  if (aSides & eSideBitsRight) {
+  if (aSides & SideBits::eRight) {
     r[eSideRight] =
         Rect(aOuterRect.XMost() - aBorderSizes[eSideRight], aOuterRect.Y(),
              aBorderSizes[eSideRight], aOuterRect.Height());
   }
 
   // If two sides meet at a corner that we're rendering, then
   // make sure that we adjust one of the sides to avoid overlap.
   // This is especially important in the case of colors with
   // an alpha channel.
 
-  if ((aSides & (eSideBitsTop | eSideBitsLeft)) ==
-      (eSideBitsTop | eSideBitsLeft)) {
+  if ((aSides & (SideBits::eTop | SideBits::eLeft)) ==
+      (SideBits::eTop | SideBits::eLeft)) {
     // adjust the left's top down a bit
     r[eSideLeft].y += aBorderSizes[eSideTop];
     r[eSideLeft].height -= aBorderSizes[eSideTop];
   }
 
-  if ((aSides & (eSideBitsTop | eSideBitsRight)) ==
-      (eSideBitsTop | eSideBitsRight)) {
+  if ((aSides & (SideBits::eTop | SideBits::eRight)) ==
+      (SideBits::eTop | SideBits::eRight)) {
     // adjust the top's left a bit
     r[eSideTop].width -= aBorderSizes[eSideRight];
   }
 
-  if ((aSides & (eSideBitsBottom | eSideBitsRight)) ==
-      (eSideBitsBottom | eSideBitsRight)) {
+  if ((aSides & (SideBits::eBottom | SideBits::eRight)) ==
+      (SideBits::eBottom | SideBits::eRight)) {
     // adjust the right's bottom a bit
     r[eSideRight].height -= aBorderSizes[eSideBottom];
   }
 
-  if ((aSides & (eSideBitsBottom | eSideBitsLeft)) ==
-      (eSideBitsBottom | eSideBitsLeft)) {
+  if ((aSides & (SideBits::eBottom | SideBits::eLeft)) ==
+      (SideBits::eBottom | SideBits::eLeft)) {
     // adjust the bottom's left a bit
     r[eSideBottom].x += aBorderSizes[eSideLeft];
     r[eSideBottom].width -= aBorderSizes[eSideLeft];
   }
 
   // Filling these one by one is faster than filling them all at once.
   for (uint32_t i = 0; i < 4; i++) {
-    if (aSides & (1 << i)) {
+    if (aSides & static_cast<mozilla::SideBits>(1 << i)) {
       MaybeSnapToDevicePixels(r[i], *mDrawTarget, true);
       mDrawTarget->FillRect(r[i], aColor);
     }
   }
 }
 
 Color MakeBorderColor(nscolor aColor, BorderColorStyle aBorderColorStyle) {
   nscolor colors[2];
@@ -1221,67 +1227,68 @@ Color ComputeColorForLine(uint32_t aLine
                           const BorderColorStyle* aBorderColorStyle,
                           uint32_t aBorderColorStyleCount,
                           nscolor aBorderColor) {
   NS_ASSERTION(aLineIndex < aBorderColorStyleCount, "Invalid lineIndex given");
 
   return MakeBorderColor(aBorderColor, aBorderColorStyle[aLineIndex]);
 }
 
-void nsCSSBorderRenderer::DrawBorderSides(int aSides) {
-  if (aSides == 0 || (aSides & ~eSideBitsAll) != 0) {
+void nsCSSBorderRenderer::DrawBorderSides(mozilla::SideBits aSides) {
+  if (aSides == SideBits::eNone ||
+      (aSides & ~SideBits::eAll) != SideBits::eNone) {
     NS_WARNING("DrawBorderSides: invalid sides!");
     return;
   }
 
   StyleBorderStyle borderRenderStyle = StyleBorderStyle::None;
   nscolor borderRenderColor;
 
   uint32_t borderColorStyleCount = 0;
   BorderColorStyle borderColorStyleTopLeft[3], borderColorStyleBottomRight[3];
   BorderColorStyle* borderColorStyle = nullptr;
 
   NS_FOR_CSS_SIDES(i) {
-    if ((aSides & (1 << i)) == 0) {
+    if ((aSides & static_cast<mozilla::SideBits>(1 << i)) == SideBits::eNone) {
       continue;
     }
     borderRenderStyle = mBorderStyles[i];
     borderRenderColor = mBorderColors[i];
     break;
   }
 
   if (borderRenderStyle == StyleBorderStyle::None ||
       borderRenderStyle == StyleBorderStyle::Hidden) {
     return;
   }
 
   if (borderRenderStyle == StyleBorderStyle::Dashed ||
       borderRenderStyle == StyleBorderStyle::Dotted) {
     // Draw each corner separately, with the given side's color.
-    if (aSides & eSideBitsTop) {
+    if (aSides & SideBits::eTop) {
       DrawDashedOrDottedCorner(eSideTop, C_TL);
-    } else if (aSides & eSideBitsLeft) {
+    } else if (aSides & SideBits::eLeft) {
       DrawDashedOrDottedCorner(eSideLeft, C_TL);
     }
 
-    if (aSides & eSideBitsTop) {
+    if (aSides & SideBits::eTop) {
       DrawDashedOrDottedCorner(eSideTop, C_TR);
-    } else if (aSides & eSideBitsRight) {
+    } else if (aSides & SideBits::eRight) {
       DrawDashedOrDottedCorner(eSideRight, C_TR);
     }
 
-    if (aSides & eSideBitsBottom) {
+    if (aSides & SideBits::eBottom) {
       DrawDashedOrDottedCorner(eSideBottom, C_BL);
-    } else if (aSides & eSideBitsLeft) {
+    } else if (aSides & SideBits::eLeft) {
       DrawDashedOrDottedCorner(eSideLeft, C_BL);
     }
 
-    if (aSides & eSideBitsBottom) {
+    if (aSides & SideBits::eBottom) {
       DrawDashedOrDottedCorner(eSideBottom, C_BR);
-    } else if (aSides & eSideBitsRight) {
+    } else if (aSides & SideBits::eRight) {
       DrawDashedOrDottedCorner(eSideRight, C_BR);
     }
     return;
   }
 
   // The borderColorStyle array goes from the outer to the inner style.
   //
   // If the border width is 1, we need to change the borderRenderStyle
@@ -1358,17 +1365,17 @@ void nsCSSBorderRenderer::DrawBorderSide
   // since -moz-border-colors doesn't get handled here.
   NS_ASSERTION(borderColorStyleCount > 0 && borderColorStyleCount < 4,
                "Non-border-colors case with borderColorStyleCount < 1 or > 3; "
                "what happened?");
 
   // The caller should never give us anything with a mix
   // of TL/BR if the border style would require a
   // TL/BR split.
-  if (aSides & (eSideBitsBottom | eSideBitsRight)) {
+  if (aSides & (SideBits::eBottom | SideBits::eRight)) {
     borderColorStyle = borderColorStyleBottomRight;
   } else {
     borderColorStyle = borderColorStyleTopLeft;
   }
 
   // Distribute the border across the available space.
   Float borderWidths[3][4];
 
@@ -1429,35 +1436,35 @@ void nsCSSBorderRenderer::DrawBorderSide
   // |     |
   bool noMarginTop = false;
   bool noMarginRight = false;
   bool noMarginBottom = false;
   bool noMarginLeft = false;
 
   // If there is at least one dotted side, every side is rendered separately.
   if (IsSingleSide(aSides)) {
-    if (aSides == eSideBitsTop) {
+    if (aSides == SideBits::eTop) {
       if (mBorderStyles[eSideRight] == StyleBorderStyle::Dotted &&
           IsZeroSize(mBorderRadii[C_TR])) {
         noMarginRight = true;
       }
       if (mBorderStyles[eSideLeft] == StyleBorderStyle::Dotted &&
           IsZeroSize(mBorderRadii[C_TL])) {
         noMarginLeft = true;
       }
-    } else if (aSides == eSideBitsRight) {
+    } else if (aSides == SideBits::eRight) {
       if (mBorderStyles[eSideTop] == StyleBorderStyle::Dotted &&
           IsZeroSize(mBorderRadii[C_TR])) {
         noMarginTop = true;
       }
       if (mBorderStyles[eSideBottom] == StyleBorderStyle::Dotted &&
           IsZeroSize(mBorderRadii[C_BR])) {
         noMarginBottom = true;
       }
-    } else if (aSides == eSideBitsBottom) {
+    } else if (aSides == SideBits::eBottom) {
       if (mBorderStyles[eSideRight] == StyleBorderStyle::Dotted &&
           IsZeroSize(mBorderRadii[C_BR])) {
         noMarginRight = true;
       }
       if (mBorderStyles[eSideLeft] == StyleBorderStyle::Dotted &&
           IsZeroSize(mBorderRadii[C_BL])) {
         noMarginLeft = true;
       }
@@ -3085,35 +3092,36 @@ void nsCSSBorderRenderer::DrawBorders() 
     }
     mOuterRect = ToRect(outerRect);
 
     gfxRect innerRect = ThebesRect(mInnerRect);
     gfxUtils::ConditionRect(innerRect);
     mInnerRect = ToRect(innerRect);
   }
 
-  int dashedSides = 0;
+  SideBits dashedSides = SideBits::eNone;
   bool forceSeparateCorners = false;
 
   NS_FOR_CSS_SIDES(i) {
     StyleBorderStyle style = mBorderStyles[i];
     if (style == StyleBorderStyle::Dashed ||
         style == StyleBorderStyle::Dotted) {
       // we need to draw things separately for dashed/dotting
       forceSeparateCorners = true;
-      dashedSides |= (1 << i);
+      dashedSides |= static_cast<mozilla::SideBits>(1 << i);
     }
   }
 
   PrintAsFormatString(" mAllBordersSameStyle: %d dashedSides: 0x%02x\n",
-                      mAllBordersSameStyle, dashedSides);
+                      mAllBordersSameStyle,
+                      static_cast<unsigned int>(dashedSides));
 
   if (mAllBordersSameStyle && !forceSeparateCorners) {
     /* Draw everything in one go */
-    DrawBorderSides(eSideBitsAll);
+    DrawBorderSides(SideBits::eAll);
     PrintAsStringNewline("---------------- (1)");
   } else {
     AUTO_PROFILER_LABEL("nsCSSBorderRenderer::DrawBorders:multipass", GRAPHICS);
 
     /* We have more than one pass to go.  Draw the corners separately from the
      * sides. */
 
     // The corner is going to have negligible size if its two adjacent border
@@ -3191,17 +3199,18 @@ void nsCSSBorderRenderer::DrawBorders() 
     // First, the corners
     NS_FOR_CSS_FULL_CORNERS(corner) {
       // if there's no corner, don't do all this work for it
       if (IsZeroSize(mBorderCornerDimensions[corner])) {
         continue;
       }
 
       const int sides[2] = {corner, PREV_SIDE(corner)};
-      int sideBits = (1 << sides[0]) | (1 << sides[1]);
+      SideBits sideBits =
+          static_cast<SideBits>((1 << sides[0]) | (1 << sides[1]));
 
       bool simpleCornerStyle = AreBorderSideFinalStylesSame(sideBits);
 
       // If we don't have anything complex going on in this corner,
       // then we can just fill the corner with a solid color, and avoid
       // the potentially expensive clip.
       if (simpleCornerStyle && IsZeroSize(mBorderRadii[corner]) &&
           IsSolidCornerStyle(mBorderStyles[sides[0]], corner)) {
@@ -3238,17 +3247,17 @@ void nsCSSBorderRenderer::DrawBorders() 
 
           PrintAsFormatString("corner: %d cornerSide: %d side: %d style: %d\n",
                               corner, cornerSide, side,
                               static_cast<int>(style));
 
           RefPtr<Path> path = GetSideClipSubPath(side);
           mDrawTarget->PushClip(path);
 
-          DrawBorderSides(1 << side);
+          DrawBorderSides(static_cast<mozilla::SideBits>(1 << side));
 
           mDrawTarget->PopClip();
         }
       }
 
       mDrawTarget->PopClip();
 
       PrintAsStringNewline();
@@ -3256,51 +3265,52 @@ void nsCSSBorderRenderer::DrawBorders() 
 
     // in the case of a single-unit border, we already munged the
     // corners up above; so we can just draw the top left and bottom
     // right sides separately, if they're the same.
     //
     // We need to check for mNoBorderRadius, because when there is
     // one, FillSolidBorder always draws the full rounded rectangle
     // and expects there to be a clip in place.
-    int alreadyDrawnSides = 0;
+    SideBits alreadyDrawnSides = SideBits::eNone;
     if (mOneUnitBorder && mNoBorderRadius &&
-        (dashedSides & (eSideBitsTop | eSideBitsLeft)) == 0) {
+        (dashedSides & (SideBits::eTop | SideBits::eLeft)) == SideBits::eNone) {
       bool tlBordersSameStyle =
-          AreBorderSideFinalStylesSame(eSideBitsTop | eSideBitsLeft);
+          AreBorderSideFinalStylesSame(SideBits::eTop | SideBits::eLeft);
       bool brBordersSameStyle =
-          AreBorderSideFinalStylesSame(eSideBitsBottom | eSideBitsRight);
+          AreBorderSideFinalStylesSame(SideBits::eBottom | SideBits::eRight);
 
       if (tlBordersSameStyle) {
-        DrawBorderSides(eSideBitsTop | eSideBitsLeft);
-        alreadyDrawnSides |= (eSideBitsTop | eSideBitsLeft);
+        DrawBorderSides(SideBits::eTop | SideBits::eLeft);
+        alreadyDrawnSides |= (SideBits::eTop | SideBits::eLeft);
       }
 
       if (brBordersSameStyle &&
-          (dashedSides & (eSideBitsBottom | eSideBitsRight)) == 0) {
-        DrawBorderSides(eSideBitsBottom | eSideBitsRight);
-        alreadyDrawnSides |= (eSideBitsBottom | eSideBitsRight);
+          (dashedSides & (SideBits::eBottom | SideBits::eRight)) ==
+              SideBits::eNone) {
+        DrawBorderSides(SideBits::eBottom | SideBits::eRight);
+        alreadyDrawnSides |= (SideBits::eBottom | SideBits::eRight);
       }
     }
 
     // We're done with the corners, now draw the sides.
     NS_FOR_CSS_SIDES(side) {
       // if we drew it above, skip it
-      if (alreadyDrawnSides & (1 << side)) {
+      if (alreadyDrawnSides & static_cast<mozilla::SideBits>(1 << side)) {
         continue;
       }
 
       // If there's no border on this side, skip it
       if (mBorderWidths[side] == 0.0 ||
           mBorderStyles[side] == StyleBorderStyle::Hidden ||
           mBorderStyles[side] == StyleBorderStyle::None) {
         continue;
       }
 
-      if (dashedSides & (1 << side)) {
+      if (dashedSides & static_cast<mozilla::SideBits>(1 << side)) {
         // Dashed sides will always draw just the part ignoring the
         // corners for the side, so no need to clip.
         DrawDashedOrDottedSide(side);
 
         PrintAsStringNewline("---------------- (d)");
         continue;
       }
 
@@ -3309,17 +3319,17 @@ void nsCSSBorderRenderer::DrawBorders() 
       // so we need to clip.
       //
       // XXX Optimization -- it would be good to make this work like
       // DrawDashedOrDottedSide, and have a DrawOneSide function that just
       // draws one side and not the corners, because then we can
       // avoid the potentially expensive clip.
       mDrawTarget->PushClipRect(GetSideClipWithoutCornersRect(side));
 
-      DrawBorderSides(1 << side);
+      DrawBorderSides(static_cast<mozilla::SideBits>(1 << side));
 
       mDrawTarget->PopClip();
 
       PrintAsStringNewline("---------------- (*)");
     }
   }
 }
 
--- a/layout/painting/nsCSSRenderingBorders.h
+++ b/layout/painting/nsCSSRenderingBorders.h
@@ -146,17 +146,17 @@ class nsCSSBorderRenderer final {
   bool mOneUnitBorder;
   bool mNoBorderRadius;
   bool mAvoidStroke;
   bool mBackfaceIsVisible;
   mozilla::Maybe<Rect> mLocalClip;
 
   // For all the sides in the bitmask, would they be rendered
   // in an identical color and style?
-  bool AreBorderSideFinalStylesSame(uint8_t aSides);
+  bool AreBorderSideFinalStylesSame(mozilla::SideBits aSides);
 
   // For the given style, is the given corner a solid color?
   bool IsSolidCornerStyle(mozilla::StyleBorderStyle aStyle,
                           mozilla::Corner aCorner);
 
   // For the given corner, is the given corner mergeable into one dot?
   bool IsCornerMergeable(mozilla::Corner aCorner);
 
@@ -202,26 +202,26 @@ class nsCSSBorderRenderer final {
   //
   // If we can't stroke, then if it's a TL/BR pair, we use the specific
   // TL/BR paths.  Otherwise, we do the full path and fill.
   //
   // Calling code is expected to only set up a clip as necessary; no
   // clip is needed if we can render the entire border in 1 or 2 passes.
   void FillSolidBorder(const Rect& aOuterRect, const Rect& aInnerRect,
                        const RectCornerRadii& aBorderRadii,
-                       const Float* aBorderSizes, int aSides,
+                       const Float* aBorderSizes, mozilla::SideBits aSides,
                        const ColorPattern& aColor);
 
   //
   // core rendering
   //
 
   // draw the border for the given sides, using the style of the first side
   // present in the bitmask
-  void DrawBorderSides(int aSides);
+  void DrawBorderSides(mozilla::SideBits aSides);
 
   // Setup the stroke options for the given dashed/dotted side
   void SetupDashedOptions(StrokeOptions* aStrokeOptions, Float aDash[2],
                           mozilla::Side aSide, Float aBorderLength,
                           bool isCorner);
 
   // Draw the given dashed/dotte side
   void DrawDashedOrDottedSide(mozilla::Side aSide);