summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/TranslationUnit.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-03-15 23:59:48 +0000
committerChris Lattner <sabre@nondot.org>2008-03-15 23:59:48 +0000
commit7a51313d8a0a358bb92eb5dbf8fd846b7c48e7fe (patch)
treef34d8e560a6abbae809b7dbee85606becf47dfd0 /clang/lib/AST/TranslationUnit.cpp
parentd3f989ccd302d53e327c030347313fbd8d23a344 (diff)
downloadbcm5719-llvm-7a51313d8a0a358bb92eb5dbf8fd846b7c48e7fe.tar.gz
bcm5719-llvm-7a51313d8a0a358bb92eb5dbf8fd846b7c48e7fe.zip
Make a major restructuring of the clang tree: introduce a top-level
lib dir and move all the libraries into it. This follows the main llvm tree, and allows the libraries to be built in parallel. The top level now enforces that all the libs are built before Driver, but we don't care what order the libs are built in. This speeds up parallel builds, particularly incremental ones. llvm-svn: 48402
Diffstat (limited to 'clang/lib/AST/TranslationUnit.cpp')
-rw-r--r--clang/lib/AST/TranslationUnit.cpp225
1 files changed, 225 insertions, 0 deletions
diff --git a/clang/lib/AST/TranslationUnit.cpp b/clang/lib/AST/TranslationUnit.cpp
new file mode 100644
index 00000000000..b91448b2d3f
--- /dev/null
+++ b/clang/lib/AST/TranslationUnit.cpp
@@ -0,0 +1,225 @@
+//===--- 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 <stdio.h>
+
+using namespace clang;
+
+enum { BasicMetadataBlock = 1,
+ ASTContextBlock = 2,
+ DeclsBlock = 3 };
+
+
+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);
+
+ // 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.Emit(Sezr);
+ }
+
+ // 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;
+}
+
+void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
+
+ // ===---------------------------------------------------===/
+ // Serialize the top-level decls.
+ // ===---------------------------------------------------===/
+
+ Sezr.EnterBlock(DeclsBlock);
+
+ // Only serialize the head of a decl chain. The ASTConsumer interfaces
+ // provides us with each top-level decl, including those nested in
+ // a decl chain, so we may be passed decls that are already serialized.
+ for (const_iterator I=begin(), E=end(); I!=E; ++I)
+ if (!Sezr.isRegistered(*I))
+ Sezr.EmitOwnedPtr(*I);
+
+ Sezr.ExitBlock();
+
+ // ===---------------------------------------------------===/
+ // Serialize the "Translation Unit" metadata.
+ // ===---------------------------------------------------===/
+
+ // Emit ASTContext.
+ Sezr.EnterBlock(ASTContextBlock);
+ Sezr.EmitOwnedPtr(Context);
+ Sezr.ExitBlock();
+
+ Sezr.EnterBlock(BasicMetadataBlock);
+
+ // Block for SourceManager, LangOptions, and Target. Allows easy skipping
+ // around to the block for the Selectors during deserialization.
+ Sezr.EnterBlock();
+
+ // Emit the SourceManager.
+ Sezr.Emit(Context->getSourceManager());
+
+ // Emit the LangOptions.
+ Sezr.Emit(LangOpts);
+
+ // Emit the Target.
+ Sezr.EmitPtr(&Context->Target);
+ Sezr.EmitCStr(Context->Target.getTargetTriple());
+
+ Sezr.ExitBlock(); // exit "BasicMetadataBlock"
+
+ // Emit the Selectors.
+ Sezr.Emit(Context->Selectors);
+
+ // Emit the Identifier Table.
+ Sezr.Emit(Context->Idents);
+
+ Sezr.ExitBlock(); // exit "ASTContextBlock"
+}
+
+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(),
+ strlen(Filename.c_str())));
+
+ if (!MBuffer) {
+ // FIXME: Provide diagnostic.
+ return NULL;
+ }
+
+ // 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* TranslationUnit::Create(llvm::Deserializer& Dezr,
+ FileManager& FMgr) {
+
+ // Create the translation unit object.
+ TranslationUnit* TU = new TranslationUnit();
+
+ // ===---------------------------------------------------===/
+ // Deserialize the "Translation Unit" metadata.
+ // ===---------------------------------------------------===/
+
+ // Skip to the BasicMetaDataBlock. First jump to ASTContextBlock
+ // (which will appear earlier) and record its location.
+
+ bool FoundBlock = Dezr.SkipToBlock(ASTContextBlock);
+ assert (FoundBlock);
+
+ llvm::Deserializer::Location ASTContextBlockLoc =
+ Dezr.getCurrentBlockLocation();
+
+ FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
+ assert (FoundBlock);
+
+ // Read the SourceManager.
+ SourceManager::CreateAndRegister(Dezr,FMgr);
+
+ // Read the LangOptions.
+ TU->LangOpts.Read(Dezr);
+
+ { // Read the TargetInfo.
+ llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
+ char* triple = Dezr.ReadCStr(NULL,0,true);
+ Dezr.RegisterPtr(PtrID,TargetInfo::CreateTargetInfo(std::string(triple)));
+ delete [] triple;
+ }
+
+ // For Selectors, we must read the identifier table first because the
+ // SelectorTable depends on the identifiers being already deserialized.
+ llvm::Deserializer::Location SelectorBlkLoc = Dezr.getCurrentBlockLocation();
+ Dezr.SkipBlock();
+
+ // Read the identifier table.
+ IdentifierTable::CreateAndRegister(Dezr);
+
+ // Now jump back and read the selectors.
+ Dezr.JumpTo(SelectorBlkLoc);
+ SelectorTable::CreateAndRegister(Dezr);
+
+ // Now jump back to ASTContextBlock and read the ASTContext.
+ Dezr.JumpTo(ASTContextBlockLoc);
+ TU->Context = Dezr.ReadOwnedPtr<ASTContext>();
+
+ // "Rewind" the stream. Find the block with the serialized top-level decls.
+ Dezr.Rewind();
+ FoundBlock = Dezr.SkipToBlock(DeclsBlock);
+ assert (FoundBlock);
+ llvm::Deserializer::Location DeclBlockLoc = Dezr.getCurrentBlockLocation();
+
+ while (!Dezr.FinishedBlock(DeclBlockLoc))
+ TU->AddTopLevelDecl(Dezr.ReadOwnedPtr<Decl>());
+
+ return TU;
+}
+
OpenPOWER on IntegriCloud