blob: 95cad39f6812f88ae6787d9e979cd80aa285d9ea [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 (OwnsMetaData && Context) {
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000035 // The ASTContext object has the sole references to the IdentifierTable
36 // Selectors, and the Target information. Go and delete them, since
37 // the TranslationUnit effectively owns them.
Eli Friedman5f1adf82008-05-21 05:33:10 +000038
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000039 delete &(Context->Idents);
40 delete &(Context->Selectors);
41 delete &(Context->Target);
42 delete Context;
43 }
Sam Bishop71de20e2008-04-03 05:35:20 +000044}
Ted Kremenek63ea8632007-12-19 19:27:38 +000045
Zhongxing Xu8ce66662008-12-21 04:46:06 +000046bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
Ted Kremenekc1e9dea2008-04-23 16:25:39 +000047 const llvm::sys::Path& Filename) {
48
49 return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
50}
51
Ted Kremenek0ce902b2008-07-10 22:10:48 +000052bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,
53 std::vector<unsigned char>& Buffer) {
54
55 return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false;
56}
57
58bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,
59 std::ostream& Stream) {
60
61 return TU ? EmitASTBitcodeStream(*TU, Stream) : false;
62}
63
64bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,
65 std::vector<unsigned char>& Buffer) {
Ted Kremenek2f743592007-12-05 21:36:08 +000066 // Create bitstream.
67 llvm::BitstreamWriter Stream(Buffer);
68
69 // Emit the preamble.
70 Stream.Emit((unsigned)'B', 8);
71 Stream.Emit((unsigned)'C', 8);
72 Stream.Emit(0xC, 4);
73 Stream.Emit(0xF, 4);
74 Stream.Emit(0xE, 4);
75 Stream.Emit(0x0, 4);
76
77 {
78 // Create serializer. Placing it in its own scope assures any necessary
79 // finalization of bits to the buffer in the serializer's dstor.
80 llvm::Serializer Sezr(Stream);
81
82 // Emit the translation unit.
Ted Kremenekdca29272007-12-18 21:44:50 +000083 TU.Emit(Sezr);
Ted Kremenek2f743592007-12-05 21:36:08 +000084 }
85
Ted Kremenek0ce902b2008-07-10 22:10:48 +000086 return true;
87}
88
89bool clang::EmitASTBitcodeStream(const TranslationUnit& TU,
90 std::ostream& Stream) {
91
92 // Reserve 256K for bitstream buffer.
93 std::vector<unsigned char> Buffer;
94 Buffer.reserve(256*1024);
95
96 EmitASTBitcodeBuffer(TU,Buffer);
97
98 // Write the bits to disk.
99 Stream.write((char*)&Buffer.front(), Buffer.size());
100 return true;
101}
102
103bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
104 const llvm::sys::Path& Filename) {
105
106 // Reserve 256K for bitstream buffer.
107 std::vector<unsigned char> Buffer;
108 Buffer.reserve(256*1024);
109
110 EmitASTBitcodeBuffer(TU,Buffer);
111
Ted Kremenek2f743592007-12-05 21:36:08 +0000112 // Write the bits to disk.
113 if (FILE* fp = fopen(Filename.c_str(),"wb")) {
114 fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
115 fclose(fp);
116 return true;
117 }
118
119 return false;
120}
121
122void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
Ted Kremenek2f743592007-12-05 21:36:08 +0000123 // ===---------------------------------------------------===/
124 // Serialize the "Translation Unit" metadata.
125 // ===---------------------------------------------------===/
126
127 // Emit ASTContext.
128 Sezr.EnterBlock(ASTContextBlock);
129 Sezr.EmitOwnedPtr(Context);
Zhongxing Xuc994bb22008-12-21 13:00:52 +0000130 Sezr.ExitBlock(); // exit "ASTContextBlock"
Ted Kremenek2f743592007-12-05 21:36:08 +0000131
132 Sezr.EnterBlock(BasicMetadataBlock);
133
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000134 // Block for SourceManager and Target. Allows easy skipping
Ted Kremenek2f743592007-12-05 21:36:08 +0000135 // around to the block for the Selectors during deserialization.
136 Sezr.EnterBlock();
Ted Kremenekfdfc1982007-12-19 22:24:34 +0000137
Ted Kremenek2f743592007-12-05 21:36:08 +0000138 // Emit the SourceManager.
Ted Kremenek7a9d49f2007-12-11 21:27:55 +0000139 Sezr.Emit(Context->getSourceManager());
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000140
Ted Kremenek2f743592007-12-05 21:36:08 +0000141 // Emit the Target.
142 Sezr.EmitPtr(&Context->Target);
143 Sezr.EmitCStr(Context->Target.getTargetTriple());
144
Zhongxing Xuc994bb22008-12-21 13:00:52 +0000145 Sezr.ExitBlock(); // exit "SourceManager and Target Block"
Ted Kremenek2f743592007-12-05 21:36:08 +0000146
147 // Emit the Selectors.
148 Sezr.Emit(Context->Selectors);
149
150 // Emit the Identifier Table.
151 Sezr.Emit(Context->Idents);
152
Zhongxing Xuc994bb22008-12-21 13:00:52 +0000153 Sezr.ExitBlock(); // exit "BasicMetadataBlock"
Ted Kremenek2f743592007-12-05 21:36:08 +0000154}
155
Ted Kremeneka1fa3a12007-12-13 00:37:31 +0000156TranslationUnit*
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000157clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) {
158
Ted Kremenek2f743592007-12-05 21:36:08 +0000159 // Check if the file is of the proper length.
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000160 if (MBuffer.getBufferSize() & 0x3) {
Ted Kremenek2f743592007-12-05 21:36:08 +0000161 // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
162 return NULL;
163 }
164
165 // Create the bitstream reader.
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000166 unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart();
167 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize());
Ted Kremenek2f743592007-12-05 21:36:08 +0000168
169 if (Stream.Read(8) != 'B' ||
170 Stream.Read(8) != 'C' ||
171 Stream.Read(4) != 0xC ||
172 Stream.Read(4) != 0xF ||
173 Stream.Read(4) != 0xE ||
174 Stream.Read(4) != 0x0) {
175 // FIXME: Provide diagnostic.
176 return NULL;
177 }
178
179 // Create the deserializer.
180 llvm::Deserializer Dezr(Stream);
181
Ted Kremenekdca29272007-12-18 21:44:50 +0000182 return TranslationUnit::Create(Dezr,FMgr);
Ted Kremenek2f743592007-12-05 21:36:08 +0000183}
184
Ted Kremenek0ce902b2008-07-10 22:10:48 +0000185TranslationUnit*
186clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) {
187
188 // Create the memory buffer that contains the contents of the file.
189 llvm::OwningPtr<llvm::MemoryBuffer>
190 MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str()));
191
192 if (!MBuffer) {
193 // FIXME: Provide diagnostic.
194 return NULL;
195 }
196
197 return ReadASTBitcodeBuffer(*MBuffer, FMgr);
198}
199
Ted Kremenek2f743592007-12-05 21:36:08 +0000200TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
201 FileManager& FMgr) {
202
203 // Create the translation unit object.
204 TranslationUnit* TU = new TranslationUnit();
205
206 // ===---------------------------------------------------===/
207 // Deserialize the "Translation Unit" metadata.
208 // ===---------------------------------------------------===/
209
210 // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
211 // (which will appear earlier) and record its location.
212
213 bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
214 assert (FoundBlock);
215
216 llvm::Deserializer::Location ASTContextBlockLoc =
217 Dezr.getCurrentBlockLocation();
218
219 FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
220 assert (FoundBlock);
Ted Kremenek63ea8632007-12-19 19:27:38 +0000221
Ted Kremenek2f743592007-12-05 21:36:08 +0000222 // Read the SourceManager.
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000223 SourceManager::CreateAndRegister(Dezr,FMgr);
Ted Kremeneke7d07d12008-06-04 15:55:15 +0000224
Ted Kremenekbbced582007-12-12 18:05:32 +0000225 { // Read the TargetInfo.
Ted Kremenek2f743592007-12-05 21:36:08 +0000226 llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
227 char* triple = Dezr.ReadCStr(NULL,0,true);
Ted Kremenekc1e9dea2008-04-23 16:25:39 +0000228 Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple)));
Ted Kremenek2f743592007-12-05 21:36:08 +0000229 delete [] triple;
Ted Kremenek2f743592007-12-05 21:36:08 +0000230 }
231
232 // For Selectors, we must read the identifier table first because the
233 // SelectorTable depends on the identifiers being already deserialized.
Chris Lattnerd603eaa2009-02-16 22:33:34 +0000234 llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();
Ted Kremenek2f743592007-12-05 21:36:08 +0000235 Dezr.SkipBlock();
236
237 // Read the identifier table.
238 IdentifierTable::CreateAndRegister(Dezr);
239
240 // Now jump back and read the selectors.
241 Dezr.JumpTo(SelectorBlkLoc);
242 SelectorTable::CreateAndRegister(Dezr);
243
244 // Now jump back to ASTContextBlock and read the ASTContext.
245 Dezr.JumpTo(ASTContextBlockLoc);
246 TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
247
Ted Kremenek2f743592007-12-05 21:36:08 +0000248 return TU;
249}
250