blob: a0a800c1e31490be68f1a26d12085c3dd8278220 [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 +000029
Sam Bishopfc8584c2008-04-03 14:20:28 +000030TranslationUnit::~TranslationUnit() {
Eli Friedman01a8b6c2008-05-21 05:33:10 +000031 if (OwnsMetaData && Context) {
Ted Kremenek863b01f2008-04-23 16:25:39 +000032 // The ASTContext object has the sole references to the IdentifierTable
33 // Selectors, and the Target information. Go and delete them, since
34 // the TranslationUnit effectively owns them.
Chris Lattner9c18fde2009-03-28 01:44:40 +000035 delete &Context->Idents;
36 delete &Context->Selectors;
37 delete &Context->Target;
Ted Kremenek863b01f2008-04-23 16:25:39 +000038 delete Context;
39 }
Sam Bishop49492512008-04-03 05:35:20 +000040}
Ted Kremenekab749372007-12-19 19:27:38 +000041
Zhongxing Xu605ad512008-12-21 04:46:06 +000042bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
Ted Kremenek863b01f2008-04-23 16:25:39 +000043 const llvm::sys::Path& Filename) {
44
45 return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
46}
47
Ted Kremenek438a8f02008-07-10 22:10:48 +000048bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,
49 std::vector<unsigned char>& Buffer) {
50
51 return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false;
52}
53
54bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,
55 std::ostream& Stream) {
56
57 return TU ? EmitASTBitcodeStream(*TU, Stream) : false;
58}
59
60bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,
61 std::vector<unsigned char>& Buffer) {
Ted Kremenek6f046da2007-12-05 21:36:08 +000062 // 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.
Chris Lattnerb09b31d2009-03-28 03:45:20 +000079 TU.getContext().EmitAll(Sezr);
Ted Kremenek6f046da2007-12-05 21:36:08 +000080 }
81
Ted Kremenek438a8f02008-07-10 22:10:48 +000082 return true;
83}
84
85bool clang::EmitASTBitcodeStream(const TranslationUnit& TU,
86 std::ostream& Stream) {
87
88 // Reserve 256K for bitstream buffer.
89 std::vector<unsigned char> Buffer;
90 Buffer.reserve(256*1024);
91
92 EmitASTBitcodeBuffer(TU,Buffer);
93
94 // Write the bits to disk.
95 Stream.write((char*)&Buffer.front(), Buffer.size());
96 return true;
97}
98
99bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
100 const llvm::sys::Path& Filename) {
101
102 // Reserve 256K for bitstream buffer.
103 std::vector<unsigned char> Buffer;
104 Buffer.reserve(256*1024);
105
106 EmitASTBitcodeBuffer(TU,Buffer);
107
Ted Kremenek6f046da2007-12-05 21:36:08 +0000108 // Write the bits to disk.
109 if (FILE* fp = fopen(Filename.c_str(),"wb")) {
110 fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
111 fclose(fp);
112 return true;
113 }
114
115 return false;
116}
117
Ted Kremenek397de012007-12-13 00:37:31 +0000118TranslationUnit*
Ted Kremenek438a8f02008-07-10 22:10:48 +0000119clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) {
120
Ted Kremenek6f046da2007-12-05 21:36:08 +0000121 // Check if the file is of the proper length.
Ted Kremenek438a8f02008-07-10 22:10:48 +0000122 if (MBuffer.getBufferSize() & 0x3) {
Ted Kremenek6f046da2007-12-05 21:36:08 +0000123 // FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
124 return NULL;
125 }
126
127 // Create the bitstream reader.
Ted Kremenek438a8f02008-07-10 22:10:48 +0000128 unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart();
129 llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize());
Ted Kremenek6f046da2007-12-05 21:36:08 +0000130
131 if (Stream.Read(8) != 'B' ||
132 Stream.Read(8) != 'C' ||
133 Stream.Read(4) != 0xC ||
134 Stream.Read(4) != 0xF ||
135 Stream.Read(4) != 0xE ||
136 Stream.Read(4) != 0x0) {
137 // FIXME: Provide diagnostic.
138 return NULL;
139 }
140
141 // Create the deserializer.
142 llvm::Deserializer Dezr(Stream);
143
Ted Kremenekeccf0702007-12-18 21:44:50 +0000144 return TranslationUnit::Create(Dezr,FMgr);
Ted Kremenek6f046da2007-12-05 21:36:08 +0000145}
146
147TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
148 FileManager& FMgr) {
149
150 // Create the translation unit object.
151 TranslationUnit* TU = new TranslationUnit();
152
Chris Lattner06459ae2009-03-28 03:49:26 +0000153 TU->Context = ASTContext::CreateAll(Dezr, FMgr);
Ted Kremenek6f046da2007-12-05 21:36:08 +0000154
Ted Kremenek6f046da2007-12-05 21:36:08 +0000155 return TU;
156}