5e6eaa05c226aa7e79197c985c888ab0f66b210d
[oota-llvm.git] / include / llvm / Bitcode / Serialize.h
1 //==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Ted Kremenek and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the interface for generic object serialization to
11 // LLVM bitcode.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_BITCODE_SERIALIZE_OUTPUT
16 #define LLVM_BITCODE_SERIALIZE_OUTPUT
17
18 #include "llvm/Bitcode/Serialization.h"
19 #include "llvm/Bitcode/BitstreamWriter.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/DenseMap.h"
22
23 namespace llvm {
24
25 class Serializer {
26   BitstreamWriter& Stream;
27   SmallVector<uint64_t,10> Record;
28   unsigned BlockLevel;
29   
30   typedef DenseMap<const void*,unsigned> MapTy;
31   MapTy PtrMap;
32   
33 public:
34   explicit Serializer(BitstreamWriter& stream);
35   ~Serializer();
36
37   //==------------------------------------------------==//
38   // Template-based dispatch to emit arbitrary types.
39   //==------------------------------------------------==//
40   
41   template <typename T> 
42   inline void Emit(const T& X) { SerializeTrait<T>::Emit(*this,X); }
43   
44   //==------------------------------------------------==//
45   // Methods to emit primitive types.
46   //==------------------------------------------------==//  
47   
48   void EmitInt(uint64_t X);
49   void EmitSInt(int64_t X);
50   
51   inline void EmitBool(bool X) { EmitInt(X); }
52   void EmitCStr(const char* beg, const char* end);
53   void EmitCStr(const char* cstr);
54   
55   void EmitPtr(const void* ptr) { EmitInt(getPtrId(ptr)); }
56   
57   template <typename T>
58   inline void EmitRef(const T& ref) { EmitPtr(&ref); }
59   
60   template <typename T>
61   inline void EmitOwnedPtr(T* ptr) {
62     EmitPtr(ptr);
63     if (ptr) SerializeTrait<T>::Emit(*this,*ptr);
64   }
65   
66   
67   //==------------------------------------------------==//
68   // Batch emission of pointers.
69   //==------------------------------------------------==//
70     
71   template <typename T1, typename T2>
72   void BatchEmitOwnedPtrs(T1* p1, T2* p2) {
73     EmitPtr(p1);
74     EmitPtr(p2);
75     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
76     if (p2) SerializeTrait<T2>::Emit(*this,*p2);    
77   }
78
79   template <typename T1, typename T2, typename T3>
80   void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3) {
81     EmitPtr(p1);
82     EmitPtr(p2);
83     EmitPtr(p3);
84     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
85     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
86     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
87   }
88   
89   template <typename T1, typename T2, typename T3, typename T4>
90   void BatchEmitOwnedPtrs(T1* p1, T2* p2, T3* p3, T4& p4) {
91     EmitPtr(p1);
92     EmitPtr(p2);
93     EmitPtr(p3);
94     EmitPtr(p4);
95     if (p1) SerializeTrait<T1>::Emit(*this,*p1);
96     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
97     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
98     if (p4) SerializeTrait<T4>::Emit(*this,*p4);
99   }
100
101   template <typename T>
102   void BatchEmitOwnedPtrs(unsigned NumPtrs, T* const * Ptrs) {
103     for (unsigned i = 0; i < NumPtrs; ++i)
104       EmitPtr(Ptrs[i]);
105
106     for (unsigned i = 0; i < NumPtrs; ++i)
107       if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]);
108   }
109   
110   template <typename T1, typename T2>
111   void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs, T2* p2) {
112     
113     for (unsigned i = 0; i < NumT1Ptrs; ++i)
114       EmitPtr(Ptrs[i]);
115     
116     EmitPtr(p2);
117     
118     for (unsigned i = 0; i < NumT1Ptrs; ++i)
119       if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
120     
121     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
122   }
123   
124   template <typename T1, typename T2, typename T3>
125   void BatchEmitOwnedPtrs(unsigned NumT1Ptrs, T1* const * Ptrs,
126                           T2* p2, T3* p3) {
127     
128     for (unsigned i = 0; i < NumT1Ptrs; ++i)
129       EmitPtr(Ptrs[i]);
130     
131     EmitPtr(p2);
132     EmitPtr(p3);
133     
134     for (unsigned i = 0; i < NumT1Ptrs; ++i)
135       if (Ptrs[i]) SerializeTrait<T1>::Emit(*this,*Ptrs[i]);
136     
137     if (p2) SerializeTrait<T2>::Emit(*this,*p2);
138     if (p3) SerializeTrait<T3>::Emit(*this,*p3);
139   }
140   
141   //==------------------------------------------------==//
142   // Emitter Functors
143   //==------------------------------------------------==//
144   
145   template <typename T>
146   struct Emitter0 {
147     Serializer& S;    
148     Emitter0(Serializer& s) : S(s) {}
149     void operator()(const T& x) const {
150       SerializeTrait<T>::Emit(S,x);
151     }
152   };
153   
154   template <typename T, typename Arg1>
155   struct Emitter1 {
156     Serializer& S;
157     Arg1 A1;
158     
159     Emitter1(Serializer& s, Arg1 a1) : S(s), A1(a1) {}
160     void operator()(const T& x) const {
161       SerializeTrait<T>::Emit(S,x,A1);
162     }
163   };
164   
165   template <typename T, typename Arg1, typename Arg2>
166   struct Emitter2 {
167     Serializer& S;
168     Arg1 A1;
169     Arg2 A2;
170     
171     Emitter2(Serializer& s, Arg1 a1, Arg2 a2) : S(s), A1(a1), A2(a2) {}
172     void operator()(const T& x) const {
173       SerializeTrait<T>::Emit(S,x,A1,A2);
174     }
175   };
176   
177   template <typename T>
178   Emitter0<T> MakeEmitter() {
179     return Emitter0<T>(*this);
180   }
181   
182   template <typename T, typename Arg1>
183   Emitter1<T,Arg1> MakeEmitter(Arg1 a1) {
184     return Emitter1<T,Arg1>(*this,a1);
185   }
186   
187   template <typename T, typename Arg1, typename Arg2>
188   Emitter2<T,Arg1,Arg2> MakeEmitter(Arg1 a1, Arg2 a2) {
189     return Emitter2<T,Arg1,Arg2>(*this,a1,a2);
190   }
191   
192   //==------------------------------------------------==//
193   // Misc. query and block/record manipulation methods.
194   //==------------------------------------------------==//  
195     
196   bool isRegistered(const void* p) const;
197   
198   void FlushRecord() { if (inRecord()) EmitRecord(); }  
199   void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3);
200   void ExitBlock();    
201   
202 private:
203   void EmitRecord();
204   inline bool inRecord() { return Record.size() > 0; }
205   SerializedPtrID getPtrId(const void* ptr);
206 };
207
208 } // end namespace llvm
209 #endif