| Ted Kremenek | cc92709 | 2007-12-13 17:54:02 +0000 | [diff] [blame] | 1 | //===--- TranslationUnit.cpp - Abstraction for Translation Units ----------===// | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 7 | // | 
 | 8 | // FIXME: This should eventually be moved out of the driver, or replaced | 
 | 9 | //        with its eventual successor. | 
 | 10 | // | 
 | 11 | //===----------------------------------------------------------------------===// | 
 | 12 |  | 
| Ted Kremenek | 525fdbc | 2007-12-18 21:36:21 +0000 | [diff] [blame] | 13 | #include "clang/AST/TranslationUnit.h" | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 14 |  | 
 | 15 | #include "clang/Basic/TargetInfo.h" | 
 | 16 | #include "clang/Basic/SourceManager.h" | 
 | 17 | #include "clang/AST/AST.h" | 
 | 18 |  | 
 | 19 | #include "llvm/Bitcode/Serialize.h" | 
 | 20 | #include "llvm/Bitcode/Deserialize.h" | 
 | 21 | #include "llvm/Support/MemoryBuffer.h" | 
 | 22 | #include "llvm/System/Path.h" | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 23 |  | 
| Ted Kremenek | 27f8a28 | 2008-05-20 00:43:19 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/OwningPtr.h" | 
 | 25 | #include "llvm/ADT/DenseSet.h" | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 26 |  | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 27 | using namespace clang; | 
 | 28 |  | 
| Ted Kremenek | 63ea863 | 2007-12-19 19:27:38 +0000 | [diff] [blame] | 29 | enum { BasicMetadataBlock = 1, | 
 | 30 |        ASTContextBlock = 2, | 
 | 31 |        DeclsBlock = 3 }; | 
 | 32 |  | 
