blob: ed84241df423ccb7b8ab829d8fc1883d33358f30 [file] [log] [blame]
Ted Kremenek27cc3c22007-12-13 17:54:02 +00001//===--- TranslationUnit.cpp - Abstraction for Translation Units ----------===//
Ted Kremenek6f046da2007-12-05 21:36:08 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-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 Kremenek6f046da2007-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 Kremenek3a0b28b2007-12-18 21:36:21 +000013#include "clang/AST/TranslationUnit.h"
Ted Kremenek6f046da2007-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 Kremenek6f046da2007-12-05 21:36:08 +000023
Ted Kremenekafdf8112008-05-20 00:43:19 +000024#include "llvm/ADT/OwningPtr.h"
25#include "llvm/ADT/DenseSet.h"
Ted Kremenek6f046da2007-12-05 21:36:08 +000026
Ted Kremenek6f046da2007-12-05 21:36:08 +000027using namespace clang;
28
Ted Kremenekab749372007-12-19 19:27:38 +000029enum { BasicMetadataBlock = 1,
30 ASTContextBlock = 2,
31 DeclsBlock = 3 };
32
Sam Bishopfc8584c2008-04-03 14:20:28 +000033TranslationUnit::~TranslationUnit() {
Eli Friedman01a8b6c2008-05-21 05:33:10 +000034 if (OwnsMetaData && Context) {
Ted Kremenek863b01f2008-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.
Chris Lattner9c18fde2009-03-28 01:44:40 +000038 delete &Context->Idents;
39 delete &Context->Selectors;
40 delete &Context->Target;
Ted Kremenek863b01f2008-04-23 16:25:39 +000041 delete Context;
42 }
Sam Bishop49492512008-04-03 05:35:20 +000043}
Ted Kremenekab749372007-12-19 19:27:38 +000044
Zhongxing Xu605ad512008-12-21 04:46:06 +000045bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
Ted Kremenek863b01f2008-04-23 16:25:39 +000046 const llvm::sys::Path& Filename) {
47
48 return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
49}
50
Ted Kremenek438a8f02008-07-10 22:10:48 +000051bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,
52 std::vector<unsigned char>& Buffer) {
53
54 return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false;
55}
56
57bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,
58 std::ostream& Stream) {
59
60 return TU ? EmitASTBitcodeStream(*TU, Stream) : false;
61}
62
63bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,
64 std::vector<unsigned char>& Buffer) {
Ted Kremenek6f046da2007-12-05 21:36:08 +000065 // Create bitstream.
66 llvm::BitstreamWriter Stream(Buffer);
67
68 // Emit the preamble.
69 Stream.Emit((unsigned)'B', 8);
70 Stream.Emit((unsigned)'C', 8);
71 Stream.Emit(0xC, 4);
72 Stream.Emit(0xF, 4);
73 Stream.Emit(0xE, 4);
74 Stream.Emit(0x0, 4);
75
76 {
77 // Create serializer. Placing it in its own scope assures any necessary
78 // finalization of bits to the buffer in the serializer's dstor.
79 llvm::Serializer Sezr(Stream);
80
81 // Emit the translation unit.
Ted Kremenekeccf0702007-12-18 21:44:50 +000082 TU.Emit(Sezr);
Ted Kremenek6f046da2007-12-05 21:36:08 +000083 }
84
Ted Kremenek438a8f02008-07-10 22:10:48 +000085 return true;
86}
87
88bool clang::EmitASTBitcodeStream(const TranslationUnit& TU,
89 std::ostream& Stream) {
90
91 // Reserve 256K for bitstream buffer.
92 std::vector<unsigned char> Buffer;
93 Buffer.reserve(256*1024);
94
95 EmitASTBitcodeBuffer(TU,Buffer);
96
97 // Write the bits to disk.
98 Stream.write((char*)&Buffer.front(), Buffer.size());
99 return true;
100}
101
102bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
103 const llvm::sys::Path& Filename) {
104
105 // Reserve 256K for bitstream buffer.
106 std::vector<unsigned char> Buffer;
107 Buffer.reserve(256*1024);
108
109 EmitASTBitcodeBuffer(TU,Buffer);
110
Ted Kremenek6f046da2007-12-05 21:36:08 +0000111 // Write the bits to disk.
112 if (FILE* fp = fopen(Filename.c_str(),"wb")) {
113 fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
114 fclose(fp);
115 return true;
116 }
117
118 return false;
119}
120
121void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
Ted Kremenek6f046da2007-12-05 21:36:08 +0000122 // ===---------------------------------------------------===/
123 // Serialize the "Translation Unit" metadata.
124 // ===---------------------------------------------------===/
125
126 // Emit ASTContext.
127 Sezr.EnterBlock(ASTContextBlock);
128 Sezr.EmitOwnedPtr(Context);
Zhongxing Xu80da19a2008-12-21 13:00:52 +0000129 Sezr.ExitBlock(); // exit "ASTContextBlock"
Ted Kremenek6f046da2007-12-05 21:36:08 +0000130
131 Sezr.EnterBlock(BasicMetadataBlock);
132
Ted Kremenek842126e2008-06-04 15:55:15 +0000133 // Block for SourceManager and Target. Allows easy skipping
Ted Kremenek6f046da2007-12-05 21:36:08 +0000134 // around to the block for the Selectors during deserialization.
135 Sezr.EnterBlock();
Ted Kremenekd890f6a2007-12-19 22:24:34 +0000136
Ted Kremenek6f046da2007-12-05 21:36:08 +0000137 // Emit the SourceManager.
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000138 Sezr.Emit(Context->getSourceManager());
Ted Kremenek842126e2008-06-04 15:55:15 +0000139
Ted Kremenek6f046da2007-12-05 21:36:08 +0000140 // Emit the Target.
141 Sezr.EmitPtr(&Context->Target);
142 Sezr.EmitCStr(Context->Target.getTargetTriple());
143
Zhongxing Xu80da19a2008-12-21 13:00:52 +0000144 Sezr.ExitBlock(); // exit "SourceManager and Target Block"
Ted Kremenek6f046da2007-12-05 21:36:08 +0000145
146 // Emit the Selectors.
147 Sezr.Emit(Context->Selectors);
148
149 // Emit the Identifier Table.
150 Sezr.Emit(Context->Idents);
151
Zhongxing Xu80da19a2008-12-21 13:00:52 +0000152 Sezr.ExitBlock(); // exit "BasicMetadataBlock"
Ted Kremenek6f046da2007-12-05 21:36:08 +0000153}
154
Ted Kremenek397de012007-12-13 00:37:31 +0000155TranslationUnit*
Ted Kremenek438a8f02008-07-10 22:10:48 +0000156clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) {
157
Ted Kremenek6f046da2007-12-05 21:36:08 +0000158 // Check if the file is of the proper length.
Ted Kremenek438a8f02008-07-10 22:10:48 +0000159 if (MBuffer.getBufferSize() & 0x3) {
Ted Kremenek6f046da2007-12-05 21:36:08 +0000160 // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
161 return NULL;
162 }
163
164 // Create the bitstream reader.
Ted Kremenek438a8f02008-07-10 22:10:48 +0000165 unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart();
166 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize());
Ted Kremenek6f046da2007-12-05 21:36:08 +0000167
168 if (Stream.Read(8) != 'B' ||
169 Stream.Read(8) != 'C' ||
170 Stream.Read(4) != 0xC ||
171 Stream.Read(4) != 0xF ||
172 Stream.Read(4) != 0xE ||
173 Stream.Read(4) != 0x0) {
174 // FIXME: Provide diagnostic.
175 return NULL;
176 }
177
178 // Create the deserializer.
179 llvm::Deserializer Dezr(Stream);
180
Ted Kremenekeccf0702007-12-18 21:44:50 +0000181 return TranslationUnit::Create(Dezr,FMgr);
Ted Kremenek6f046da2007-12-05 21:36:08 +0000182}
183
Ted Kremenek438a8f02008-07-10 22:10:48 +0000184TranslationUnit*
185clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) {
186
187 // Create the memory buffer that contains the contents of the file.
188 llvm::OwningPtr<llvm::MemoryBuffer>
189 MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str()));
190
191 if (!MBuffer) {
192 // FIXME: Provide diagnostic.
193 return NULL;
194 }
195
196 return ReadASTBitcodeBuffer(*MBuffer, FMgr);
197}
198
Ted Kremenek6f046da2007-12-05 21:36:08 +0000199TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
200 FileManager& FMgr) {
201
202 // Create the translation unit object.
203 TranslationUnit* TU = new TranslationUnit();
204
205 // ===---------------------------------------------------===/
206 // Deserialize the "Translation Unit" metadata.
207 // ===---------------------------------------------------===/
208
209 // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
210 // (which will appear earlier) and record its location.
211
212 bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
213 assert (FoundBlock);
214
215 llvm::Deserializer::Location ASTContextBlockLoc =
216 Dezr.getCurrentBlockLocation();
217
218 FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
219 assert (FoundBlock);
Ted Kremenekab749372007-12-19 19:27:38 +0000220
Ted Kremenek6f046da2007-12-05 21:36:08 +0000221 // Read the SourceManager.
Ted Kremenekd7f64cd2007-12-12 22:39:36 +0000222 SourceManager::CreateAndRegister(Dezr,FMgr);
Ted Kremenek842126e2008-06-04 15:55:15 +0000223
Ted Kremenek38591a22007-12-12 18:05:32 +0000224 { // Read the TargetInfo.
Ted Kremenek6f046da2007-12-05 21:36:08 +0000225 llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
226 char* triple = Dezr.ReadCStr(NULL,0,true);
Ted Kremenek863b01f2008-04-23 16:25:39 +0000227 Dezr.RegisterPtr(PtrID, TargetInfo::CreateTargetInfo(std::string(triple)));
Ted Kremenek6f046da2007-12-05 21:36:08 +0000228 delete [] triple;
Ted Kremenek6f046da2007-12-05 21:36:08 +0000229 }
230
231 // For Selectors, we must read the identifier table first because the
232 // SelectorTable depends on the identifiers being already deserialized.
Chris Lattnerb6eccdc2009-02-16 22:33:34 +0000233 llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();
Ted Kremenek6f046da2007-12-05 21:36:08 +0000234 Dezr.SkipBlock();
235
236 // Read the identifier table.
237 IdentifierTable::CreateAndRegister(Dezr);
238
239 // Now jump back and read the selectors.
240 Dezr.JumpTo(SelectorBlkLoc);
241 SelectorTable::CreateAndRegister(Dezr);
242
243 // Now jump back to ASTContextBlock and read the ASTContext.
244 Dezr.JumpTo(ASTContextBlockLoc);
245 TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
246
Ted Kremenek6f046da2007-12-05 21:36:08 +0000247 return TU;
248}
249