blob: 826bfa0bae7ebf802fc2fbb226788e8ed2a324b0 [file] [log] [blame]
Ted Kremenekcc927092007-12-13 17:54:02 +00001//===--- TranslationUnit.cpp - Abstraction for Translation Units ----------===//
Ted Kremenek2f743592007-12-05 21:36:08 +00002//
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 Kremenek2f743592007-12-05 21:36:08 +00007//
8// FIXME: This should eventually be moved out of the driver, or replaced
9// with its eventual successor.
10//
11//===----------------------------------------------------------------------===//
12
Ted Kremenek525fdbc2007-12-18 21:36:21 +000013#include "clang/AST/TranslationUnit.h"
Ted Kremenek2f743592007-12-05 21:36:08 +000014
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 Kremenek2f743592007-12-05 21:36:08 +000023
Ted Kremenek27f8a282008-05-20 00:43:19 +000024#include "llvm/ADT/OwningPtr.h"
25#include "llvm/ADT/DenseSet.h"
Ted Kremenek2f743592007-12-05 21:36:08 +000026
Ted Kremenek2f743592007-12-05 21:36:08 +000027using namespace clang;
28
Ted Kremenek63ea8632007-12-19 19:27:38 +000029enum { BasicMetadataBlock = 1,
30 ASTContextBlock = 2,
31 DeclsBlock = 3 };
32
Sam Bishop0f9c72f2008-04-03 14:20:28 +000033TranslationUnit::~TranslationUnit() {
Eli Friedman5f1adf82008-05-21 05:33:10 +000034 if (OwnsDecls) {
Eli Friedman1108e7d2008-05-21 05:01:55 +000035 llvm::DenseSet<Decl*> Killed;
Douglas Gregor3dda64e2008-10-27 12:50:38 +000036 for (std::vector<Decl*>::reverse_iterator I=TopLevelDecls.rbegin(),
37 E=TopLevelDecls.rend();
38 I!=E; ++I) {
Eli Friedman1108e7d2008-05-21 05:01:55 +000039 if (Killed.count(*I)) continue;
40
41 Killed.insert(*I);
Ted Kremenek1a726d72008-06-06 17:21:42 +000042
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))
49 for (ObjCInterfaceDecl::classprop_iterator ID=IDecl->classprop_begin(),
50 ED=IDecl->classprop_end(); ID!=ED; ++ID) {
Ted Kremenek1c8a4132008-06-06 19:48:57 +000051 if (!*ID || Killed.count(*ID)) continue;
Ted Kremenek1a726d72008-06-06 17:21:42 +000052 Killed.insert(*ID);
53 (*ID)->Destroy(*Context);
54 }
55
Ted Kremenek1c8a4132008-06-06 19:48:57 +000056 // 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))
Ted Kremenek400d95f2008-06-06 20:11:53 +000062 for (ObjCProtocolDecl::classprop_iterator ID=PDecl->classprop_begin(),
63 ED=PDecl->classprop_end(); ID!=ED; ++ID) {
64 if (!*ID || Killed.count(*ID)) continue;
65 Killed.insert(*ID);
66 (*ID)->Destroy(*Context);
Ted Kremenek1c8a4132008-06-06 19:48:57 +000067 }
Ted Kremenek400d95f2008-06-06 20:11:53 +000068
69 // FIXME: There is no clear ownership policy now for ObjCInterfaceDecls
70 // referenced by ObjCClassDecls. Some of them can be forward decls that
Ted Kremenek05ac3ef2008-06-06 21:05:33 +000071 // are never later defined (and forward decls can be referenced by
72 // multiple ObjCClassDecls) or the ObjCInterfaceDecl later
73 // becomes a real definition.
Ted Kremenek400d95f2008-06-06 20:11:53 +000074 // 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 Kremenek05ac3ef2008-06-06 21:05:33 +000084
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 Kremenek400d95f2008-06-06 20:11:53 +0000101
Eli Friedman1108e7d2008-05-21 05:01:55 +0000102 (*I)->Destroy(*Context);
103 }
Eli Friedman5f1adf82008-05-21 05:33:10 +0000104 }
Eli Friedman1108e7d2008-05-21 05:01:55 +0000105
Eli Friedman5f1adf82008-05-21 05:33:10 +0000106 if (OwnsMetaData && Context) {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000107 // 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 Friedman5f1adf82008-05-21 05:33:10 +0000110
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000111 delete &(Context->Idents);
112 delete &(Context->Selectors);
113 delete &(Context->Target);
114 delete Context;
115 }
Sam Bishop71de20e2008-04-03 05:35:20 +0000116}
Ted Kremenek63ea8632007-12-19 19:27:38 +0000117
Zhongxing Xu8ce66662008-12-21 04:46:06 +0000118bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000119 const llvm::sys::Path& Filename) {
120
121 return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
122}
123
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000124bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,
125 std::vector<unsigned char>& Buffer) {
126
127 return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false;
128}
129
130bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,
131 std::ostream& Stream) {
132
133 return TU ? EmitASTBitcodeStream(*TU, Stream) : false;
134}
135
136bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,
137 std::vector<unsigned char>& Buffer) {
Ted Kremenek2f743592007-12-05 21:36:08 +0000138 // 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 Kremenekdca29272007-12-18 21:44:50 +0000155 TU.Emit(Sezr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000156 }
157
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000158 return true;
159}
160
161bool 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
175bool 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 Kremenek2f743592007-12-05 21:36:08 +0000184 // 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
194void 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);
218 Sezr.ExitBlock();
219
220 Sezr.EnterBlock(BasicMetadataBlock);
221
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000222 // Block for SourceManager and Target. Allows easy skipping
Ted Kremenek2f743592007-12-05 21:36:08 +0000223 // around to the block for the Selectors during deserialization.
224 Sezr.EnterBlock();
Ted Kremenekfdfc1982007-12-19 22:24:34 +0000225
Ted Kremenek2f743592007-12-05 21:36:08 +0000226 // Emit the SourceManager.
Ted Kremenek7a9d49f2007-12-11 21:27:55 +0000227 Sezr.Emit(Context->getSourceManager());
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000228
Ted Kremenek2f743592007-12-05 21:36:08 +0000229 // Emit the Target.
230 Sezr.EmitPtr(&Context->Target);
231 Sezr.EmitCStr(Context->Target.getTargetTriple());
232
233 Sezr.ExitBlock(); // exit "BasicMetadataBlock"
234
235 // Emit the Selectors.
236 Sezr.Emit(Context->Selectors);
237
238 // Emit the Identifier Table.
239 Sezr.Emit(Context->Idents);
240
241 Sezr.ExitBlock(); // exit "ASTContextBlock"
242}
243
Ted Kremeneka1fa3a12007-12-13 00:37:31 +0000244TranslationUnit*
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000245clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) {
246
Ted Kremenek2f743592007-12-05 21:36:08 +0000247 // Check if the file is of the proper length.
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000248 if (MBuffer.getBufferSize() & 0x3) {
Ted Kremenek2f743592007-12-05 21:36:08 +0000249 // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
250 return NULL;
251 }
252
253 // Create the bitstream reader.
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000254 unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart();
255 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize());
Ted Kremenek2f743592007-12-05 21:36:08 +0000256
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 Kremenekdca29272007-12-18 21:44:50 +0000270 return TranslationUnit::Create(Dezr,FMgr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000271}
272
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000273TranslationUnit*
274clang::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 Kremenek2f743592007-12-05 21:36:08 +0000288TranslationUnit* 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 Kremenek63ea8632007-12-19 19:27:38 +0000309
Ted Kremenek2f743592007-12-05 21:36:08 +0000310 // Read the SourceManager.
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000311 SourceManager::CreateAndRegister(Dezr,FMgr);
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000312
Ted Kremenekbbced582007-12-12 18:05:32 +0000313 { // Read the TargetInfo.
Ted Kremenek2f743592007-12-05 21:36:08 +0000314 llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
315 char* triple = Dezr.ReadCStr(NULL,0,true);
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000316 Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple)));
Ted Kremenek2f743592007-12-05 21:36:08 +0000317 delete [] triple;
Ted Kremenek2f743592007-12-05 21:36:08 +0000318 }
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 Bishope2563ca2008-04-07 21:55:54 +0000343 TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>(*TU->Context));
Ted Kremenek2f743592007-12-05 21:36:08 +0000344
345 return TU;
346}
347