blob: 8ceada593ede256e489585d0b80b0710a4c7c2a6 [file] [log] [blame]
//===--- TranslationUnit.cpp - Abstraction for Translation Units ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// FIXME: This should eventually be moved out of the driver, or replaced
// with its eventual successor.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/TranslationUnit.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/SourceManager.h"
#include "clang/AST/AST.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Path.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/DenseSet.h"
using namespace clang;
TranslationUnit::~TranslationUnit() {
if (OwnsMetaData && Context) {
// The ASTContext object has the sole references to the IdentifierTable
// Selectors, and the Target information. Go and delete them, since
// the TranslationUnit effectively owns them.
delete &Context->Idents;
delete &Context->Selectors;
delete &Context->Target;
delete Context;
}
}
bool clang::EmitASTBitcodeFile(const TranslationUnit* TU,
const llvm::sys::Path& Filename) {
return TU ? EmitASTBitcodeFile(*TU, Filename) : false;
}
bool clang::EmitASTBitcodeBuffer(const TranslationUnit* TU,
std::vector<unsigned char>& Buffer) {
return TU ? EmitASTBitcodeBuffer(*TU, Buffer) : false;
}
bool clang::EmitASTBitcodeStream(const TranslationUnit* TU,
std::ostream& Stream) {
return TU ? EmitASTBitcodeStream(*TU, Stream) : false;
}
bool clang::EmitASTBitcodeBuffer(const TranslationUnit& TU,
std::vector<unsigned char>& Buffer) {
// Create bitstream.
llvm::BitstreamWriter Stream(Buffer);
// Emit the preamble.
Stream.Emit((unsigned)'B', 8);
Stream.Emit((unsigned)'C', 8);
Stream.Emit(0xC, 4);
Stream.Emit(0xF, 4);
Stream.Emit(0xE, 4);
Stream.Emit(0x0, 4);
{
// Create serializer. Placing it in its own scope assures any necessary
// finalization of bits to the buffer in the serializer's dstor.
llvm::Serializer Sezr(Stream);
// Emit the translation unit.
TU.getContext().EmitAll(Sezr);
}
return true;
}
bool clang::EmitASTBitcodeStream(const TranslationUnit& TU,
std::ostream& Stream) {
// Reserve 256K for bitstream buffer.
std::vector<unsigned char> Buffer;
Buffer.reserve(256*1024);
EmitASTBitcodeBuffer(TU,Buffer);
// Write the bits to disk.
Stream.write((char*)&Buffer.front(), Buffer.size());
return true;
}
bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
const llvm::sys::Path& Filename) {
// Reserve 256K for bitstream buffer.
std::vector<unsigned char> Buffer;
Buffer.reserve(256*1024);
EmitASTBitcodeBuffer(TU,Buffer);
// Write the bits to disk.
if (FILE* fp = fopen(Filename.c_str(),"wb")) {
fwrite((char*)&Buffer.front(), sizeof(char), Buffer.size(), fp);
fclose(fp);
return true;
}
return false;
}
TranslationUnit*
clang::ReadASTBitcodeBuffer(llvm::MemoryBuffer& MBuffer, FileManager& FMgr) {
// Check if the file is of the proper length.
if (MBuffer.getBufferSize() & 0x3) {
// FIXME: Provide diagnostic: "Length should be a multiple of 4 bytes."
return NULL;
}
// Create the bitstream reader.
unsigned char *BufPtr = (unsigned char *) MBuffer.getBufferStart();
llvm::BitstreamReader Stream(BufPtr,BufPtr+MBuffer.getBufferSize());
if (Stream.Read(8) != 'B' ||
Stream.Read(8) != 'C' ||
Stream.Read(4) != 0xC ||
Stream.Read(4) != 0xF ||
Stream.Read(4) != 0xE ||
Stream.Read(4) != 0x0) {
// FIXME: Provide diagnostic.
return NULL;
}
// Create the deserializer.
llvm::Deserializer Dezr(Stream);
return TranslationUnit::Create(Dezr,FMgr);
}
TranslationUnit*
clang::ReadASTBitcodeFile(const llvm::sys::Path& Filename, FileManager& FMgr) {
// Create the memory buffer that contains the contents of the file.
llvm::OwningPtr<llvm::MemoryBuffer>
MBuffer(llvm::MemoryBuffer::getFile(Filename.c_str()));
if (!MBuffer) {
// FIXME: Provide diagnostic.
return NULL;
}
return ReadASTBitcodeBuffer(*MBuffer, FMgr);
}
TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
FileManager& FMgr) {
// Create the translation unit object.
TranslationUnit* TU = new TranslationUnit();
TU->Context = ASTContext.CreateAll(Dezr, FmMgr);
return TU;
}