blob: 813aa7ea7b76d612867b9c5a6945888937695565 [file] [log] [blame]
Ted Kremenek221bb8d2007-10-16 23:37:27 +00001//===--- SerializationTest.cpp - Experimental Object Serialization --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Ted Kremenek and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements prototype code for serialization of objects in clang.
11// It is not intended yet for public use, but simply is a placeholder to
12// experiment with new serialization features. Serialization will eventually
13// be integrated as a proper component of the clang libraries.
14//
15//===----------------------------------------------------------------------===//
16
17#include "ASTConsumers.h"
Ted Kremenek8b61b3b2007-12-03 22:48:14 +000018#include "clang/Basic/TargetInfo.h"
Ted Kremenek923de592007-12-05 00:26:13 +000019#include "clang/Basic/SourceManager.h"
Ted Kremenek221bb8d2007-10-16 23:37:27 +000020#include "clang/AST/AST.h"
21#include "clang/AST/ASTConsumer.h"
22#include "clang/AST/ASTContext.h"
Ted Kremenek09a0cef2007-11-29 01:24:25 +000023#include "clang/AST/CFG.h"
Ted Kremenek8b61b3b2007-12-03 22:48:14 +000024#include "clang.h"
Ted Kremenek221bb8d2007-10-16 23:37:27 +000025#include "llvm/System/Path.h"
Ted Kremenek634cadf2007-10-23 22:18:37 +000026#include "llvm/Support/Streams.h"
27#include "llvm/Support/MemoryBuffer.h"
Ted Kremenekce797d92007-10-24 19:06:02 +000028#include "llvm/Bitcode/Serialize.h"
29#include "llvm/Bitcode/Deserialize.h"
Ted Kremenekbe2ea3b2007-11-28 21:32:21 +000030#include <fstream>
Ted Kremenek634cadf2007-10-23 22:18:37 +000031#include <stdio.h>
Ted Kremenek1e049d22007-11-06 19:50:53 +000032#include <list>
Ted Kremenek634cadf2007-10-23 22:18:37 +000033
Ted Kremenek221bb8d2007-10-16 23:37:27 +000034using namespace clang;
Ted Kremenek221bb8d2007-10-16 23:37:27 +000035
Ted Kremenekb3b25972007-11-28 19:21:47 +000036//===----------------------------------------------------------------------===//
37// Utility classes
38//===----------------------------------------------------------------------===//
39
Ted Kremenek221bb8d2007-10-16 23:37:27 +000040namespace {
Ted Kremenek221bb8d2007-10-16 23:37:27 +000041
Ted Kremenekb3b25972007-11-28 19:21:47 +000042template<typename T> class Janitor {
Ted Kremenek47916ee2007-11-05 21:39:35 +000043 T* Obj;
Ted Kremenekb3b25972007-11-28 19:21:47 +000044public:
45 explicit Janitor(T* obj) : Obj(obj) {}
Ted Kremenek47916ee2007-11-05 21:39:35 +000046 ~Janitor() { delete Obj; }
Ted Kremenekb3b25972007-11-28 19:21:47 +000047 operator T*() const { return Obj; }
48 T* operator->() { return Obj; }
Ted Kremenek47916ee2007-11-05 21:39:35 +000049};
Ted Kremenekb3b25972007-11-28 19:21:47 +000050
51//===----------------------------------------------------------------------===//
52// Driver code.
53//===----------------------------------------------------------------------===//
54
Ted Kremenek47916ee2007-11-05 21:39:35 +000055class SerializationTest : public ASTConsumer {
56 ASTContext* Context;
Ted Kremenek8b61b3b2007-12-03 22:48:14 +000057 Diagnostic &Diags;
Ted Kremenek923de592007-12-05 00:26:13 +000058 FileManager &FMgr;
Ted Kremenek2939b8a2007-12-05 21:34:36 +000059 const LangOptions& LangOpts;
Ted Kremenek1e049d22007-11-06 19:50:53 +000060 std::list<Decl*> Decls;
Ted Kremenek47916ee2007-11-05 21:39:35 +000061
Ted Kremeneka8a6a482007-11-30 22:46:56 +000062 enum { BasicMetadataBlock = 1,
63 ASTContextBlock = 2,
64 DeclsBlock = 3 };
Ted Kremenek1e049d22007-11-06 19:50:53 +000065
66public:
Ted Kremenek2939b8a2007-12-05 21:34:36 +000067 SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts)
68 : Context(NULL), Diags(d), FMgr(fmgr), LangOpts(LOpts) {};
Ted Kremenek923de592007-12-05 00:26:13 +000069
Ted Kremenek47916ee2007-11-05 21:39:35 +000070 ~SerializationTest();
71
Ted Kremenek1e049d22007-11-06 19:50:53 +000072 virtual void Initialize(ASTContext& context, unsigned) {
73 Context = &context;
74 }
75
76 virtual void HandleTopLevelDecl(Decl *D) {
77 Decls.push_back(D);
78 }
79
80private:
Ted Kremenekb3b25972007-11-28 19:21:47 +000081 void Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
82 void Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
Ted Kremenek47916ee2007-11-05 21:39:35 +000083};
84
Ted Kremenek634cadf2007-10-23 22:18:37 +000085} // end anonymous namespace
Ted Kremenek221bb8d2007-10-16 23:37:27 +000086
Ted Kremenek923de592007-12-05 00:26:13 +000087ASTConsumer*
Ted Kremenek2939b8a2007-12-05 21:34:36 +000088clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr,
89 const LangOptions &LOpts) {
90 return new SerializationTest(Diags,FMgr,LOpts);
Ted Kremenek1e049d22007-11-06 19:50:53 +000091}
92
93static void WritePreamble(llvm::BitstreamWriter& Stream) {
94 Stream.Emit((unsigned)'B', 8);
95 Stream.Emit((unsigned)'C', 8);
96 Stream.Emit(0xC, 4);
97 Stream.Emit(0xF, 4);
98 Stream.Emit(0xE, 4);
99 Stream.Emit(0x0, 4);
100}
101
Ted Kremenekccc24742007-11-06 23:52:19 +0000102static bool ReadPreamble(llvm::BitstreamReader& Stream) {
Ted Kremenek1e049d22007-11-06 19:50:53 +0000103 return Stream.Read(8) != 'B' ||
104 Stream.Read(8) != 'C' ||
105 Stream.Read(4) != 0xC ||
106 Stream.Read(4) != 0xF ||
107 Stream.Read(4) != 0xE ||
108 Stream.Read(4) != 0x0;
109}
110
Ted Kremenekb3b25972007-11-28 19:21:47 +0000111void SerializationTest::Serialize(llvm::sys::Path& Filename,
112 llvm::sys::Path& FNameDeclPrint) {
Ted Kremenek634cadf2007-10-23 22:18:37 +0000113
Ted Kremenek1e049d22007-11-06 19:50:53 +0000114 // Reserve 256K for bitstream buffer.
115 std::vector<unsigned char> Buffer;
116 Buffer.reserve(256*1024);
117
118 // Create bitstream and write preamble.
119 llvm::BitstreamWriter Stream(Buffer);
120 WritePreamble(Stream);
121
122 // Create serializer.
123 llvm::Serializer Sezr(Stream);
124
125 // ===---------------------------------------------------===/
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000126 // Serialize the top-level decls.
127 // ===---------------------------------------------------===/
128
Ted Kremenek286333d2007-11-14 17:46:35 +0000129 Sezr.EnterBlock(DeclsBlock);
Ted Kremenekea5bfc72007-11-13 22:56:10 +0000130
Ted Kremenekb3b25972007-11-28 19:21:47 +0000131 { // Create a printer to "consume" our deserialized ASTS.
132
133 Janitor<ASTConsumer> Printer(CreateASTPrinter());
Ted Kremenekbe2ea3b2007-11-28 21:32:21 +0000134 std::ofstream DeclPP(FNameDeclPrint.c_str());
135 assert (DeclPP && "Could not open file for printing out decls.");
136 Janitor<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
Ted Kremenekea5bfc72007-11-13 22:56:10 +0000137
Ted Kremenekb3b25972007-11-28 19:21:47 +0000138 for (std::list<Decl*>::iterator I=Decls.begin(), E=Decls.end(); I!=E; ++I) {
139 llvm::cerr << "Serializing: Decl.\n";
140
Ted Kremenek430aee62007-11-29 19:04:54 +0000141 // Only serialize the head of a decl chain. The ASTConsumer interfaces
142 // provides us with each top-level decl, including those nested in
143 // a decl chain, so we may be passed decls that are already serialized.
144 if (!Sezr.isRegistered(*I)) {
145 Printer->HandleTopLevelDecl(*I);
146 FilePrinter->HandleTopLevelDecl(*I);
147
148 if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*I))
149 if (FD->getBody()) {
150 // Construct and print a CFG.
151 Janitor<CFG> cfg(CFG::buildCFG(FD->getBody()));
152 cfg->print(DeclPP);
153 }
154
155 // Serialize the decl.
156 Sezr.EmitOwnedPtr(*I);
157 }
Ted Kremenekb3b25972007-11-28 19:21:47 +0000158 }
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000159 }
160
161 Sezr.ExitBlock();
162
163 // ===---------------------------------------------------===/
Ted Kremenek1e049d22007-11-06 19:50:53 +0000164 // Serialize the "Translation Unit" metadata.
165 // ===---------------------------------------------------===/
166
Ted Kremenek286333d2007-11-14 17:46:35 +0000167 // Emit ASTContext.
168 Sezr.EnterBlock(ASTContextBlock);
169 llvm::cerr << "Serializing: ASTContext.\n";
170 Sezr.EmitOwnedPtr(Context);
171 Sezr.ExitBlock();
172
173
174 Sezr.EnterBlock(BasicMetadataBlock);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000175
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000176 // Block for SourceManager and Target. Allows easy skipping around
177 // to the Selectors during deserialization.
178 Sezr.EnterBlock();
179
Ted Kremenek1e049d22007-11-06 19:50:53 +0000180 // "Fake" emit the SourceManager.
Ted Kremenek923de592007-12-05 00:26:13 +0000181 llvm::cerr << "Serializing: SourceManager.\n";
182 Sezr.Emit(Context->SourceMgr);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000183
Ted Kremenek8b61b3b2007-12-03 22:48:14 +0000184 // Emit the Target.
185 llvm::cerr << "Serializing: Target.\n";
Ted Kremenek1e049d22007-11-06 19:50:53 +0000186 Sezr.EmitPtr(&Context->Target);
Ted Kremenek8b61b3b2007-12-03 22:48:14 +0000187 Sezr.EmitCStr(Context->Target.getTargetTriple());
Ted Kremenek1e049d22007-11-06 19:50:53 +0000188
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000189 Sezr.ExitBlock();
190
191 // Emit the Selectors.
192 llvm::cerr << "Serializing: Selectors.\n";
193 Sezr.Emit(Context->Selectors);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000194
195 // Emit the Identifier Table.
196 llvm::cerr << "Serializing: IdentifierTable.\n";
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000197 Sezr.Emit(Context->Idents);
Ted Kremenek286333d2007-11-14 17:46:35 +0000198
Ted Kremenek1e049d22007-11-06 19:50:53 +0000199 Sezr.ExitBlock();
200
201 // ===---------------------------------------------------===/
Ted Kremenekb3b25972007-11-28 19:21:47 +0000202 // Finalize serialization: write the bits to disk.
Ted Kremenekbe2ea3b2007-11-28 21:32:21 +0000203 if (FILE* fp = fopen(Filename.c_str(),"wb")) {
204 fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
205 fclose(fp);
206 }
207 else {
208 llvm::cerr << "Error: Cannot open " << Filename.c_str() << "\n";
209 return;
Ted Kremenek221bb8d2007-10-16 23:37:27 +0000210 }
Ted Kremenek634cadf2007-10-23 22:18:37 +0000211
Ted Kremenek1e049d22007-11-06 19:50:53 +0000212 llvm::cerr << "Commited bitstream to disk: " << Filename.c_str() << "\n";
Ted Kremenek221bb8d2007-10-16 23:37:27 +0000213}
214
Ted Kremenek221bb8d2007-10-16 23:37:27 +0000215
Ted Kremenekb3b25972007-11-28 19:21:47 +0000216void SerializationTest::Deserialize(llvm::sys::Path& Filename,
217 llvm::sys::Path& FNameDeclPrint) {
Ted Kremenek1e049d22007-11-06 19:50:53 +0000218
219 // Create the memory buffer that contains the contents of the file.
220
221 using llvm::MemoryBuffer;
222
Ted Kremenekb3b25972007-11-28 19:21:47 +0000223 Janitor<MemoryBuffer> MBuffer(MemoryBuffer::getFile(Filename.c_str(),
224 strlen(Filename.c_str())));
Ted Kremenek221bb8d2007-10-16 23:37:27 +0000225
Ted Kremenek47916ee2007-11-05 21:39:35 +0000226 if(!MBuffer) {
227 llvm::cerr << "ERROR: Cannot read file for deserialization.\n";
228 return;
Ted Kremenek221bb8d2007-10-16 23:37:27 +0000229 }
Ted Kremenek221bb8d2007-10-16 23:37:27 +0000230
Ted Kremenek1e049d22007-11-06 19:50:53 +0000231 // Check if the file is of the proper length.
Ted Kremenek47916ee2007-11-05 21:39:35 +0000232 if (MBuffer->getBufferSize() & 0x3) {
Ted Kremenek1e049d22007-11-06 19:50:53 +0000233 llvm::cerr << "ERROR: AST file length should be a multiple of 4 bytes.\n";
Ted Kremenek47916ee2007-11-05 21:39:35 +0000234 return;
Ted Kremenek634cadf2007-10-23 22:18:37 +0000235 }
236
Ted Kremenek1e049d22007-11-06 19:50:53 +0000237 // Create the bitstream reader.
238 unsigned char *BufPtr = (unsigned char *) MBuffer->getBufferStart();
239 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer->getBufferSize());
Ted Kremenek634cadf2007-10-23 22:18:37 +0000240
Ted Kremenek1e049d22007-11-06 19:50:53 +0000241 // Sniff for the signature in the bitcode file.
Ted Kremenekccc24742007-11-06 23:52:19 +0000242 if (ReadPreamble(Stream)) {
Ted Kremenek47916ee2007-11-05 21:39:35 +0000243 llvm::cerr << "ERROR: Invalid AST-bitcode signature.\n";
244 return;
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000245 }
246
247 // Create the deserializer.
Ted Kremenek1e049d22007-11-06 19:50:53 +0000248 llvm::Deserializer Dezr(Stream);
249
250 // ===---------------------------------------------------===/
251 // Deserialize the "Translation Unit" metadata.
252 // ===---------------------------------------------------===/
253
Ted Kremenek286333d2007-11-14 17:46:35 +0000254 // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
255 // (which will appear earlier) and record its location.
256
257 bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
258 assert (FoundBlock);
259
260 llvm::Deserializer::Location ASTContextBlockLoc =
261 Dezr.getCurrentBlockLocation();
262
263 FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000264 assert (FoundBlock);
265
Ted Kremenek923de592007-12-05 00:26:13 +0000266 // Read the SourceManager.
267 llvm::cerr << "Deserializing: SourceManager.\n";
268 SourceManager::CreateAndRegister(Dezr,FMgr);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000269
Ted Kremenek8b61b3b2007-12-03 22:48:14 +0000270 { // Read the TargetInfo.
271 llvm::cerr << "Deserializing: Target.\n";
272 llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
273 char* triple = Dezr.ReadCStr(NULL,0,true);
274 std::vector<std::string> triples;
275 triples.push_back(triple);
276 delete [] triple;
Ted Kremenek2939b8a2007-12-05 21:34:36 +0000277 Dezr.RegisterPtr(PtrID,CreateTargetInfo(triples,&Diags));
Ted Kremenek8b61b3b2007-12-03 22:48:14 +0000278 }
279
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000280 // For Selectors, we must read the identifier table first because the
281 // SelectorTable depends on the identifiers being already deserialized.
Ted Kremenek8b61b3b2007-12-03 22:48:14 +0000282 llvm::Deserializer::Location SelectorBlockLoc =
283 Dezr.getCurrentBlockLocation();
284
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000285 Dezr.SkipBlock();
Ted Kremenek1e049d22007-11-06 19:50:53 +0000286
287 // Read the identifier table.
288 llvm::cerr << "Deserializing: IdentifierTable\n";
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000289 IdentifierTable::CreateAndRegister(Dezr);
290
291 // Now jump back and read the selectors.
292 llvm::cerr << "Deserializing: Selectors\n";
293 Dezr.JumpTo(SelectorBlockLoc);
294 SelectorTable::CreateAndRegister(Dezr);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000295
Ted Kremenek286333d2007-11-14 17:46:35 +0000296 // Now jump back to ASTContextBlock and read the ASTContext.
Ted Kremenek1e049d22007-11-06 19:50:53 +0000297 llvm::cerr << "Deserializing: ASTContext.\n";
Ted Kremeneka8a6a482007-11-30 22:46:56 +0000298 Dezr.JumpTo(ASTContextBlockLoc);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000299 Dezr.ReadOwnedPtr<ASTContext>();
Ted Kremenekb3b25972007-11-28 19:21:47 +0000300
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000301 // "Rewind" the stream. Find the block with the serialized top-level decls.
302 Dezr.Rewind();
Ted Kremenek286333d2007-11-14 17:46:35 +0000303 FoundBlock = Dezr.SkipToBlock(DeclsBlock);
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000304 assert (FoundBlock);
305 llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
306
Ted Kremenekb3b25972007-11-28 19:21:47 +0000307 // Create a printer to "consume" our deserialized ASTS.
308 ASTConsumer* Printer = CreateASTPrinter();
309 Janitor<ASTConsumer> PrinterJanitor(Printer);
Ted Kremenekbe2ea3b2007-11-28 21:32:21 +0000310 std::ofstream DeclPP(FNameDeclPrint.c_str());
311 assert (DeclPP && "Could not open file for printing out decls.");
312 Janitor<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
Ted Kremenekb3b25972007-11-28 19:21:47 +0000313
Ted Kremenek1e049d22007-11-06 19:50:53 +0000314 // The remaining objects in the file are top-level decls.
Ted Kremenek9dcb2882007-11-10 02:07:12 +0000315 while (!Dezr.FinishedBlock(DeclBlockLoc)) {
Ted Kremenek1e049d22007-11-06 19:50:53 +0000316 llvm::cerr << "Deserializing: Decl.\n";
317 Decl* decl = Dezr.ReadOwnedPtr<Decl>();
Ted Kremenekb3b25972007-11-28 19:21:47 +0000318 Printer->HandleTopLevelDecl(decl);
319 FilePrinter->HandleTopLevelDecl(decl);
Ted Kremenek09a0cef2007-11-29 01:24:25 +0000320
321 if (FunctionDecl* FD = dyn_cast<FunctionDecl>(decl))
322 if (FD->getBody()) {
323 // Construct and print a CFG.
324 Janitor<CFG> cfg(CFG::buildCFG(FD->getBody()));
325 cfg->print(DeclPP);
326 }
Ted Kremenek1e049d22007-11-06 19:50:53 +0000327 }
328}
329
Ted Kremenekb3b25972007-11-28 19:21:47 +0000330namespace {
331 class TmpDirJanitor {
332 llvm::sys::Path& Dir;
333 public:
334 explicit TmpDirJanitor(llvm::sys::Path& dir) : Dir(dir) {}
335
336 ~TmpDirJanitor() {
337 llvm::cerr << "Removing: " << Dir.c_str() << '\n';
338 Dir.eraseFromDisk(true);
339 }
340 };
341}
Ted Kremenek1e049d22007-11-06 19:50:53 +0000342
343SerializationTest::~SerializationTest() {
Ted Kremenekb3b25972007-11-28 19:21:47 +0000344
Ted Kremenek1e049d22007-11-06 19:50:53 +0000345 std::string ErrMsg;
Ted Kremenekb3b25972007-11-28 19:21:47 +0000346 llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
Ted Kremenek1e049d22007-11-06 19:50:53 +0000347
Ted Kremenekb3b25972007-11-28 19:21:47 +0000348 if (Dir.isEmpty()) {
Ted Kremenek1e049d22007-11-06 19:50:53 +0000349 llvm::cerr << "Error: " << ErrMsg << "\n";
350 return;
Ted Kremenek634cadf2007-10-23 22:18:37 +0000351 }
352
Ted Kremenekb3b25972007-11-28 19:21:47 +0000353 TmpDirJanitor RemoveTmpOnExit(Dir);
354
355 llvm::sys::Path FNameDeclBefore = Dir;
356 FNameDeclBefore.appendComponent("test.decl_before.txt");
357
358 if (FNameDeclBefore.makeUnique(true,&ErrMsg)) {
Ted Kremenek1e049d22007-11-06 19:50:53 +0000359 llvm::cerr << "Error: " << ErrMsg << "\n";
360 return;
361 }
Ted Kremenek47916ee2007-11-05 21:39:35 +0000362
Ted Kremenekb3b25972007-11-28 19:21:47 +0000363 llvm::sys::Path FNameDeclAfter = Dir;
364 FNameDeclAfter.appendComponent("test.decl_after.txt");
365
366 if (FNameDeclAfter.makeUnique(true,&ErrMsg)) {
367 llvm::cerr << "Error: " << ErrMsg << "\n";
368 return;
369 }
370
371 llvm::sys::Path ASTFilename = Dir;
372 ASTFilename.appendComponent("test.ast");
373
374 if (ASTFilename.makeUnique(true,&ErrMsg)) {
375 llvm::cerr << "Error: " << ErrMsg << "\n";
376 return;
377 }
378
379 // Serialize and then deserialize the ASTs.
380 Serialize(ASTFilename, FNameDeclBefore);
381 Deserialize(ASTFilename, FNameDeclAfter);
382
383 // Read both pretty-printed files and compare them.
384
385 using llvm::MemoryBuffer;
386
387 Janitor<MemoryBuffer>
388 MBufferSer(MemoryBuffer::getFile(FNameDeclBefore.c_str(),
389 strlen(FNameDeclBefore.c_str())));
390
391 if(!MBufferSer) {
392 llvm::cerr << "ERROR: Cannot read pretty-printed file (pre-pickle).\n";
393 return;
394 }
395
396 Janitor<MemoryBuffer>
397 MBufferDSer(MemoryBuffer::getFile(FNameDeclAfter.c_str(),
398 strlen(FNameDeclAfter.c_str())));
399
400 if(!MBufferDSer) {
401 llvm::cerr << "ERROR: Cannot read pretty-printed file (post-pickle).\n";
402 return;
403 }
404
405 const char *p1 = MBufferSer->getBufferStart();
406 const char *e1 = MBufferSer->getBufferEnd();
407 const char *p2 = MBufferDSer->getBufferStart();
408 const char *e2 = MBufferDSer->getBufferEnd();
409
410 if (MBufferSer->getBufferSize() == MBufferDSer->getBufferSize())
411 for ( ; p1 != e1 ; ++p1, ++p2 )
412 if (*p1 != *p2) break;
413
414 if (p1 != e1 || p2 != e2 )
415 llvm::cerr << "ERROR: Pretty-printed files are not the same.\n";
416 else
417 llvm::cerr << "SUCCESS: Pretty-printed files are the same.\n";
Ted Kremenek634cadf2007-10-23 22:18:37 +0000418}