| Sam Bishop | 0f9c72f | 2008-04-03 14:20:28 +0000 | [diff] [blame] | 33 | TranslationUnit::~TranslationUnit() { | 
| Eli Friedman | 5f1adf8 | 2008-05-21 05:33:10 +0000 | [diff] [blame] | 34 |   if (OwnsDecls) { | 
| Eli Friedman | 1108e7d | 2008-05-21 05:01:55 +0000 | [diff] [blame] | 35 |     llvm::DenseSet<Decl*> Killed; | 
| Douglas Gregor | 3dda64e | 2008-10-27 12:50:38 +0000 | [diff] [blame] | 36 |     for (std::vector<Decl*>::reverse_iterator I=TopLevelDecls.rbegin(),  | 
 | 37 |                                               E=TopLevelDecls.rend();  | 
 | 38 |          I!=E; ++I) { | 
| Eli Friedman | 1108e7d | 2008-05-21 05:01:55 +0000 | [diff] [blame] | 39 |       if (Killed.count(*I)) continue; | 
 | 40 |  | 
 | 41 |       Killed.insert(*I); | 
| Ted Kremenek | 1a726d7 | 2008-06-06 17:21:42 +0000 | [diff] [blame] | 42 |        | 
 | 43 |       // FIXME: This is a horrible hack.  Because there is no clear ownership | 
 | 44 |       //  role between ObjCInterfaceDecls and the ObjCPropertyDecls that they | 
 | 45 |       //  reference, we need to destroy ObjCPropertyDecls here.  This will | 
 | 46 |       //  eventually be fixed when the ownership of ObjCPropertyDecls gets | 
 | 47 |       //  cleaned up. | 
 | 48 |       if (ObjCInterfaceDecl* IDecl = dyn_cast<ObjCInterfaceDecl>(*I)) | 
| Steve Naroff | 09c4719 | 2009-01-09 15:36:25 +0000 | [diff] [blame] | 49 |         for (ObjCInterfaceDecl::prop_iterator ID=IDecl->prop_begin(), | 
 | 50 |              ED=IDecl->prop_end(); ID!=ED; ++ID) { | 
| Ted Kremenek | 1c8a413 | 2008-06-06 19:48:57 +0000 | [diff] [blame] | 51 |           if (!*ID || Killed.count(*ID)) continue; | 
| Ted Kremenek | 1a726d7 | 2008-06-06 17:21:42 +0000 | [diff] [blame] | 52 |           Killed.insert(*ID); | 
 | 53 |           (*ID)->Destroy(*Context); | 
 | 54 |         } | 
 | 55 |        | 
| Ted Kremenek | 1c8a413 | 2008-06-06 19:48:57 +0000 | [diff] [blame] | 56 |       // FIXME: This is a horrible hack.  Because there is no clear ownership | 
 | 57 |       //  role between ObjCProtocolDecls and the ObjCPropertyDecls that they | 
 | 58 |       //  reference, we need to destroy ObjCPropertyDecls here.  This will | 
 | 59 |       //  eventually be fixed when the ownership of ObjCPropertyDecls gets | 
 | 60 |       //  cleaned up. | 
 | 61 |       if (ObjCProtocolDecl* PDecl = dyn_cast<ObjCProtocolDecl>(*I)) | 
| Steve Naroff | 09c4719 | 2009-01-09 15:36:25 +0000 | [diff] [blame] | 62 |         for (ObjCProtocolDecl::prop_iterator ID=PDecl->prop_begin(), | 
 | 63 |              ED=PDecl->prop_end(); ID!=ED; ++ID) { | 
| Ted Kremenek | 400d95f | 2008-06-06 20:11:53 +0000 | [diff] [blame] | 64 |           if (!*ID || Killed.count(*ID)) continue; | 
 | 65 |           Killed.insert(*ID); | 
 | 66 |           (*ID)->Destroy(*Context); | 
| Ted Kremenek | 1c8a413 | 2008-06-06 19:48:57 +0000 | [diff] [blame] | 67 |         } | 
| Ted Kremenek | 400d95f | 2008-06-06 20:11:53 +0000 | [diff] [blame] | 68 |              | 
 | 69 |       // FIXME: There is no clear ownership policy now for ObjCInterfaceDecls | 
 | 70 |       //  referenced by ObjCClassDecls.  Some of them can be forward decls that | 
| Ted Kremenek | 05ac3ef | 2008-06-06 21:05:33 +0000 | [diff] [blame] | 71 |       //  are never later defined (and forward decls can be referenced by | 
 | 72 |       //  multiple ObjCClassDecls) or the ObjCInterfaceDecl later | 
 | 73 |       //  becomes a real definition.  | 
| Ted Kremenek | 400d95f | 2008-06-06 20:11:53 +0000 | [diff] [blame] | 74 |       //  Ideally we should have separate objects for forward declarations and | 
 | 75 |       //  definitions, obviating this problem.  Because of this situation, | 
 | 76 |       //  referenced ObjCInterfaceDecls are destroyed here.       | 
 | 77 |       if (ObjCClassDecl* CDecl = dyn_cast<ObjCClassDecl>(*I)) | 
 | 78 |         for (ObjCClassDecl::iterator ID=CDecl->begin(), | 
 | 79 |              ED=CDecl->end(); ID!=ED; ++ID) {           | 
 | 80 |           if (!*ID || Killed.count(*ID)) continue; | 
 | 81 |           Killed.insert(*ID); | 
 | 82 |           (*ID)->Destroy(*Context); | 
 | 83 |         } | 
| Ted Kremenek | 05ac3ef | 2008-06-06 21:05:33 +0000 | [diff] [blame] | 84 |        | 
 | 85 |       // FIXME: There is no clear ownership policy now for ObjCProtocolDecls | 
 | 86 |       //  referenced by ObjCForwardProtocolDecl.  Some of them can be forward  | 
 | 87 |       //  decls that are never later defined (and forward decls can be | 
 | 88 |       //  referenced by multiple ObjCClassDecls) or the ObjCProtocolDecl  | 
 | 89 |       //  later becomes a real definition.  | 
 | 90 |       //  Ideally we should have separate objects for forward declarations and | 
 | 91 |       //  definitions, obviating this problem.  Because of this situation, | 
 | 92 |       //  referenced ObjCProtocolDecls are destroyed here.   | 
 | 93 |       if (ObjCForwardProtocolDecl* FDec = dyn_cast<ObjCForwardProtocolDecl>(*I)) | 
 | 94 |         for (ObjCForwardProtocolDecl::iterator ID=FDec->begin(), | 
 | 95 |              ED=FDec->end(); ID!=ED; ++ID) {           | 
 | 96 |           if (!*ID || Killed.count(*ID)) continue; | 
 | 97 |           Killed.insert(*ID); | 
 | 98 |           (*ID)->Destroy(*Context); | 
 | 99 |         } | 
 | 100 |        | 
| Ted Kremenek | 400d95f | 2008-06-06 20:11:53 +0000 | [diff] [blame] | 101 |              | 
| Eli Friedman | 1108e7d | 2008-05-21 05:01:55 +0000 | [diff] [blame] | 102 |       (*I)->Destroy(*Context); | 
 | 103 |     } | 
| Eli Friedman | 5f1adf8 | 2008-05-21 05:33:10 +0000 | [diff] [blame] | 104 |   } | 
| Eli Friedman | 1108e7d | 2008-05-21 05:01:55 +0000 | [diff] [blame] | 105 |  | 
| Eli Friedman | 5f1adf8 | 2008-05-21 05:33:10 +0000 | [diff] [blame] | 106 |   if (OwnsMetaData && Context) { | 
| Ted Kremenek | c1e9dea | 2008-04-23 16:25:39 +0000 | [diff] [blame] | 107 |     // The ASTContext object has the sole references to the IdentifierTable | 
 | 108 |     // Selectors, and the Target information.  Go and delete them, since | 
 | 109 |     // the TranslationUnit effectively owns them. | 
| Eli Friedman | 5f1adf8 | 2008-05-21 05:33:10 +0000 | [diff] [blame] | 110 |      | 
| Ted Kremenek | c1e9dea | 2008-04-23 16:25:39 +0000 | [diff] [blame] | 111 |     delete &(Context->Idents); | 
 | 112 |     delete &(Context->Selectors); | 
 | 113 |     delete &(Context->Target); | 
 | 114 |     delete Context; | 
 | 115 |   }   | 
| Sam Bishop | 71de20e | 2008-04-03 05:35:20 +0000 | [diff] [blame] | 116 | } | 
| Ted Kremenek | 63ea863 | 2007-12-19 19:27:38 +0000 | [diff] [blame] | 117 |  | 
| Zhongxing Xu | 8ce6666 | 2008-12-21 04:46:06 +0000 | [diff] [blame] | 118 | bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,                    | 
| Ted Kremenek | c1e9dea | 2008-04-23 16:25:39 +0000 | [diff] [blame] | 119 |                                const llvm::sys::Path& Filename) { | 
 | 120 |  | 
 | 121 |   return TU ? EmitASTBitcodeFile(*TU, Filename) : false; | 
 | 122 | } | 
 | 123 |    | 
