blob: 5e644cf9835e91b8989da10100b0d38d15efeff6 [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;
36 for (iterator I=begin(), E=end(); I!=E; ++I) {
37 if (Killed.count(*I)) continue;
38
39 Killed.insert(*I);
Ted Kremenek1a726d72008-06-06 17:21:42 +000040
41 // FIXME: This is a horrible hack. Because there is no clear ownership
42 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
43 // reference, we need to destroy ObjCPropertyDecls here. This will
44 // eventually be fixed when the ownership of ObjCPropertyDecls gets
45 // cleaned up.
46 if (ObjCInterfaceDecl* IDecl = dyn_cast<ObjCInterfaceDecl>(*I))
47 for (ObjCInterfaceDecl::classprop_iterator ID=IDecl->classprop_begin(),
48 ED=IDecl->classprop_end(); ID!=ED; ++ID) {
Ted Kremenek1c8a4132008-06-06 19:48:57 +000049 if (!*ID || Killed.count(*ID)) continue;
Ted Kremenek1a726d72008-06-06 17:21:42 +000050 Killed.insert(*ID);
51 (*ID)->Destroy(*Context);
52 }
53
Ted Kremenek1c8a4132008-06-06 19:48:57 +000054 // FIXME: This is a horrible hack. Because there is no clear ownership
55 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
56 // reference, we need to destroy ObjCPropertyDecls here. This will
57 // eventually be fixed when the ownership of ObjCPropertyDecls gets
58 // cleaned up.
59 if (ObjCProtocolDecl* PDecl = dyn_cast<ObjCProtocolDecl>(*I))
Ted Kremenek400d95f2008-06-06 20:11:53 +000060 for (ObjCProtocolDecl::classprop_iterator ID=PDecl->classprop_begin(),
61 ED=PDecl->classprop_end(); ID!=ED; ++ID) {
62 if (!*ID || Killed.count(*ID)) continue;
63 Killed.insert(*ID);
64 (*ID)->Destroy(*Context);
Ted Kremenek1c8a4132008-06-06 19:48:57 +000065 }
Ted Kremenek400d95f2008-06-06 20:11:53 +000066
67 // FIXME: There is no clear ownership policy now for ObjCInterfaceDecls
68 // referenced by ObjCClassDecls. Some of them can be forward decls that
69 // are never later defined (in which case the ObjCClassDecl owns them)
70 // or the ObjCInterfaceDecl later becomes a real definition later.
71 // Ideally we should have separate objects for forward declarations and
72 // definitions, obviating this problem. Because of this situation,
73 // referenced ObjCInterfaceDecls are destroyed here.
74 if (ObjCClassDecl* CDecl = dyn_cast<ObjCClassDecl>(*I))
75 for (ObjCClassDecl::iterator ID=CDecl->begin(),
76 ED=CDecl->end(); ID!=ED; ++ID) {
77 if (!*ID || Killed.count(*ID)) continue;
78 Killed.insert(*ID);
79 (*ID)->Destroy(*Context);
80 }
81
Eli Friedman1108e7d2008-05-21 05:01:55 +000082 (*I)->Destroy(*Context);
83 }
Eli Friedman5f1adf82008-05-21 05:33:10 +000084 }
Eli Friedman1108e7d2008-05-21 05:01:55 +000085
Eli Friedman5f1adf82008-05-21 05:33:10 +000086 if (OwnsMetaData && Context) {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000087 // The ASTContext object has the sole references to the IdentifierTable
88 // Selectors, and the Target information. Go and delete them, since
89 // the TranslationUnit effectively owns them.
Eli Friedman5f1adf82008-05-21 05:33:10 +000090
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000091 delete &(Context->Idents);
92 delete &(Context->Selectors);
93 delete &(Context->Target);
94 delete Context;
95 }
Sam Bishop71de20e2008-04-03 05:35:20 +000096}
Ted Kremenek63ea8632007-12-19 19:27:38 +000097
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000098bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
99 const llvm::sys::Path& Filename) {
100
101 return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
102}
103
Ted Kremenekdca29272007-12-18 21:44:50 +0000104bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
105 const llvm::sys::Path& Filename) {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000106
Ted Kremenek2f743592007-12-05 21:36:08 +0000107 // Reserve 256K for bitstream buffer.
108 std::vector<unsigned char> Buffer;
109 Buffer.reserve(256*1024);
110
111 // Create bitstream.
112 llvm::BitstreamWriter Stream(Buffer);
113
114 // Emit the preamble.
115 Stream.Emit((unsigned)'B', 8);
116 Stream.Emit((unsigned)'C', 8);
117 Stream.Emit(0xC, 4);
118 Stream.Emit(0xF, 4);
119 Stream.Emit(0xE, 4);
120 Stream.Emit(0x0, 4);
121
122 {
123 // Create serializer. Placing it in its own scope assures any necessary
124 // finalization of bits to the buffer in the serializer's dstor.
125 llvm::Serializer Sezr(Stream);
126
127 // Emit the translation unit.
Ted Kremenekdca29272007-12-18 21:44:50 +0000128 TU.Emit(Sezr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000129 }
130
131 // Write the bits to disk.
132 if (FILE* fp = fopen(Filename.c_str(),"wb")) {
133 fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
134 fclose(fp);
135 return true;
136 }
137
138 return false;
139}
140
141void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
142
143 // ===---------------------------------------------------===/
144 // Serialize the top-level decls.
145 // ===---------------------------------------------------===/
146
147 Sezr.EnterBlock(DeclsBlock);
148
149 // Only serialize the head of a decl chain. The ASTConsumer interfaces
150 // provides us with each top-level decl, including those nested in
151 // a decl chain, so we may be passed decls that are already serialized.
152 for (const_iterator I=begin(), E=end(); I!=E; ++I)
153 if (!Sezr.isRegistered(*I))
154 Sezr.EmitOwnedPtr(*I);
155
156 Sezr.ExitBlock();
157
158 // ===---------------------------------------------------===/
159 // Serialize the "Translation Unit" metadata.
160 // ===---------------------------------------------------===/
161
162 // Emit ASTContext.
163 Sezr.EnterBlock(ASTContextBlock);
164 Sezr.EmitOwnedPtr(Context);
165 Sezr.ExitBlock();
166
167 Sezr.EnterBlock(BasicMetadataBlock);
168
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000169 // Block for SourceManager and Target. Allows easy skipping
Ted Kremenek2f743592007-12-05 21:36:08 +0000170 // around to the block for the Selectors during deserialization.
171 Sezr.EnterBlock();
Ted Kremenekfdfc1982007-12-19 22:24:34 +0000172
Ted Kremenek2f743592007-12-05 21:36:08 +0000173 // Emit the SourceManager.
Ted Kremenek7a9d49f2007-12-11 21:27:55 +0000174 Sezr.Emit(Context->getSourceManager());
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000175
Ted Kremenek2f743592007-12-05 21:36:08 +0000176 // Emit the Target.
177 Sezr.EmitPtr(&Context->Target);
178 Sezr.EmitCStr(Context->Target.getTargetTriple());
179
180 Sezr.ExitBlock(); // exit "BasicMetadataBlock"
181
182 // Emit the Selectors.
183 Sezr.Emit(Context->Selectors);
184
185 // Emit the Identifier Table.
186 Sezr.Emit(Context->Idents);
187
188 Sezr.ExitBlock(); // exit "ASTContextBlock"
189}
190
Ted Kremeneka1fa3a12007-12-13 00:37:31 +0000191TranslationUnit*
Ted Kremenekdca29272007-12-18 21:44:50 +0000192clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) {
Ted Kremenek2f743592007-12-05 21:36:08 +0000193
194 // Create the memory buffer that contains the contents of the file.
Ted Kremenekee533642007-12-20 19:47:16 +0000195 llvm::OwningPtr<llvm::MemoryBuffer>
Chris Lattner35de5122008-04-01 18:04:30 +0000196 MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str()));
Ted Kremenek2f743592007-12-05 21:36:08 +0000197
198 if (!MBuffer) {
199 // FIXME: Provide diagnostic.
200 return NULL;
201 }
202
203 // Check if the file is of the proper length.
204 if (MBuffer->getBufferSize() & 0x3) {
205 // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
206 return NULL;
207 }
208
209 // Create the bitstream reader.
210 unsigned char *BufPtr = (unsigned char *) MBuffer->getBufferStart();
211 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer->getBufferSize());
212
213 if (Stream.Read(8) != 'B' ||
214 Stream.Read(8) != 'C' ||
215 Stream.Read(4) != 0xC ||
216 Stream.Read(4) != 0xF ||
217 Stream.Read(4) != 0xE ||
218 Stream.Read(4) != 0x0) {
219 // FIXME: Provide diagnostic.
220 return NULL;
221 }
222
223 // Create the deserializer.
224 llvm::Deserializer Dezr(Stream);
225
Ted Kremenekdca29272007-12-18 21:44:50 +0000226 return TranslationUnit::Create(Dezr,FMgr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000227}
228
229TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
230 FileManager& FMgr) {
231
232 // Create the translation unit object.
233 TranslationUnit* TU = new TranslationUnit();
234
235 // ===---------------------------------------------------===/
236 // Deserialize the "Translation Unit" metadata.
237 // ===---------------------------------------------------===/
238
239 // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
240 // (which will appear earlier) and record its location.
241
242 bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
243 assert (FoundBlock);
244
245 llvm::Deserializer::Location ASTContextBlockLoc =
246 Dezr.getCurrentBlockLocation();
247
248 FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
249 assert (FoundBlock);
Ted Kremenek63ea8632007-12-19 19:27:38 +0000250
Ted Kremenek2f743592007-12-05 21:36:08 +0000251 // Read the SourceManager.
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000252 SourceManager::CreateAndRegister(Dezr,FMgr);
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000253
Ted Kremenekbbced582007-12-12 18:05:32 +0000254 { // Read the TargetInfo.
Ted Kremenek2f743592007-12-05 21:36:08 +0000255 llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
256 char* triple = Dezr.ReadCStr(NULL,0,true);
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000257 Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple)));
Ted Kremenek2f743592007-12-05 21:36:08 +0000258 delete [] triple;
Ted Kremenek2f743592007-12-05 21:36:08 +0000259 }
260
261 // For Selectors, we must read the identifier table first because the
262 // SelectorTable depends on the identifiers being already deserialized.
263 llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();
264 Dezr.SkipBlock();
265
266 // Read the identifier table.
267 IdentifierTable::CreateAndRegister(Dezr);
268
269 // Now jump back and read the selectors.
270 Dezr.JumpTo(SelectorBlkLoc);
271 SelectorTable::CreateAndRegister(Dezr);
272
273 // Now jump back to ASTContextBlock and read the ASTContext.
274 Dezr.JumpTo(ASTContextBlockLoc);
275 TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
276
277 // "Rewind" the stream. Find the block with the serialized top-level decls.
278 Dezr.Rewind();
279 FoundBlock = Dezr.SkipToBlock(DeclsBlock);
280 assert (FoundBlock);
281 llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
282
283 while (!Dezr.FinishedBlock(DeclBlockLoc))
Sam Bishope2563ca2008-04-07 21:55:54 +0000284 TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>(*TU->Context));
Ted Kremenek2f743592007-12-05 21:36:08 +0000285
286 return TU;
287}
288