blob: 5f7b94fca409b7d30b65dc21ebb27f6b052dc845 [file] [log] [blame]
Ted Kremenekbfa82c42007-10-16 23:37:27 +00001//===--- SerializationTest.cpp - Experimental Object Serialization --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Ted Kremenekbfa82c42007-10-16 23:37:27 +00007//
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
Ted Kremenekbfa82c42007-10-16 23:37:27 +000017#include "clang/AST/ASTConsumer.h"
Ted Kremenek5656b782007-11-29 01:24:25 +000018#include "clang/AST/CFG.h"
Ted Kremenekc4ca2882007-12-03 22:48:14 +000019#include "clang.h"
Ted Kremenek35537662007-12-05 22:08:43 +000020#include "ASTConsumers.h"
Ted Kremenek525fdbc2007-12-18 21:36:21 +000021#include "clang/AST/TranslationUnit.h"
Ted Kremenekc637e6b2007-10-23 22:18:37 +000022#include "llvm/Support/MemoryBuffer.h"
Ted Kremenekee533642007-12-20 19:47:16 +000023#include "llvm/ADT/OwningPtr.h"
Ted Kremenek35537662007-12-05 22:08:43 +000024#include "llvm/Support/Streams.h"
Ted Kremenekea75c552007-11-28 21:32:21 +000025#include <fstream>
Chris Lattner87cf5ac2008-03-10 17:04:53 +000026#include <cstring>
Ted Kremenekbfa82c42007-10-16 23:37:27 +000027using namespace clang;
Ted Kremenekbfa82c42007-10-16 23:37:27 +000028
Ted Kremenek79a2a262007-11-28 19:21:47 +000029//===----------------------------------------------------------------------===//
Ted Kremenek79a2a262007-11-28 19:21:47 +000030// Driver code.
31//===----------------------------------------------------------------------===//
32
Ted Kremenek35537662007-12-05 22:08:43 +000033namespace {
Ted Kremenek4ac81212007-11-05 21:39:35 +000034
Ted Kremenek35537662007-12-05 22:08:43 +000035class SerializationTest : public ASTConsumer {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000036 llvm::OwningPtr<TranslationUnit> TU;
Ted Kremenek35537662007-12-05 22:08:43 +000037 Diagnostic &Diags;
38 FileManager &FMgr;
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000039 const LangOptions& lopts;
Ted Kremenek018b3952007-11-06 19:50:53 +000040public:
Ted Kremenekfdfc1982007-12-19 22:24:34 +000041 SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts)
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000042 : Diags(d), FMgr(fmgr), lopts(LOpts) {}
Ted Kremenekdca24662007-12-05 00:26:13 +000043
Ted Kremenek4ac81212007-11-05 21:39:35 +000044 ~SerializationTest();
45
Ted Kremenek95041a22007-12-19 22:51:13 +000046 virtual void Initialize(ASTContext& context) {
Eli Friedman5f1adf82008-05-21 05:33:10 +000047 if (!TU) {
48 TU.reset(new TranslationUnit(context, lopts));
49 TU->SetOwnsDecls(false);
50 }
Ted Kremenek35537662007-12-05 22:08:43 +000051 }
Ted Kremenek018b3952007-11-06 19:50:53 +000052
Ted Kremenek35537662007-12-05 22:08:43 +000053 virtual void HandleTopLevelDecl(Decl *D) {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000054 TU->AddTopLevelDecl(D);
Ted Kremenek35537662007-12-05 22:08:43 +000055 }
Ted Kremenek63ea8632007-12-19 19:27:38 +000056
Ted Kremenek018b3952007-11-06 19:50:53 +000057private:
Ted Kremenek35537662007-12-05 22:08:43 +000058 bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
59 bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
Ted Kremenek4ac81212007-11-05 21:39:35 +000060};
61
Ted Kremenekc637e6b2007-10-23 22:18:37 +000062} // end anonymous namespace
Ted Kremenekbfa82c42007-10-16 23:37:27 +000063
Ted Kremenekdca24662007-12-05 00:26:13 +000064ASTConsumer*
Ted Kremenekfdfc1982007-12-19 22:24:34 +000065clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr,
66 const LangOptions &LOpts) {
67
68 return new SerializationTest(Diags,FMgr,LOpts);
Ted Kremenek018b3952007-11-06 19:50:53 +000069}
70
Ted Kremenek018b3952007-11-06 19:50:53 +000071
Ted Kremenek35537662007-12-05 22:08:43 +000072bool SerializationTest::Serialize(llvm::sys::Path& Filename,
Ted Kremenek79a2a262007-11-28 19:21:47 +000073 llvm::sys::Path& FNameDeclPrint) {
Ted Kremenek35537662007-12-05 22:08:43 +000074 {
75 // Pretty-print the decls to a temp file.
Ted Kremenekea75c552007-11-28 21:32:21 +000076 std::ofstream DeclPP(FNameDeclPrint.c_str());
77 assert (DeclPP && "Could not open file for printing out decls.");
Ted Kremenekee533642007-12-20 19:47:16 +000078 llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
Ted Kremeneke7201982007-11-13 22:56:10 +000079
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000080 for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
Ted Kremenek35537662007-12-05 22:08:43 +000081 FilePrinter->HandleTopLevelDecl(*I);
Ted Kremenek7a1f4db2007-11-10 02:07:12 +000082 }
83
Ted Kremenek35537662007-12-05 22:08:43 +000084 // Serialize the translation unit.
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000085 return EmitASTBitcodeFile(*TU,Filename);
Ted Kremenekbfa82c42007-10-16 23:37:27 +000086}
87
Ted Kremenek35537662007-12-05 22:08:43 +000088bool SerializationTest::Deserialize(llvm::sys::Path& Filename,
Ted Kremenek79a2a262007-11-28 19:21:47 +000089 llvm::sys::Path& FNameDeclPrint) {
Ted Kremenek018b3952007-11-06 19:50:53 +000090
Ted Kremenek35537662007-12-05 22:08:43 +000091 // Deserialize the translation unit.
Ted Kremenekdca29272007-12-18 21:44:50 +000092 TranslationUnit* NewTU = ReadASTBitcodeFile(Filename,FMgr);
Ted Kremenekb899ad22007-11-14 17:46:35 +000093
Ted Kremenek35537662007-12-05 22:08:43 +000094 if (!NewTU)
95 return false;
Ted Kremenekb899ad22007-11-14 17:46:35 +000096
Ted Kremenek35537662007-12-05 22:08:43 +000097 {
98 // Pretty-print the deserialized decls to a temp file.
99 std::ofstream DeclPP(FNameDeclPrint.c_str());
100 assert (DeclPP && "Could not open file for printing out decls.");
Ted Kremenekee533642007-12-20 19:47:16 +0000101 llvm::OwningPtr<ASTConsumer> FilePrinter(CreateASTPrinter(&DeclPP));
Ted Kremenek35537662007-12-05 22:08:43 +0000102
103 for (TranslationUnit::iterator I=NewTU->begin(), E=NewTU->end(); I!=E; ++I)
104 FilePrinter->HandleTopLevelDecl(*I);
Ted Kremenekc4ca2882007-12-03 22:48:14 +0000105 }
Sam Bishop4ccea1a2008-04-03 05:03:34 +0000106
107 delete NewTU;
Ted Kremenek018b3952007-11-06 19:50:53 +0000108
Ted Kremenek35537662007-12-05 22:08:43 +0000109 return true;
Ted Kremenek018b3952007-11-06 19:50:53 +0000110}
111
Ted Kremenek79a2a262007-11-28 19:21:47 +0000112namespace {
113 class TmpDirJanitor {
114 llvm::sys::Path& Dir;
115 public:
116 explicit TmpDirJanitor(llvm::sys::Path& dir) : Dir(dir) {}
117
118 ~TmpDirJanitor() {
119 llvm::cerr << "Removing: " << Dir.c_str() << '\n';
120 Dir.eraseFromDisk(true);
121 }
122 };
123}
Ted Kremenek018b3952007-11-06 19:50:53 +0000124
125SerializationTest::~SerializationTest() {
Ted Kremenek79a2a262007-11-28 19:21:47 +0000126
Ted Kremenek018b3952007-11-06 19:50:53 +0000127 std::string ErrMsg;
Ted Kremenek79a2a262007-11-28 19:21:47 +0000128 llvm::sys::Path Dir = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
Ted Kremenek018b3952007-11-06 19:50:53 +0000129
Ted Kremenek79a2a262007-11-28 19:21:47 +0000130 if (Dir.isEmpty()) {
Ted Kremenek018b3952007-11-06 19:50:53 +0000131 llvm::cerr << "Error: " << ErrMsg << "\n";
132 return;
Ted Kremenekc637e6b2007-10-23 22:18:37 +0000133 }
134
Ted Kremenek79a2a262007-11-28 19:21:47 +0000135 TmpDirJanitor RemoveTmpOnExit(Dir);
136
137 llvm::sys::Path FNameDeclBefore = Dir;
138 FNameDeclBefore.appendComponent("test.decl_before.txt");
139
140 if (FNameDeclBefore.makeUnique(true,&ErrMsg)) {
Ted Kremenek018b3952007-11-06 19:50:53 +0000141 llvm::cerr << "Error: " << ErrMsg << "\n";
142 return;
143 }
Ted Kremenek4ac81212007-11-05 21:39:35 +0000144
Ted Kremenek79a2a262007-11-28 19:21:47 +0000145 llvm::sys::Path FNameDeclAfter = Dir;
146 FNameDeclAfter.appendComponent("test.decl_after.txt");
147
148 if (FNameDeclAfter.makeUnique(true,&ErrMsg)) {
149 llvm::cerr << "Error: " << ErrMsg << "\n";
150 return;
151 }
152
153 llvm::sys::Path ASTFilename = Dir;
154 ASTFilename.appendComponent("test.ast");
155
156 if (ASTFilename.makeUnique(true,&ErrMsg)) {
157 llvm::cerr << "Error: " << ErrMsg << "\n";
158 return;
159 }
160
161 // Serialize and then deserialize the ASTs.
Ted Kremenek35537662007-12-05 22:08:43 +0000162 bool status = Serialize(ASTFilename, FNameDeclBefore);
163 assert (status && "Serialization failed.");
164 status = Deserialize(ASTFilename, FNameDeclAfter);
165 assert (status && "Deserialization failed.");
Ted Kremenek79a2a262007-11-28 19:21:47 +0000166
167 // Read both pretty-printed files and compare them.
168
169 using llvm::MemoryBuffer;
170
Ted Kremenekee533642007-12-20 19:47:16 +0000171 llvm::OwningPtr<MemoryBuffer>
Chris Lattner35de5122008-04-01 18:04:30 +0000172 MBufferSer(MemoryBuffer::getFile(FNameDeclBefore.c_str()));
Ted Kremenek79a2a262007-11-28 19:21:47 +0000173
174 if(!MBufferSer) {
175 llvm::cerr << "ERROR: Cannot read pretty-printed file (pre-pickle).\n";
176 return;
177 }
178
Ted Kremenekee533642007-12-20 19:47:16 +0000179 llvm::OwningPtr<MemoryBuffer>
Chris Lattner35de5122008-04-01 18:04:30 +0000180 MBufferDSer(MemoryBuffer::getFile(FNameDeclAfter.c_str()));
Ted Kremenek79a2a262007-11-28 19:21:47 +0000181
182 if(!MBufferDSer) {
183 llvm::cerr << "ERROR: Cannot read pretty-printed file (post-pickle).\n";
184 return;
185 }
186
187 const char *p1 = MBufferSer->getBufferStart();
188 const char *e1 = MBufferSer->getBufferEnd();
189 const char *p2 = MBufferDSer->getBufferStart();
190 const char *e2 = MBufferDSer->getBufferEnd();
191
192 if (MBufferSer->getBufferSize() == MBufferDSer->getBufferSize())
193 for ( ; p1 != e1 ; ++p1, ++p2 )
194 if (*p1 != *p2) break;
195
196 if (p1 != e1 || p2 != e2 )
197 llvm::cerr << "ERROR: Pretty-printed files are not the same.\n";
198 else
199 llvm::cerr << "SUCCESS: Pretty-printed files are the same.\n";
Ted Kremenekc637e6b2007-10-23 22:18:37 +0000200}