| Ted Kremenek | 0ce902b | 2008-07-10 22:10:48 +0000 | [diff] [blame] | 124 | bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,  | 
 | 125 |                                  std::vector<unsigned char>& Buffer) { | 
 | 126 |  | 
 | 127 |   return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false; | 
 | 128 | } | 
 | 129 |  | 
 | 130 | bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,  | 
 | 131 |                                  std::ostream& Stream) { | 
 | 132 |  | 
 | 133 |   return TU ? EmitASTBitcodeStream(*TU, Stream) : false; | 
 | 134 | } | 
 | 135 |  | 
 | 136 | bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,  | 
 | 137 |                                  std::vector<unsigned char>& Buffer) { | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 138 |   // Create bitstream. | 
 | 139 |   llvm::BitstreamWriter Stream(Buffer); | 
 | 140 |    | 
 | 141 |   // Emit the preamble. | 
 | 142 |   Stream.Emit((unsigned)'B', 8); | 
 | 143 |   Stream.Emit((unsigned)'C', 8); | 
 | 144 |   Stream.Emit(0xC, 4); | 
 | 145 |   Stream.Emit(0xF, 4); | 
 | 146 |   Stream.Emit(0xE, 4); | 
 | 147 |   Stream.Emit(0x0, 4); | 
 | 148 |    | 
 | 149 |   {  | 
 | 150 |     // Create serializer.  Placing it in its own scope assures any necessary | 
 | 151 |     // finalization of bits to the buffer in the serializer's dstor.     | 
 | 152 |     llvm::Serializer Sezr(Stream);   | 
 | 153 |      | 
 | 154 |     // Emit the translation unit. | 
| Ted Kremenek | dca2927 | 2007-12-18 21:44:50 +0000 | [diff] [blame] | 155 |     TU.Emit(Sezr); | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 156 |   } | 
 | 157 |    | 
| Ted Kremenek | 0ce902b | 2008-07-10 22:10:48 +0000 | [diff] [blame] | 158 |   return true; | 
 | 159 | } | 
 | 160 |  | 
 | 161 | bool clang::EmitASTBitcodeStream(const TranslationUnit& TU,  | 
 | 162 |                                  std::ostream& Stream) {   | 
 | 163 |    | 
 | 164 |   // Reserve 256K for bitstream buffer. | 
 | 165 |   std::vector<unsigned char> Buffer; | 
 | 166 |   Buffer.reserve(256*1024); | 
 | 167 |    | 
 | 168 |   EmitASTBitcodeBuffer(TU,Buffer); | 
 | 169 |    | 
 | 170 |   // Write the bits to disk. | 
 | 171 |   Stream.write((char*)&Buffer.front(), Buffer.size()); | 
 | 172 |   return true; | 
 | 173 | } | 
 | 174 |  | 
 | 175 | bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,  | 
 | 176 |                                const llvm::sys::Path& Filename) {   | 
 | 177 |    | 
 | 178 |   // Reserve 256K for bitstream buffer. | 
 | 179 |   std::vector<unsigned char> Buffer; | 
 | 180 |   Buffer.reserve(256*1024); | 
 | 181 |    | 
 | 182 |   EmitASTBitcodeBuffer(TU,Buffer); | 
 | 183 |    | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 184 |   // Write the bits to disk.  | 
 | 185 |   if (FILE* fp = fopen(Filename.c_str(),"wb")) { | 
 | 186 |     fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp); | 
 | 187 |     fclose(fp); | 
 | 188 |     return true; | 
 | 189 |   } | 
 | 190 |  | 
 | 191 |   return false;   | 
 | 192 | } | 
 | 193 |  | 
 | 194 | void TranslationUnit::Emit(llvm::Serializer& Sezr) const { | 
 | 195 |  | 
 | 196 |   // ===---------------------------------------------------===/ | 
 | 197 |   //      Serialize the top-level decls. | 
 | 198 |   // ===---------------------------------------------------===/   | 
 | 199 |    | 
 | 200 |   Sezr.EnterBlock(DeclsBlock); | 
 | 201 |  | 
 | 202 |   // Only serialize the head of a decl chain.  The ASTConsumer interfaces | 
 | 203 |   // provides us with each top-level decl, including those nested in | 
 | 204 |   // a decl chain, so we may be passed decls that are already serialized.   | 
 | 205 |   for (const_iterator I=begin(), E=end(); I!=E; ++I)  | 
 | 206 |       if (!Sezr.isRegistered(*I)) | 
 | 207 |         Sezr.EmitOwnedPtr(*I); | 
 | 208 |    | 
 | 209 |   Sezr.ExitBlock(); | 
 | 210 |    | 
 | 211 |   // ===---------------------------------------------------===/ | 
 | 212 |   //      Serialize the "Translation Unit" metadata. | 
 | 213 |   // ===---------------------------------------------------===/ | 
 | 214 |  | 
 | 215 |   // Emit ASTContext. | 
 | 216 |   Sezr.EnterBlock(ASTContextBlock);   | 
 | 217 |   Sezr.EmitOwnedPtr(Context);   | 
| Zhongxing Xu | c994bb2 | 2008-12-21 13:00:52 +0000 | [diff] [blame] | 218 |   Sezr.ExitBlock();      // exit "ASTContextBlock" | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 219 |    | 
 | 220 |   Sezr.EnterBlock(BasicMetadataBlock); | 
 | 221 |    | 
| Ted Kremenek | e7d07d1 | 2008-06-04 15:55:15 +0000 | [diff] [blame] | 222 |   // Block for SourceManager and Target.  Allows easy skipping | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 223 |   // around to the block for the Selectors during deserialization. | 
 | 224 |   Sezr.EnterBlock(); | 
| Ted Kremenek | fdfc198 | 2007-12-19 22:24:34 +0000 | [diff] [blame] | 225 |      | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 226 |   // Emit the SourceManager. | 
| Ted Kremenek | 7a9d49f | 2007-12-11 21:27:55 +0000 | [diff] [blame] | 227 |   Sezr.Emit(Context->getSourceManager()); | 
| Ted Kremenek | e7d07d1 | 2008-06-04 15:55:15 +0000 | [diff] [blame] | 228 |      | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 229 |   // Emit the Target. | 
 | 230 |   Sezr.EmitPtr(&Context->Target); | 
 | 231 |   Sezr.EmitCStr(Context->Target.getTargetTriple()); | 
 | 232 |    | 
| Zhongxing Xu | c994bb2 | 2008-12-21 13:00:52 +0000 | [diff] [blame] | 233 |   Sezr.ExitBlock(); // exit "SourceManager and Target Block" | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 234 |    | 
 | 235 |   // Emit the Selectors. | 
 | 236 |   Sezr.Emit(Context->Selectors); | 
 | 237 |    | 
 | 238 |   // Emit the Identifier Table. | 
 | 239 |   Sezr.Emit(Context->Idents); | 
 | 240 |    | 
| Zhongxing Xu | c994bb2 | 2008-12-21 13:00:52 +0000 | [diff] [blame] | 241 |   Sezr.ExitBlock(); // exit "BasicMetadataBlock" | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 242 | } | 
 | 243 |  | 
| Ted Kremenek | a1fa3a1 | 2007-12-13 00:37:31 +0000 | [diff] [blame] | 244 | TranslationUnit* | 
| Ted Kremenek | 0ce902b | 2008-07-10 22:10:48 +0000 | [diff] [blame] | 245 | clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) { | 
 | 246 |  | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 247 |   // Check if the file is of the proper length. | 
| Ted Kremenek | 0ce902b | 2008-07-10 22:10:48 +0000 | [diff] [blame] | 248 |   if (MBuffer.getBufferSize() & 0x3) { | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 249 |     // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes." | 
 | 250 |     return NULL; | 
 | 251 |   } | 
 | 252 |    | 
 | 253 |   // Create the bitstream reader. | 
| Ted Kremenek | 0ce902b | 2008-07-10 22:10:48 +0000 | [diff] [blame] | 254 |   unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart(); | 
 | 255 |   llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize()); | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 256 |    | 
 | 257 |   if (Stream.Read(8) != 'B' || | 
 | 258 |       Stream.Read(8) != 'C' || | 
 | 259 |       Stream.Read(4) != 0xC || | 
 | 260 |       Stream.Read(4) != 0xF || | 
 | 261 |       Stream.Read(4) != 0xE || | 
 | 262 |       Stream.Read(4) != 0x0) { | 
 | 263 |     // FIXME: Provide diagnostic. | 
 | 264 |     return NULL; | 
 | 265 |   } | 
 | 266 |    | 
 | 267 |   // Create the deserializer. | 
 | 268 |   llvm::Deserializer Dezr(Stream); | 
 | 269 |    | 
| Ted Kremenek | dca2927 | 2007-12-18 21:44:50 +0000 | [diff] [blame] | 270 |   return TranslationUnit::Create(Dezr,FMgr); | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 271 | } | 
 | 272 |  | 
| Ted Kremenek | 0ce902b | 2008-07-10 22:10:48 +0000 | [diff] [blame] | 273 | TranslationUnit* | 
 | 274 | clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) { | 
 | 275 |    | 
 | 276 |   // Create the memory buffer that contains the contents of the file.   | 
 | 277 |   llvm::OwningPtr<llvm::MemoryBuffer>  | 
 | 278 |     MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str())); | 
 | 279 |    | 
 | 280 |   if (!MBuffer) { | 
 | 281 |     // FIXME: Provide diagnostic. | 
 | 282 |     return NULL; | 
 | 283 |   } | 
 | 284 |    | 
 | 285 |   return ReadASTBitcodeBuffer(*MBuffer, FMgr); | 
 | 286 | } | 
 | 287 |  | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 288 | TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr, | 
 | 289 |                                          FileManager& FMgr) { | 
 | 290 |    | 
 | 291 |   // Create the translation unit object. | 
 | 292 |   TranslationUnit* TU = new TranslationUnit(); | 
 | 293 |    | 
 | 294 |   // ===---------------------------------------------------===/ | 
 | 295 |   //      Deserialize the "Translation Unit" metadata. | 
 | 296 |   // ===---------------------------------------------------===/ | 
 | 297 |    | 
 | 298 |   // Skip to the BasicMetaDataBlock.  First jump to ASTContextBlock | 
 | 299 |   // (which will appear earlier) and record its location. | 
 | 300 |    | 
 | 301 |   bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock); | 
 | 302 |   assert (FoundBlock); | 
 | 303 |    | 
 | 304 |   llvm::Deserializer::Location ASTContextBlockLoc = | 
 | 305 |   Dezr.getCurrentBlockLocation(); | 
 | 306 |    | 
 | 307 |   FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock); | 
 | 308 |   assert (FoundBlock); | 
