AST reader support for having specializations of templates from earlier in the chain.

llvm-svn: 111985
This commit is contained in:
Sebastian Redl 2010-08-24 22:50:19 +00:00
parent b46e9bc26f
commit aba202b430
4 changed files with 36 additions and 1 deletions

View File

@ -316,7 +316,11 @@ namespace clang {
/// \brief Record code for an update to a decl context's lookup table.
///
/// In practice, this should only be used for the TU and namespaces.
UPDATE_VISIBLE = 34
UPDATE_VISIBLE = 34,
/// \brief Record code for template specializations introduced after
/// serializations of the original template decl.
ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35
};
/// \brief Record types used within a source manager block.

View File

@ -372,6 +372,16 @@ private:
/// most recent declarations in another AST file.
FirstLatestDeclIDMap FirstLatestDeclIDs;
typedef llvm::SmallVector<serialization::DeclID, 4>
AdditionalTemplateSpecializations;
typedef llvm::DenseMap<serialization::DeclID,
AdditionalTemplateSpecializations>
AdditionalTemplateSpecializationsMap;
/// \brief Additional specializations (including partial) of templates that
/// were introduced after the template was serialized.
AdditionalTemplateSpecializationsMap AdditionalTemplateSpecializationsPending;
/// \brief Read the records that describe the contents of declcontexts.
bool ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
const std::pair<uint64_t, uint64_t> &Offsets,

View File

@ -1972,6 +1972,13 @@ ASTReader::ReadASTBlock(PerFileData &F) {
std::make_pair(&F, Record[I+1]);
break;
}
case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: {
AdditionalTemplateSpecializations &ATS =
AdditionalTemplateSpecializationsPending[Record[0]];
ATS.insert(ATS.end(), Record.begin()+1, Record.end());
break;
}
}
First = false;
}

View File

@ -1424,6 +1424,20 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
}
}
}
// If this is a template, read additional specializations that may be in a
// different part of the chain.
if (isa<RedeclarableTemplateDecl>(D)) {
AdditionalTemplateSpecializationsMap::iterator F =
AdditionalTemplateSpecializationsPending.find(ID);
if (F != AdditionalTemplateSpecializationsPending.end()) {
for (AdditionalTemplateSpecializations::iterator I = F->second.begin(),
E = F->second.end();
I != E; ++I)
GetDecl(*I);
AdditionalTemplateSpecializationsPending.erase(F);
}
}
assert(Idx == Record.size());
// If we have deserialized a declaration that has a definition the