ThreadLocal: Return a mutable pointer if templated with a non-const type
[oota-llvm.git] / include / llvm / Support / OutputBuffer.h
index 24a655cef6c16352b6d65a8a1537753f454fddd2..6b98e99e28e06face9cbef5997206ee4d9e5a5a5 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Bill Wendling and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
 #define LLVM_SUPPORT_OUTPUTBUFFER_H
 
+#include <cassert>
+#include <string>
 #include <vector>
 
 namespace llvm {
-  
+
   class OutputBuffer {
     /// Output buffer.
     std::vector<unsigned char> &Output;
@@ -26,19 +28,17 @@ namespace llvm {
     /// machine directly, indicating what header values and flags to set.
     bool is64Bit, isLittleEndian;
   public:
-    OutputBuffer(const TargetMachine& TM,
-                 std::vector<unsigned char> &Out) : Output(Out) {
-      is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
-      isLittleEndian = TM.getTargetData()->isLittleEndian();
-    }
+    OutputBuffer(std::vector<unsigned char> &Out,
+                 bool is64bit, bool le)
+      : Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
 
     // align - Emit padding into the file until the current output position is
     // aligned to the specified power of two boundary.
     void align(unsigned Boundary) {
       assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
-             "Must alitypedef std::vector<unsigned char> DataBuffer;gn to 2^k boundary");
+             "Must align to 2^k boundary");
       size_t Size = Output.size();
-      
+
       if (Size & (Boundary - 1)) {
         // Add padding to get alignment to the correct place.
         size_t Pad = Boundary - (Size & (Boundary - 1));
@@ -107,13 +107,15 @@ namespace llvm {
       else
         outxword(X);
     }
-    void outstring(std::string &S, unsigned Length) {
-      unsigned len_to_copy = S.length() < Length ? S.length() : Length;
-      unsigned len_to_fill = S.length() < Length ? Length - S.length() : 0;
-      
+    void outstring(const std::string &S, unsigned Length) {
+      unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length
+        ? static_cast<unsigned>(S.length()) : Length;
+      unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length
+        ? Length - static_cast<unsigned>(S.length()) : 0;
+
       for (unsigned i = 0; i < len_to_copy; ++i)
         outbyte(S[i]);
-      
+
       for (unsigned i = 0; i < len_to_fill; ++i)
         outbyte(0);
     }
@@ -133,14 +135,32 @@ namespace llvm {
       P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
       P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
     }
+    void fixxword(uint64_t X, unsigned Offset) {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 56)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 48)) & 255;
+      P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255;
+      P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255;
+      P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255;
+      P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255;
+      P[6] = (X >> (isLittleEndian ? 48 :  8)) & 255;
+      P[7] = (X >> (isLittleEndian ? 56 :  0)) & 255;
+    }
     void fixaddr(uint64_t X, unsigned Offset) {
       if (!is64Bit)
         fixword((unsigned)X, Offset);
       else
-        assert(0 && "Emission of 64-bit data not implemented yet!");
+        fixxword(X, Offset);
+    }
+
+    unsigned char &operator[](unsigned Index) {
+      return Output[Index];
+    }
+    const unsigned char &operator[](unsigned Index) const {
+      return Output[Index];
     }
   };
-  
+
 } // end llvm namespace
 
 #endif // LLVM_SUPPORT_OUTPUTBUFFER_H