| Ted Kremenek | 63ea863 | 2007-12-19 19:27:38 +0000 | [diff] [blame] | 309 |    | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 310 |   // Read the SourceManager. | 
| Ted Kremenek | 9c728dc | 2007-12-12 22:39:36 +0000 | [diff] [blame] | 311 |   SourceManager::CreateAndRegister(Dezr,FMgr); | 
| Ted Kremenek | e7d07d1 | 2008-06-04 15:55:15 +0000 | [diff] [blame] | 312 |      | 
| Ted Kremenek | bbced58 | 2007-12-12 18:05:32 +0000 | [diff] [blame] | 313 |   { // Read the TargetInfo. | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 314 |     llvm::SerializedPtrID PtrID = Dezr.ReadPtrID(); | 
 | 315 |     char* triple = Dezr.ReadCStr(NULL,0,true); | 
| Ted Kremenek | c1e9dea | 2008-04-23 16:25:39 +0000 | [diff] [blame] | 316 |     Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple))); | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 317 |     delete [] triple; | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 318 |   } | 
 | 319 |    | 
 | 320 |   // For Selectors, we must read the identifier table first because the | 
 | 321 |   //  SelectorTable depends on the identifiers being already deserialized. | 
 | 322 |   llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();   | 
 | 323 |   Dezr.SkipBlock(); | 
 | 324 |    | 
 | 325 |   // Read the identifier table. | 
 | 326 |   IdentifierTable::CreateAndRegister(Dezr); | 
 | 327 |    | 
 | 328 |   // Now jump back and read the selectors. | 
 | 329 |   Dezr.JumpTo(SelectorBlkLoc); | 
 | 330 |   SelectorTable::CreateAndRegister(Dezr); | 
 | 331 |    | 
 | 332 |   // Now jump back to ASTContextBlock and read the ASTContext. | 
 | 333 |   Dezr.JumpTo(ASTContextBlockLoc); | 
 | 334 |   TU->Context = Dezr.ReadOwnedPtr<ASTContext>(); | 
 | 335 |    | 
 | 336 |   // "Rewind" the stream.  Find the block with the serialized top-level decls. | 
 | 337 |   Dezr.Rewind(); | 
 | 338 |   FoundBlock = Dezr.SkipToBlock(DeclsBlock); | 
 | 339 |   assert (FoundBlock); | 
 | 340 |   llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation(); | 
 | 341 |    | 
 | 342 |   while (!Dezr.FinishedBlock(DeclBlockLoc)) | 
| Sam Bishop | e2563ca | 2008-04-07 21:55:54 +0000 | [diff] [blame] | 343 |     TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>(*TU->Context)); | 
| Ted Kremenek | 2f74359 | 2007-12-05 21:36:08 +0000 | [diff] [blame] | 344 |  | 
 | 345 |   return TU; | 
 | 346 | } | 
 | 347 |  |