blob: 5c043efeb31753e7671ffcc4f77cf0f9fdca6732 [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 Kremenekee533642007-12-20 19:47:16 +000023#include "llvm/ADT/OwningPtr.h"
Ted Kremenek2f743592007-12-05 21:36:08 +000024
25#include <stdio.h>
26
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() {
Sam Bishop71de20e2008-04-03 05:35:20 +000034 for (iterator I=begin(), E=end(); I!=E; ++I)
Sam Bishopbb45c512008-04-11 15:01:25 +000035 (*I)->Destroy(*Context);
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000036
37 if (OwnsMetaData && Context) {
38 // The ASTContext object has the sole references to the IdentifierTable
39 // Selectors, and the Target information. Go and delete them, since
40 // the TranslationUnit effectively owns them.
41
42 delete &(Context->Idents);
43 delete &(Context->Selectors);
44 delete &(Context->Target);
45 delete Context;
46 }
Sam Bishop71de20e2008-04-03 05:35:20 +000047}
Ted Kremenek63ea8632007-12-19 19:27:38 +000048
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000049bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
50 const llvm::sys::Path& Filename) {
51
52 return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
53}
54
Ted Kremenekdca29272007-12-18 21:44:50 +000055bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
56 const llvm::sys::Path& Filename) {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000057
Ted Kremenek2f743592007-12-05 21:36:08 +000058 // Reserve 256K for bitstream buffer.
59 std::vector<unsigned char> Buffer;
60 Buffer.reserve(256*1024);
61
62 // Create bitstream.
63 llvm::BitstreamWriter Stream(Buffer);
64
65 // Emit the preamble.
66 Stream.Emit((unsigned)'B', 8);
67 Stream.Emit((unsigned)'C', 8);
68 Stream.Emit(0xC, 4);
69 Stream.Emit(0xF, 4);
70 Stream.Emit(0xE, 4);
71 Stream.Emit(0x0, 4);
72
73 {
74 // Create serializer. Placing it in its own scope assures any necessary
75 // finalization of bits to the buffer in the serializer's dstor.
76 llvm::Serializer Sezr(Stream);
77
78 // Emit the translation unit.
Ted Kremenekdca29272007-12-18 21:44:50 +000079 TU.Emit(Sezr);
Ted Kremenek2f743592007-12-05 21:36:08 +000080 }
81
82 // Write the bits to disk.
83 if (FILE* fp = fopen(Filename.c_str(),"wb")) {
84 fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
85 fclose(fp);
86 return true;
87 }
88
89 return false;
90}
91
92void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
93
94 // ===---------------------------------------------------===/
95 // Serialize the top-level decls.
96 // ===---------------------------------------------------===/
97
98 Sezr.EnterBlock(DeclsBlock);
99
100 // Only serialize the head of a decl chain. The ASTConsumer interfaces
101 // provides us with each top-level decl, including those nested in
102 // a decl chain, so we may be passed decls that are already serialized.
103 for (const_iterator I=begin(), E=end(); I!=E; ++I)
104 if (!Sezr.isRegistered(*I))
105 Sezr.EmitOwnedPtr(*I);
106
107 Sezr.ExitBlock();
108
109 // ===---------------------------------------------------===/
110 // Serialize the "Translation Unit" metadata.
111 // ===---------------------------------------------------===/
112
113 // Emit ASTContext.
114 Sezr.EnterBlock(ASTContextBlock);
115 Sezr.EmitOwnedPtr(Context);
116 Sezr.ExitBlock();
117
118 Sezr.EnterBlock(BasicMetadataBlock);
119
120 // Block for SourceManager, LangOptions, and Target. Allows easy skipping
121 // around to the block for the Selectors during deserialization.
122 Sezr.EnterBlock();
Ted Kremenekfdfc1982007-12-19 22:24:34 +0000123
Ted Kremenek2f743592007-12-05 21:36:08 +0000124 // Emit the SourceManager.
Ted Kremenek7a9d49f2007-12-11 21:27:55 +0000125 Sezr.Emit(Context->getSourceManager());
Ted Kremenek2f743592007-12-05 21:36:08 +0000126
127 // Emit the LangOptions.
128 Sezr.Emit(LangOpts);
129
130 // Emit the Target.
131 Sezr.EmitPtr(&Context->Target);
132 Sezr.EmitCStr(Context->Target.getTargetTriple());
133
134 Sezr.ExitBlock(); // exit "BasicMetadataBlock"
135
136 // Emit the Selectors.
137 Sezr.Emit(Context->Selectors);
138
139 // Emit the Identifier Table.
140 Sezr.Emit(Context->Idents);
141
142 Sezr.ExitBlock(); // exit "ASTContextBlock"
143}
144
Ted Kremeneka1fa3a12007-12-13 00:37:31 +0000145TranslationUnit*
Ted Kremenekdca29272007-12-18 21:44:50 +0000146clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) {
Ted Kremenek2f743592007-12-05 21:36:08 +0000147
148 // Create the memory buffer that contains the contents of the file.
Ted Kremenekee533642007-12-20 19:47:16 +0000149 llvm::OwningPtr<llvm::MemoryBuffer>
Chris Lattner35de5122008-04-01 18:04:30 +0000150 MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str()));
Ted Kremenek2f743592007-12-05 21:36:08 +0000151
152 if (!MBuffer) {
153 // FIXME: Provide diagnostic.
154 return NULL;
155 }
156
157 // Check if the file is of the proper length.
158 if (MBuffer->getBufferSize() & 0x3) {
159 // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
160 return NULL;
161 }
162
163 // Create the bitstream reader.
164 unsigned char *BufPtr = (unsigned char *) MBuffer->getBufferStart();
165 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer->getBufferSize());
166
167 if (Stream.Read(8) != 'B' ||
168 Stream.Read(8) != 'C' ||
169 Stream.Read(4) != 0xC ||
170 Stream.Read(4) != 0xF ||
171 Stream.Read(4) != 0xE ||
172 Stream.Read(4) != 0x0) {
173 // FIXME: Provide diagnostic.
174 return NULL;
175 }
176
177 // Create the deserializer.
178 llvm::Deserializer Dezr(Stream);
179
Ted Kremenekdca29272007-12-18 21:44:50 +0000180 return TranslationUnit::Create(Dezr,FMgr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000181}
182
183TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
184 FileManager& FMgr) {
185
186 // Create the translation unit object.
187 TranslationUnit* TU = new TranslationUnit();
188
189 // ===---------------------------------------------------===/
190 // Deserialize the "Translation Unit" metadata.
191 // ===---------------------------------------------------===/
192
193 // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
194 // (which will appear earlier) and record its location.
195
196 bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
197 assert (FoundBlock);
198
199 llvm::Deserializer::Location ASTContextBlockLoc =
200 Dezr.getCurrentBlockLocation();
201
202 FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
203 assert (FoundBlock);
Ted Kremenek63ea8632007-12-19 19:27:38 +0000204
Ted Kremenek2f743592007-12-05 21:36:08 +0000205 // Read the SourceManager.
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000206 SourceManager::CreateAndRegister(Dezr,FMgr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000207
208 // Read the LangOptions.
209 TU->LangOpts.Read(Dezr);
210
Ted Kremenekbbced582007-12-12 18:05:32 +0000211 { // Read the TargetInfo.
Ted Kremenek2f743592007-12-05 21:36:08 +0000212 llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
213 char* triple = Dezr.ReadCStr(NULL,0,true);
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000214 Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple)));
Ted Kremenek2f743592007-12-05 21:36:08 +0000215 delete [] triple;
Ted Kremenek2f743592007-12-05 21:36:08 +0000216 }
217
218 // For Selectors, we must read the identifier table first because the
219 // SelectorTable depends on the identifiers being already deserialized.
220 llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();
221 Dezr.SkipBlock();
222
223 // Read the identifier table.
224 IdentifierTable::CreateAndRegister(Dezr);
225
226 // Now jump back and read the selectors.
227 Dezr.JumpTo(SelectorBlkLoc);
228 SelectorTable::CreateAndRegister(Dezr);
229
230 // Now jump back to ASTContextBlock and read the ASTContext.
231 Dezr.JumpTo(ASTContextBlockLoc);
232 TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
233
234 // "Rewind" the stream. Find the block with the serialized top-level decls.
235 Dezr.Rewind();
236 FoundBlock = Dezr.SkipToBlock(DeclsBlock);
237 assert (FoundBlock);
238 llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
239
240 while (!Dezr.FinishedBlock(DeclBlockLoc))
Sam Bishope2563ca2008-04-07 21:55:54 +0000241 TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>(*TU->Context));
Ted Kremenek2f743592007-12-05 21:36:08 +0000242
243 return TU;
244}
245