Start writing out some relocation sections (text).

Pass the full assembler pointer to the elf writer, so
that it has access to both the text buffer and the fixups.

Remove some child classes of AssemblerFixups. They didn't
really do much, and were pretty much identical to the
original AssemblerFixup class. Dart had a virtual method
for fixups to do necessary patching, but we currently
don't do the patching and just emit the relocations.
TODO see if patching is more efficient than writing out
relocations and letting the linker do the work.

This CL also makes AssemblerFixups POD.

Change the fixup kind to be a plain unsigned int, which
the target can fill w/ target/container-specific values.

Move the fwd declaration of Assembler to IceDefs and remove
the others. Do similar for fwd declaration refactoring for
ELFWriter.

Make the createAssembler method return a std::unique_ptr.

BUG=none
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/828873002
diff --git a/src/IceFixups.cpp b/src/IceFixups.cpp
new file mode 100644
index 0000000..52bb0dd
--- /dev/null
+++ b/src/IceFixups.cpp
@@ -0,0 +1,52 @@
+//===- subzero/src/IceFixups.cpp - Implementation of Assembler Fixups -----===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AssemblerFixup class, a very basic
+// target-independent representation of a fixup or relocation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IceFixups.h"
+#include "IceOperand.h"
+
+namespace Ice {
+
+RelocOffsetT AssemblerFixup::offset() const {
+  if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(value_))
+    return CR->getOffset();
+  return 0;
+}
+
+IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const {
+  std::string Buffer;
+  llvm::raw_string_ostream Str(Buffer);
+  const Constant *C = value_;
+  if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(C)) {
+    if (CR->getSuppressMangling())
+      Str << CR->getName();
+    else
+      Str << Ctx->mangleName(CR->getName());
+  } else {
+    // NOTE: currently only float/doubles are put into constant pools.
+    // In the future we may put integers as well.
+    assert(llvm::isa<ConstantFloat>(C) || llvm::isa<ConstantDouble>(C));
+    C->emitPoolLabel(Str);
+  }
+  return Str.str();
+}
+
+void AssemblerFixup::emit(GlobalContext *Ctx) const {
+  Ostream &Str = Ctx->getStrEmit();
+  Str << symbol(Ctx);
+  RelocOffsetT Offset = offset();
+  if (Offset)
+    Str << " + " << Offset;
+}
+
+} // end of namespace Ice