Remove implicit constructor and operator int from PowerOf2.

This patch is to make instantiation and conversion to an integer explicit,
so that we can mechanically replace all occurrences of the class with
integer in the next step.

Now get() returns an alignment value rather than its log2 value.

llvm-svn: 233242
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
index 5b3fbbb..6157599 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
@@ -38,7 +38,7 @@
   const lld::AtomLayout *appendAtom(const Atom *atom) {
     const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
     DefinedAtom::Alignment atomAlign = definedAtom->alignment();
-    uint64_t alignment = 1u << atomAlign.powerOf2;
+    uint64_t alignment = atomAlign.powerOf2.get();
     this->_atoms.push_back(new (this->_alloc) lld::AtomLayout(atom, 0, 0));
     // Set the section alignment to the largest alignment
     // std::max doesn't support uint64_t
@@ -57,8 +57,8 @@
                                                 const lld::AtomLayout * B) {
     const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom);
     const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom);
-    int64_t alignmentA = 1 << definedAtomA->alignment().powerOf2;
-    int64_t alignmentB = 1 << definedAtomB->alignment().powerOf2;
+    int64_t alignmentA = definedAtomA->alignment().powerOf2.get();
+    int64_t alignmentB = definedAtomB->alignment().powerOf2.get();
     if (alignmentA == alignmentB) {
       if (definedAtomA->merge() == DefinedAtom::mergeAsTentative)
         return false;
diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h
index 03bdb59..55d8d72 100644
--- a/lld/lib/ReaderWriter/ELF/SectionChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h
@@ -310,7 +310,7 @@
 uint64_t AtomSection<ELFT>::alignOffset(uint64_t offset,
                                         DefinedAtom::Alignment &atomAlign) {
   uint64_t requiredModulus = atomAlign.modulus;
-  uint64_t alignment = 1u << atomAlign.powerOf2;
+  uint64_t alignment = atomAlign.powerOf2.get();
   uint64_t currentModulus = (offset % alignment);
   uint64_t retOffset = offset;
   if (currentModulus != requiredModulus) {
@@ -330,7 +330,7 @@
   const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
 
   DefinedAtom::Alignment atomAlign = definedAtom->alignment();
-  uint64_t alignment = 1u << atomAlign.powerOf2;
+  uint64_t alignment = atomAlign.powerOf2.get();
   // Align the atom to the required modulus/ align the file offset and the
   // memory offset separately this is required so that BSS symbols are handled
   // properly as the BSS symbols only occupy memory size and not file size
diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h
index 913644e..4fa1565 100644
--- a/lld/lib/ReaderWriter/MachO/File.h
+++ b/lld/lib/ReaderWriter/MachO/File.h
@@ -44,7 +44,7 @@
     }
     DefinedAtom::Alignment align(
         inSection->alignment,
-        sectionOffset % ((uint64_t)1 << inSection->alignment));
+        sectionOffset % inSection->alignment.get());
     MachODefinedAtom *atom =
         new (allocator()) MachODefinedAtom(*this, name, scope, type, merge,
                                            thumb, noDeadStrip, content, align);
@@ -67,7 +67,7 @@
     }
     DefinedAtom::Alignment align(
         inSection->alignment,
-        sectionOffset % ((uint64_t)1 << inSection->alignment));
+        sectionOffset % inSection->alignment.get());
     MachODefinedCustomSectionAtom *atom =
         new (allocator()) MachODefinedCustomSectionAtom(*this, name, scope, type,
                                                         merge, thumb,
@@ -86,7 +86,7 @@
     }
     DefinedAtom::Alignment align(
         inSection->alignment,
-        sectionOffset % ((uint64_t)1 << inSection->alignment));
+        sectionOffset % inSection->alignment.get());
     MachODefinedAtom *atom =
        new (allocator()) MachODefinedAtom(*this, name, scope, size, noDeadStrip,
                                           align);
diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index 1ae5be4..0940e31 100644
--- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -732,10 +732,7 @@
 
 void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
                                               PowerOf2 align2) {
-  SectionAlign entry;
-  entry.segmentName = seg;
-  entry.sectionName = sect;
-  entry.align2 = align2;
+  SectionAlign entry = { seg, sect, align2 };
   _sectAligns.push_back(entry);
 }
 
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
index 70bcde2..c1db36c 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
@@ -114,7 +114,7 @@
   StringRef       sectionName;
   SectionType     type;
   SectionAttr     attributes;
-  uint32_t        alignment;
+  PowerOf2        alignment;
   Hex64           address;
   ArrayRef<uint8_t> content;
   Relocations     relocations;
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
index 07a6dbf..5b3d942 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
@@ -297,7 +297,7 @@
           section.type = (SectionType)(read32(&sect->flags, isBig) &
                                        SECTION_TYPE);
           section.attributes  = read32(&sect->flags, isBig) & SECTION_ATTRIBUTES;
-          section.alignment   = read32(&sect->align, isBig);
+          section.alignment   = PowerOf2(read32(&sect->align, isBig));
           section.address     = read64(&sect->addr, isBig);
           const uint8_t *content =
             (const uint8_t *)start + read32(&sect->offset, isBig);
@@ -341,7 +341,7 @@
                                        SECTION_TYPE);
           section.attributes =
               read32((const uint8_t *)&sect->flags, isBig) & SECTION_ATTRIBUTES;
-          section.alignment   = read32(&sect->align, isBig);
+          section.alignment   = PowerOf2(read32(&sect->align, isBig));
           section.address     = read32(&sect->addr, isBig);
           const uint8_t *content =
             (const uint8_t *)start + read32(&sect->offset, isBig);
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index be7acf9..0f8bba4 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -291,7 +291,7 @@
     uint64_t offset = _startOfSectionsContent;
     for (const Section &sect : file.sections) {
       if (sect.type != llvm::MachO::S_ZEROFILL) {
-        offset = llvm::RoundUpToAlignment(offset, 1 << sect.alignment);
+        offset = llvm::RoundUpToAlignment(offset, sect.alignment.get());
         _sectInfo[&sect].fileOffset = offset;
         offset += sect.content.size();
       } else {
@@ -613,7 +613,7 @@
     sout->addr = sin.address;
     sout->size = sin.content.size();
     sout->offset = _sectInfo[&sin].fileOffset;
-    sout->align = sin.alignment;
+    sout->align = llvm::Log2_32(sin.alignment.get());
     sout->reloff = sin.relocations.empty() ? 0 : relOffset;
     sout->nreloc = sin.relocations.size();
     sout->flags = sin.type | sin.attributes;
@@ -661,7 +661,7 @@
         sect->offset  = 0;
       else
         sect->offset  = section->address - seg.address + segInfo.fileOffset;
-      sect->align     = section->alignment;
+      sect->align     = llvm::Log2_32(section->alignment.get());
       sect->reloff    = 0;
       sect->nreloc    = 0;
       sect->flags     = section->type | section->attributes;
@@ -1343,4 +1343,3 @@
 } // namespace normalized
 } // namespace mach_o
 } // namespace lld
-
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index eda1172..3f8a944 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -328,7 +328,7 @@
   // Figure out offset for atom in this section given alignment constraints.
   uint64_t offset = sect->size;
   DefinedAtom::Alignment atomAlign = atom->alignment();
-  uint64_t align2 = 1 << atomAlign.powerOf2;
+  uint64_t align2 = atomAlign.powerOf2.get();
   uint64_t requiredModulus = atomAlign.modulus;
   uint64_t currentModulus = (offset % align2);
   if ( currentModulus != requiredModulus ) {
@@ -338,7 +338,7 @@
       offset += align2+requiredModulus-currentModulus;
   }
   // Record max alignment of any atom in this section.
-  if ( atomAlign.powerOf2 > sect->alignment )
+  if (align2 > sect->alignment.get())
     sect->alignment = atomAlign.powerOf2;
   // Assign atom to this section with this offset.
   AtomInfo ai = {atom, offset};
@@ -454,7 +454,7 @@
 }
 
 uint64_t Util::alignTo(uint64_t value, PowerOf2 align2) {
-  return llvm::RoundUpToAlignment(value, 1 << align2);
+  return llvm::RoundUpToAlignment(value, align2.get());
 }
 
 
@@ -477,7 +477,7 @@
   for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); ++it) {
     SectionInfo *sect = *it;
     taddr -= sect->size;
-    taddr = taddr & (0 - (1 << sect->alignment));
+    taddr = taddr & (0 - sect->alignment.get());
   }
   int64_t padding = taddr - hlcSize;
   while (padding < 0)
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
index ae14d75..3635c62 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
@@ -53,6 +53,20 @@
 namespace llvm {
 namespace yaml {
 
+template <>
+struct ScalarTraits<lld::PowerOf2> {
+  static void output(const lld::PowerOf2 &value, void*, raw_ostream &out) {
+    out << llvm::format("%d", value);
+  }
+  static StringRef input(StringRef scalar, void*, lld::PowerOf2 &result) {
+    uint32_t value;
+    scalar.getAsInteger(10, value);
+    result = lld::PowerOf2(value);
+    return StringRef();
+  }
+  static bool mustQuote(StringRef) { return false; }
+};
+
 // A vector of Sections is a sequence.
 template<>
 struct SequenceTraits< std::vector<Section> > {
@@ -276,7 +290,7 @@
     io.mapRequired("section",         sect.sectionName);
     io.mapRequired("type",            sect.type);
     io.mapOptional("attributes",      sect.attributes);
-    io.mapOptional("alignment",       sect.alignment, 0U);
+    io.mapOptional("alignment",       sect.alignment, lld::PowerOf2(0));
     io.mapRequired("address",         sect.address);
     if (sect.type == llvm::MachO::S_ZEROFILL) {
       // S_ZEROFILL sections use "size:" instead of "content:"
@@ -799,4 +813,3 @@
 } // namespace normalized
 } // namespace mach_o
 } // namespace lld
-
diff --git a/lld/lib/ReaderWriter/Native/WriterNative.cpp b/lld/lib/ReaderWriter/Native/WriterNative.cpp
index 5e01a6c..658229e 100644
--- a/lld/lib/ReaderWriter/Native/WriterNative.cpp
+++ b/lld/lib/ReaderWriter/Native/WriterNative.cpp
@@ -416,7 +416,7 @@
   NativeAtomAttributesV1 computeAttributesV1(const DefinedAtom& atom) {
     NativeAtomAttributesV1 attrs;
     attrs.sectionNameOffset = sectionNameOffset(atom);
-    attrs.align2            = atom.alignment().powerOf2;
+    attrs.align2            = llvm::Log2_32(atom.alignment().powerOf2.get());
     attrs.alignModulus      = atom.alignment().modulus;
     attrs.scope             = atom.scope();
     attrs.interposable      = atom.interposable();
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
index d34e2d3..024a1c2 100644
--- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
@@ -849,10 +849,10 @@
   // the section. We restore that here.
   if (_atomLayouts.empty())
     return _ctx.getPageSize();
-  int align = _ctx.getPageSize();
+  unsigned align = _ctx.getPageSize();
   for (auto atomLayout : _atomLayouts) {
     auto *atom = cast<const DefinedAtom>(atomLayout->_atom);
-    align = std::max(align, 1 << atom->alignment().powerOf2);
+    align = std::max(align, (unsigned)atom->alignment().powerOf2.get());
   }
   return align;
 }
@@ -860,7 +860,7 @@
 void AtomChunk::appendAtom(const DefinedAtom *atom) {
   // Atom may have to be at a proper alignment boundary. If so, move the
   // pointer to make a room after the last atom before adding new one.
-  _size = llvm::RoundUpToAlignment(_size, 1 << atom->alignment().powerOf2);
+  _size = llvm::RoundUpToAlignment(_size, atom->alignment().powerOf2.get());
 
   // Create an AtomLayout and move the current pointer.
   auto *layout = new (_alloc) AtomLayout(atom, _size, _size);
diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index 64d595c..cfd3355 100644
--- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -484,9 +484,9 @@
   static void output(const lld::DefinedAtom::Alignment &value, void *ctxt,
                      raw_ostream &out) {
     if (value.modulus == 0) {
-      out << llvm::format("%d", 1U << value.powerOf2);
+      out << llvm::format("%d", value.powerOf2.get());
     } else {
-      out << llvm::format("%d mod %d", value.modulus, 1U << value.powerOf2);
+      out << llvm::format("%d mod %d", value.modulus, value.powerOf2.get());
     }
   }
 
@@ -509,7 +509,7 @@
     if (scalar.getAsInteger(0, power)) {
       return "malformed alignment power";
     }
-    value.powerOf2 = llvm::Log2_64(power);
+    value.powerOf2 = PowerOf2(llvm::Log2_64(power));
     if (value.modulus >= power) {
       return "malformed alignment, modulus too large for power";
     }