diff options
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 136 |
1 files changed, 130 insertions, 6 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 716abde892..94be24ad2c 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1653,6 +1653,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { // Create and write out the blob that contains selectors and the method pool. { OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator; + ASTMethodPoolTrait Trait(*this); // Create the on-disk hash table representation. We walk through every // selector we've seen and look it up in the method pool. @@ -1692,7 +1693,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { // A new method pool entry. ++NumTableEntries; } - Generator.insert(S, Data); + Generator.insert(S, Data, Trait); } // Create the on-disk hash table in a buffer. @@ -1877,6 +1878,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { // strings. { OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; + ASTIdentifierTableTrait Trait(*this, PP); // Look for any identifiers that were named while processing the // headers, but are otherwise not needed. We add these to the hash @@ -1896,7 +1898,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { ID != IDEnd; ++ID) { assert(ID->first && "NULL identifier in identifier table"); if (!Chain || !ID->first->isFromAST()) - Generator.insert(ID->first, ID->second); + Generator.insert(ID->first, ID->second, Trait); } // Create the on-disk hash table in a buffer. @@ -1940,6 +1942,127 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { } //===----------------------------------------------------------------------===// +// DeclContext's Name Lookup Table Serialization +//===----------------------------------------------------------------------===// + +namespace { +// Trait used for the on-disk hash table used in the method pool. +class ASTDeclContextNameLookupTrait { + ASTWriter &Writer; + +public: + typedef DeclarationName key_type; + typedef key_type key_type_ref; + + typedef DeclContext::lookup_result data_type; + typedef const data_type& data_type_ref; + + explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { } + + unsigned ComputeHash(DeclarationName Name) { + llvm::FoldingSetNodeID ID; + ID.AddInteger(Name.getNameKind()); + + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + ID.AddString(Name.getAsIdentifierInfo()->getName()); + break; + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + ID.AddInteger(serialization::ComputeHash(Name.getObjCSelector())); + break; + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + ID.AddInteger(Writer.GetOrCreateTypeID(Name.getCXXNameType())); + break; + case DeclarationName::CXXOperatorName: + ID.AddInteger(Name.getCXXOverloadedOperator()); + break; + case DeclarationName::CXXLiteralOperatorName: + ID.AddString(Name.getCXXLiteralIdentifier()->getName()); + case DeclarationName::CXXUsingDirective: + break; + } + + return ID.ComputeHash(); + } + + std::pair<unsigned,unsigned> + EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name, + data_type_ref Lookup) { + unsigned KeyLen = 1; + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + case DeclarationName::CXXLiteralOperatorName: + KeyLen += 4; + break; + case DeclarationName::CXXOperatorName: + KeyLen += 1; + break; + case DeclarationName::CXXUsingDirective: + break; + } + clang::io::Emit16(Out, KeyLen); + + // 2 bytes for num of decls and 4 for each DeclID. + unsigned DataLen = 2 + 4 * (Lookup.second - Lookup.first); + clang::io::Emit16(Out, DataLen); + + return std::make_pair(KeyLen, DataLen); + } + + void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) { + using namespace clang::io; + + assert(Name.getNameKind() < 0x100 && "Invalid name kind ?"); + Emit8(Out, Name.getNameKind()); + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo())); + break; + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector())); + break; + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + Emit32(Out, Writer.getTypeID(Name.getCXXNameType())); + break; + case DeclarationName::CXXOperatorName: + assert(Name.getCXXOverloadedOperator() < 0x100 && "Invalid operator ?"); + Emit8(Out, Name.getCXXOverloadedOperator()); + break; + case DeclarationName::CXXLiteralOperatorName: + Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier())); + break; + case DeclarationName::CXXUsingDirective: + break; + } + } + + void EmitData(llvm::raw_ostream& Out, key_type_ref, + data_type Lookup, unsigned DataLen) { + uint64_t Start = Out.tell(); (void)Start; + clang::io::Emit16(Out, Lookup.second - Lookup.first); + for (; Lookup.first != Lookup.second; ++Lookup.first) + clang::io::Emit32(Out, Writer.GetDeclRef(*Lookup.first)); + + assert(Out.tell() - Start == DataLen && "Data length is wrong"); + } +}; +} // end anonymous namespace + +//===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// @@ -2587,7 +2710,7 @@ TypeID ASTWriter::GetOrCreateTypeID(QualType T) { std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); } -TypeID ASTWriter::getTypeID(QualType T) { +TypeID ASTWriter::getTypeID(QualType T) const { return MakeTypeID(T, std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); } @@ -2607,13 +2730,14 @@ TypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) { return Idx; } -TypeIdx ASTWriter::getTypeIdx(QualType T) { +TypeIdx ASTWriter::getTypeIdx(QualType T) const { if (T.isNull()) return TypeIdx(); assert(!T.getLocalFastQualifiers()); - assert(TypeIdxs.find(T) != TypeIdxs.end() && "Type not emitted!"); - return TypeIdxs[T]; + TypeIdxMap::const_iterator I = TypeIdxs.find(T); + assert(I != TypeIdxs.end() && "Type not emitted!"); + return I->second; } void ASTWriter::AddDeclRef(const Decl *D, RecordData &Record) { |