зеркало из https://github.com/microsoft/clang-1.git
Removed storing inode and device number in TranslationUnit.
Added "SourceFile" string to TranslationUnit to record corresponding source file. Updated serialization of TranslationUnits and logic in the driver to correctly pass the source file information to the serializer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45211 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6f62c2abd8
Коммит
63ea863d47
|
@ -24,14 +24,13 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace {
|
||||
enum { BasicMetadataBlock = 1,
|
||||
ASTContextBlock = 2,
|
||||
DeclsBlock = 3 };
|
||||
}
|
||||
|
||||
using namespace clang;
|
||||
|
||||
enum { BasicMetadataBlock = 1,
|
||||
ASTContextBlock = 2,
|
||||
DeclsBlock = 3 };
|
||||
|
||||
|
||||
bool clang::EmitASTBitcodeFile(const TranslationUnit& TU,
|
||||
const llvm::sys::Path& Filename) {
|
||||
|
||||
|
@ -101,6 +100,10 @@ void TranslationUnit::Emit(llvm::Serializer& Sezr) const {
|
|||
// around to the block for the Selectors during deserialization.
|
||||
Sezr.EnterBlock();
|
||||
|
||||
// Emit the name of the source file.
|
||||
Sezr.EmitCStr(SourceFile.c_str());
|
||||
Sezr.FlushRecord();
|
||||
|
||||
// Emit the SourceManager.
|
||||
Sezr.Emit(Context->getSourceManager());
|
||||
|
||||
|
@ -182,6 +185,12 @@ TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
|
|||
|
||||
FoundBlock = Dezr.SkipToBlock(BasicMetadataBlock);
|
||||
assert (FoundBlock);
|
||||
|
||||
{ // Read the SourceFile.
|
||||
char* SName = Dezr.ReadCStr(NULL,0,true);
|
||||
TU->SourceFile = SName;
|
||||
delete [] SName;
|
||||
}
|
||||
|
||||
// Read the SourceManager.
|
||||
SourceManager::CreateAndRegister(Dezr,FMgr);
|
||||
|
|
|
@ -614,10 +614,10 @@ namespace {
|
|||
TranslationUnit TU;
|
||||
const llvm::sys::Path FName;
|
||||
public:
|
||||
ASTSerializer(const llvm::sys::Path& F, Diagnostic &diags,
|
||||
ASTSerializer(const std::string& SourceFile,
|
||||
const llvm::sys::Path& F, Diagnostic &diags,
|
||||
const LangOptions &LO)
|
||||
: Diags(diags), TU(LO), FName(F) {}
|
||||
|
||||
: Diags(diags), TU(SourceFile,LO), FName(F) {}
|
||||
|
||||
virtual void Initialize(ASTContext &Context, unsigned MainFileID) {
|
||||
TU.setContext(&Context);
|
||||
|
@ -637,20 +637,24 @@ namespace {
|
|||
} // end anonymous namespace
|
||||
|
||||
|
||||
ASTConsumer* clang::CreateASTSerializer(const std::string& InFile,
|
||||
ASTConsumer* clang::CreateASTSerializer(const std::string& SourceFile,
|
||||
Diagnostic &Diags,
|
||||
const LangOptions &Features) {
|
||||
|
||||
// FIXME: This is a hack: "/" separator not portable.
|
||||
std::string::size_type idx = InFile.rfind("/");
|
||||
// FIXME: If the translation unit we are serializing came was itself
|
||||
// deserialized from disk, we may overwrite that file. This
|
||||
// is only a temporary bug, since the code in this function will
|
||||
// be completely replaced momentarily.
|
||||
|
||||
if (idx != std::string::npos && idx == InFile.size()-1)
|
||||
// FIXME: This is a hack: "/" separator not portable.
|
||||
std::string::size_type idx = SourceFile.rfind("/");
|
||||
|
||||
if (idx != std::string::npos && idx == SourceFile.size()-1)
|
||||
return NULL;
|
||||
|
||||
std::string TargetPrefix( idx == std::string::npos ?
|
||||
InFile : InFile.substr(idx+1));
|
||||
SourceFile : SourceFile.substr(idx+1));
|
||||
|
||||
llvm::sys::Path FName = llvm::sys::Path((TargetPrefix + ".ast").c_str());
|
||||
|
||||
return new ASTSerializer(FName, Diags, Features);
|
||||
return new ASTSerializer(SourceFile, FName, Diags, Features);
|
||||
}
|
||||
|
|
|
@ -34,10 +34,11 @@ ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
|
|||
ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
|
||||
ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features);
|
||||
ASTConsumer *CreateCodeRewriterTest(Diagnostic &Diags);
|
||||
ASTConsumer *CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr,
|
||||
ASTConsumer *CreateSerializationTest(const std::string& SourceFile,
|
||||
Diagnostic &Diags, FileManager& FMgr,
|
||||
const LangOptions &LOpts);
|
||||
|
||||
ASTConsumer *CreateASTSerializer(const std::string& InFile,
|
||||
ASTConsumer *CreateASTSerializer(const std::string& SourceFile,
|
||||
Diagnostic &Diags, const LangOptions &LOpts);
|
||||
|
||||
} // end clang namespace
|
||||
|
|
|
@ -37,8 +37,9 @@ class SerializationTest : public ASTConsumer {
|
|||
Diagnostic &Diags;
|
||||
FileManager &FMgr;
|
||||
public:
|
||||
SerializationTest(Diagnostic &d, FileManager& fmgr, const LangOptions& LOpts)
|
||||
: TU(LOpts), Diags(d), FMgr(fmgr) {}
|
||||
SerializationTest(const std::string& SourceFile, Diagnostic &d,
|
||||
FileManager& fmgr, const LangOptions& LOpts)
|
||||
: TU(SourceFile, LOpts), Diags(d), FMgr(fmgr) {}
|
||||
|
||||
~SerializationTest();
|
||||
|
||||
|
@ -49,6 +50,7 @@ public:
|
|||
virtual void HandleTopLevelDecl(Decl *D) {
|
||||
TU.AddTopLevelDecl(D);
|
||||
}
|
||||
|
||||
private:
|
||||
bool Serialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
|
||||
bool Deserialize(llvm::sys::Path& Filename, llvm::sys::Path& FNameDeclPrint);
|
||||
|
@ -57,9 +59,9 @@ private:
|
|||
} // end anonymous namespace
|
||||
|
||||
ASTConsumer*
|
||||
clang::CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr,
|
||||
const LangOptions &LOpts) {
|
||||
return new SerializationTest(Diags,FMgr,LOpts);
|
||||
clang::CreateSerializationTest(const std::string& SourceFile, Diagnostic &Diags,
|
||||
FileManager& FMgr, const LangOptions &LOpts) {
|
||||
return new SerializationTest(SourceFile,Diags,FMgr,LOpts);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/System/Signals.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/ADT/scoped_ptr.h"
|
||||
#include <memory>
|
||||
using namespace clang;
|
||||
|
||||
|
@ -887,7 +888,7 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA, unsigned MainFileID){
|
|||
/// CreateASTConsumer - Create the ASTConsumer for the corresponding program
|
||||
/// action. These consumers can operate on both ASTs that are freshly
|
||||
/// parsed from source files as well as those deserialized from Bitcode.
|
||||
static ASTConsumer* CreateASTConsumer(const std::string& InFile,
|
||||
static ASTConsumer* CreateASTConsumer(const std::string& SourceFile,
|
||||
Diagnostic& Diag, FileManager& FileMgr,
|
||||
const LangOptions& LangOpts) {
|
||||
switch (ProgAction) {
|
||||
|
@ -917,14 +918,14 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
|
|||
return CreateUnitValsChecker(Diag);
|
||||
|
||||
case TestSerialization:
|
||||
return CreateSerializationTest(Diag, FileMgr, LangOpts);
|
||||
return CreateSerializationTest(SourceFile, Diag, FileMgr, LangOpts);
|
||||
|
||||
case EmitLLVM:
|
||||
return CreateLLVMEmitter(Diag, LangOpts);
|
||||
|
||||
case SerializeAST:
|
||||
// FIXME: Allow user to tailor where the file is written.
|
||||
return CreateASTSerializer(InFile, Diag, LangOpts);
|
||||
return CreateASTSerializer(SourceFile, Diag, LangOpts);
|
||||
|
||||
case RewriteTest:
|
||||
return CreateCodeRewriterTest(Diag);
|
||||
|
@ -934,7 +935,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
|
|||
/// ProcessInputFile - Process a single input file with the specified state.
|
||||
///
|
||||
static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
|
||||
const std::string &InFile,
|
||||
const std::string &SourceFile,
|
||||
TextDiagnostics &OurDiagnosticClient) {
|
||||
|
||||
ASTConsumer* Consumer = NULL;
|
||||
|
@ -942,7 +943,7 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
|
|||
|
||||
switch (ProgAction) {
|
||||
default:
|
||||
Consumer = CreateASTConsumer(InFile, PP.getDiagnostics(),
|
||||
Consumer = CreateASTConsumer(SourceFile, PP.getDiagnostics(),
|
||||
PP.getFileManager(),
|
||||
PP.getLangOptions());
|
||||
|
||||
|
@ -1005,7 +1006,7 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
|
|||
}
|
||||
|
||||
if (Stats) {
|
||||
fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str());
|
||||
fprintf(stderr, "\nSTATISTICS FOR '%s':\n", SourceFile.c_str());
|
||||
PP.PrintStats();
|
||||
PP.getIdentifierTable().PrintStats();
|
||||
PP.getHeaderSearchInfo().PrintStats();
|
||||
|
@ -1036,7 +1037,7 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
|
|||
exit (1);
|
||||
}
|
||||
|
||||
TranslationUnit* TU = ReadASTBitcodeFile(Filename,FileMgr);
|
||||
llvm::scoped_ptr<TranslationUnit> TU(ReadASTBitcodeFile(Filename,FileMgr));
|
||||
|
||||
if (!TU) {
|
||||
fprintf(stderr, "error: file '%s' could not be deserialized\n",
|
||||
|
@ -1044,8 +1045,11 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
|
|||
exit (1);
|
||||
}
|
||||
|
||||
ASTConsumer* Consumer = CreateASTConsumer(InFile,Diag,
|
||||
FileMgr,TU->getLangOpts());
|
||||
// Observe that we use the source file name stored in the deserialized
|
||||
// translation unit, rather than InFile.
|
||||
llvm::scoped_ptr<ASTConsumer>
|
||||
Consumer(CreateASTConsumer(TU->getSourceFile(), Diag, FileMgr,
|
||||
TU->getLangOpts()));
|
||||
|
||||
if (!Consumer) {
|
||||
fprintf(stderr, "Unsupported program action with serialized ASTs!\n");
|
||||
|
@ -1053,12 +1057,10 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
|
|||
}
|
||||
|
||||
// FIXME: only work on consumers that do not require MainFileID.
|
||||
Consumer->Initialize(*TU->getContext(),0);
|
||||
Consumer->Initialize(*TU->getContext(), 0);
|
||||
|
||||
for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
|
||||
Consumer->HandleTopLevelDecl(*I);
|
||||
|
||||
delete Consumer;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "llvm/Bitcode/SerializationFwd.h"
|
||||
#include "llvm/System/Path.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
@ -30,30 +31,24 @@ class Decl;
|
|||
class FileEntry;
|
||||
|
||||
class TranslationUnit {
|
||||
// Information to help uniquely identify a translation unit on disk.
|
||||
// We may also incorporate a UUID in the future.
|
||||
uint64_t ino;
|
||||
uint64_t dev;
|
||||
const char* SourceFile;
|
||||
|
||||
// The actual data of the translation unit.
|
||||
std::string SourceFile;
|
||||
LangOptions LangOpts;
|
||||
ASTContext* Context;
|
||||
std::vector<Decl*> TopLevelDecls;
|
||||
|
||||
// The default ctor is only invoked during deserialization.
|
||||
explicit TranslationUnit() : SourceFile(NULL), Context(NULL) {}
|
||||
explicit TranslationUnit() : Context(NULL) {}
|
||||
|
||||
public:
|
||||
explicit TranslationUnit(const LangOptions& lopt)
|
||||
: LangOpts(lopt), Context(NULL) {}
|
||||
explicit TranslationUnit(const std::string& sourcefile,
|
||||
const LangOptions& lopt)
|
||||
: SourceFile(sourcefile), LangOpts(lopt), Context(NULL) {}
|
||||
|
||||
|
||||
explicit TranslationUnit(const LangOptions& lopt, ASTContext& context)
|
||||
: LangOpts(lopt), Context(&context) {}
|
||||
|
||||
void setContext(ASTContext* context) { Context = context; }
|
||||
ASTContext* getContext() const { return Context; }
|
||||
const LangOptions& getLangOpts() const { return LangOpts; }
|
||||
const std::string& getSourceFile() const { return SourceFile; }
|
||||
|
||||
/// Emit - Emit the translation unit to an arbitray bitcode stream.
|
||||
void Emit(llvm::Serializer& S) const;
|
||||
|
|
Загрузка…
Ссылка в новой задаче