Implemented serialization of SelectorTable and Selectors.
Modified serialization of IdentifierTable to self-register itself with the Deserializer. llvm-svn: 44471
This commit is contained in:
parent
8ded669b04
commit
c9bcda94ae
|
|
@ -258,6 +258,8 @@ unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
|
||||||
/// this class is provided strictly through Selector.
|
/// this class is provided strictly through Selector.
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class MultiKeywordSelector : public llvm::FoldingSetNode {
|
class MultiKeywordSelector : public llvm::FoldingSetNode {
|
||||||
|
friend SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer&);
|
||||||
|
MultiKeywordSelector(unsigned nKeys) : NumArgs(nKeys) {}
|
||||||
public:
|
public:
|
||||||
unsigned NumArgs;
|
unsigned NumArgs;
|
||||||
|
|
||||||
|
|
@ -265,11 +267,13 @@ public:
|
||||||
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
|
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
|
||||||
assert((nKeys > 1) && "not a multi-keyword selector");
|
assert((nKeys > 1) && "not a multi-keyword selector");
|
||||||
NumArgs = nKeys;
|
NumArgs = nKeys;
|
||||||
|
|
||||||
// Fill in the trailing keyword array.
|
// Fill in the trailing keyword array.
|
||||||
IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
|
IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
|
||||||
for (unsigned i = 0; i != nKeys; ++i)
|
for (unsigned i = 0; i != nKeys; ++i)
|
||||||
KeyInfo[i] = IIV[i];
|
KeyInfo[i] = IIV[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// getName - Derive the full selector name and return it.
|
// getName - Derive the full selector name and return it.
|
||||||
std::string getName() const;
|
std::string getName() const;
|
||||||
|
|
||||||
|
|
@ -422,6 +426,8 @@ void IdentifierInfo::Read(llvm::Deserializer& D) {
|
||||||
void IdentifierTable::Emit(llvm::Serializer& S) const {
|
void IdentifierTable::Emit(llvm::Serializer& S) const {
|
||||||
S.EnterBlock();
|
S.EnterBlock();
|
||||||
|
|
||||||
|
S.EmitPtr(this);
|
||||||
|
|
||||||
for (iterator I=begin(), E=end(); I != E; ++I) {
|
for (iterator I=begin(), E=end(); I != E; ++I) {
|
||||||
const char* Key = I->getKeyData();
|
const char* Key = I->getKeyData();
|
||||||
const IdentifierInfo* Info = &I->getValue();
|
const IdentifierInfo* Info = &I->getValue();
|
||||||
|
|
@ -443,13 +449,14 @@ void IdentifierTable::Emit(llvm::Serializer& S) const {
|
||||||
S.ExitBlock();
|
S.ExitBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifierTable* IdentifierTable::Create(llvm::Deserializer& D) {
|
IdentifierTable* IdentifierTable::CreateAndRegister(llvm::Deserializer& D) {
|
||||||
llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
|
llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
|
||||||
|
|
||||||
std::vector<char> buff;
|
std::vector<char> buff;
|
||||||
buff.reserve(200);
|
buff.reserve(200);
|
||||||
|
|
||||||
IdentifierTable* t = new IdentifierTable();
|
IdentifierTable* t = new IdentifierTable();
|
||||||
|
D.RegisterPtr(t);
|
||||||
|
|
||||||
while (!D.FinishedBlock(BLoc)) {
|
while (!D.FinishedBlock(BLoc)) {
|
||||||
llvm::SerializedPtrID InfoPtrID = D.ReadPtrID();
|
llvm::SerializedPtrID InfoPtrID = D.ReadPtrID();
|
||||||
|
|
@ -471,3 +478,71 @@ IdentifierTable* IdentifierTable::Create(llvm::Deserializer& D) {
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Serialization for Selector and SelectorTable.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
void Selector::Emit(llvm::Serializer& S) const {
|
||||||
|
S.EmitInt(getIdentifierInfoFlag());
|
||||||
|
S.EmitPtr(reinterpret_cast<void*>(InfoPtr & ~ArgFlags));
|
||||||
|
}
|
||||||
|
|
||||||
|
Selector Selector::ReadVal(llvm::Deserializer& D) {
|
||||||
|
unsigned flag = D.ReadInt();
|
||||||
|
|
||||||
|
uintptr_t ptr;
|
||||||
|
D.ReadUIntPtr(ptr,false); // No backpatching.
|
||||||
|
|
||||||
|
return Selector(ptr | flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectorTable::Emit(llvm::Serializer& S) const {
|
||||||
|
typedef llvm::FoldingSet<MultiKeywordSelector>::iterator iterator;
|
||||||
|
llvm::FoldingSet<MultiKeywordSelector> *SelTab;
|
||||||
|
SelTab = static_cast<llvm::FoldingSet<MultiKeywordSelector> *>(Impl);
|
||||||
|
|
||||||
|
S.EnterBlock();
|
||||||
|
|
||||||
|
S.EmitPtr(this);
|
||||||
|
|
||||||
|
for (iterator I=SelTab->begin(), E=SelTab->end(); I != E; ++I) {
|
||||||
|
S.FlushRecord(); // Start a new record.
|
||||||
|
S.EmitInt(I->getNumArgs());
|
||||||
|
|
||||||
|
for (MultiKeywordSelector::keyword_iterator KI = I->keyword_begin(),
|
||||||
|
KE = I->keyword_end(); KI != KE; ++KI)
|
||||||
|
S.EmitPtr(*KI);
|
||||||
|
}
|
||||||
|
|
||||||
|
S.ExitBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer& D) {
|
||||||
|
llvm::Deserializer::Location BLoc = D.getCurrentBlockLocation();
|
||||||
|
|
||||||
|
SelectorTable* t = new SelectorTable();
|
||||||
|
D.RegisterPtr(t);
|
||||||
|
|
||||||
|
llvm::FoldingSet<MultiKeywordSelector>& SelTab =
|
||||||
|
*static_cast<llvm::FoldingSet<MultiKeywordSelector>*>(t->Impl);
|
||||||
|
|
||||||
|
while (!D.FinishedBlock(BLoc)) {
|
||||||
|
unsigned nKeys = D.ReadInt();
|
||||||
|
|
||||||
|
MultiKeywordSelector *SI =
|
||||||
|
(MultiKeywordSelector*)malloc(sizeof(MultiKeywordSelector) +
|
||||||
|
nKeys*sizeof(IdentifierInfo *));
|
||||||
|
|
||||||
|
new (SI) MultiKeywordSelector(nKeys);
|
||||||
|
|
||||||
|
IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(SI+1);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i != nKeys; ++i)
|
||||||
|
D.ReadPtr(KeyInfo[i],false);
|
||||||
|
|
||||||
|
SelTab.GetOrInsertNode(SI);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,9 @@ class SerializationTest : public ASTConsumer {
|
||||||
ASTContext* Context;
|
ASTContext* Context;
|
||||||
std::list<Decl*> Decls;
|
std::list<Decl*> Decls;
|
||||||
|
|
||||||
enum { BasicMetadataBlock,
|
enum { BasicMetadataBlock = 1,
|
||||||
ASTContextBlock,
|
ASTContextBlock = 2,
|
||||||
DeclsBlock };
|
DeclsBlock = 3 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SerializationTest() : Context(NULL) {};
|
SerializationTest() : Context(NULL) {};
|
||||||
|
|
@ -163,6 +163,10 @@ void SerializationTest::Serialize(llvm::sys::Path& Filename,
|
||||||
|
|
||||||
Sezr.EnterBlock(BasicMetadataBlock);
|
Sezr.EnterBlock(BasicMetadataBlock);
|
||||||
|
|
||||||
|
// Block for SourceManager and Target. Allows easy skipping around
|
||||||
|
// to the Selectors during deserialization.
|
||||||
|
Sezr.EnterBlock();
|
||||||
|
|
||||||
// "Fake" emit the SourceManager.
|
// "Fake" emit the SourceManager.
|
||||||
llvm::cerr << "Faux-serializing: SourceManager.\n";
|
llvm::cerr << "Faux-serializing: SourceManager.\n";
|
||||||
Sezr.EmitPtr(&Context->SourceMgr);
|
Sezr.EmitPtr(&Context->SourceMgr);
|
||||||
|
|
@ -171,13 +175,15 @@ void SerializationTest::Serialize(llvm::sys::Path& Filename,
|
||||||
llvm::cerr << "Faux-serializing: Target.\n";
|
llvm::cerr << "Faux-serializing: Target.\n";
|
||||||
Sezr.EmitPtr(&Context->Target);
|
Sezr.EmitPtr(&Context->Target);
|
||||||
|
|
||||||
// "Fake" emit Selectors.
|
Sezr.ExitBlock();
|
||||||
llvm::cerr << "Faux-serializing: Selectors.\n";
|
|
||||||
Sezr.EmitPtr(&Context->Selectors);
|
// Emit the Selectors.
|
||||||
|
llvm::cerr << "Serializing: Selectors.\n";
|
||||||
|
Sezr.Emit(Context->Selectors);
|
||||||
|
|
||||||
// Emit the Identifier Table.
|
// Emit the Identifier Table.
|
||||||
llvm::cerr << "Serializing: IdentifierTable.\n";
|
llvm::cerr << "Serializing: IdentifierTable.\n";
|
||||||
Sezr.EmitOwnedPtr(&Context->Idents);
|
Sezr.Emit(Context->Idents);
|
||||||
|
|
||||||
Sezr.ExitBlock();
|
Sezr.ExitBlock();
|
||||||
|
|
||||||
|
|
@ -254,19 +260,23 @@ void SerializationTest::Deserialize(llvm::sys::Path& Filename,
|
||||||
llvm::cerr << "Faux-Deserializing: Target.\n";
|
llvm::cerr << "Faux-Deserializing: Target.\n";
|
||||||
Dezr.RegisterPtr(&Context->Target);
|
Dezr.RegisterPtr(&Context->Target);
|
||||||
|
|
||||||
// "Fake" read the Selectors.
|
// For Selectors, we must read the identifier table first because the
|
||||||
llvm::cerr << "Faux-Deserializing: Selectors.\n";
|
// SelectorTable depends on the identifiers being already deserialized.
|
||||||
Dezr.RegisterPtr(&Context->Selectors);
|
llvm::Deserializer::Location SelectorBlockLoc = Dezr.getCurrentBlockLocation();
|
||||||
|
Dezr.SkipBlock();
|
||||||
|
|
||||||
// Read the identifier table.
|
// Read the identifier table.
|
||||||
llvm::cerr << "Deserializing: IdentifierTable\n";
|
llvm::cerr << "Deserializing: IdentifierTable\n";
|
||||||
Dezr.ReadOwnedPtr<IdentifierTable>();
|
IdentifierTable::CreateAndRegister(Dezr);
|
||||||
|
|
||||||
|
// Now jump back and read the selectors.
|
||||||
|
llvm::cerr << "Deserializing: Selectors\n";
|
||||||
|
Dezr.JumpTo(SelectorBlockLoc);
|
||||||
|
SelectorTable::CreateAndRegister(Dezr);
|
||||||
|
|
||||||
// Now jump back to ASTContextBlock and read the ASTContext.
|
// Now jump back to ASTContextBlock and read the ASTContext.
|
||||||
Dezr.JumpTo(ASTContextBlockLoc);
|
|
||||||
|
|
||||||
// Read the ASTContext.
|
|
||||||
llvm::cerr << "Deserializing: ASTContext.\n";
|
llvm::cerr << "Deserializing: ASTContext.\n";
|
||||||
|
Dezr.JumpTo(ASTContextBlockLoc);
|
||||||
Dezr.ReadOwnedPtr<ASTContext>();
|
Dezr.ReadOwnedPtr<ASTContext>();
|
||||||
|
|
||||||
// "Rewind" the stream. Find the block with the serialized top-level decls.
|
// "Rewind" the stream. Find the block with the serialized top-level decls.
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ public:
|
||||||
void Emit(llvm::Serializer& S) const;
|
void Emit(llvm::Serializer& S) const;
|
||||||
|
|
||||||
/// Create - Deserialize an IdentifierTable from a bitstream.
|
/// Create - Deserialize an IdentifierTable from a bitstream.
|
||||||
static IdentifierTable* Create(llvm::Deserializer& D);
|
static IdentifierTable* CreateAndRegister(llvm::Deserializer& D);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// This ctor is not intended to be used by anyone except for object
|
/// This ctor is not intended to be used by anyone except for object
|
||||||
|
|
@ -227,7 +227,7 @@ class Selector {
|
||||||
InfoPtr = reinterpret_cast<uintptr_t>(SI);
|
InfoPtr = reinterpret_cast<uintptr_t>(SI);
|
||||||
assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
|
assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
|
||||||
}
|
}
|
||||||
Selector(intptr_t V) : InfoPtr(V) {}
|
Selector(uintptr_t V) : InfoPtr(V) {}
|
||||||
public:
|
public:
|
||||||
friend class SelectorTable; // only the SelectorTable can create these.
|
friend class SelectorTable; // only the SelectorTable can create these.
|
||||||
|
|
||||||
|
|
@ -269,6 +269,12 @@ public:
|
||||||
static Selector getTombstoneMarker() {
|
static Selector getTombstoneMarker() {
|
||||||
return Selector(uintptr_t(-2));
|
return Selector(uintptr_t(-2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit - Emit a selector to bitcode.
|
||||||
|
void Emit(llvm::Serializer& S) const;
|
||||||
|
|
||||||
|
// ReadVal - Read a selector from bitcode.
|
||||||
|
static Selector ReadVal(llvm::Deserializer& D);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// SelectorTable - This table allows us to fully hide how we implement
|
/// SelectorTable - This table allows us to fully hide how we implement
|
||||||
|
|
@ -292,6 +298,12 @@ public:
|
||||||
Selector getNullarySelector(IdentifierInfo *ID) {
|
Selector getNullarySelector(IdentifierInfo *ID) {
|
||||||
return Selector(ID, 0);
|
return Selector(ID, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit - Emit a SelectorTable to bitcode.
|
||||||
|
void Emit(llvm::Serializer& S) const;
|
||||||
|
|
||||||
|
// Create - Reconstitute a SelectorTable from bitcode.
|
||||||
|
static SelectorTable* CreateAndRegister(llvm::Deserializer& D);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue