diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index fb7da7713de5..0abe65747592 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -422,8 +422,10 @@ namespace clang { TYPE_TEMPLATE_TYPE_PARM = 29, /// \brief An TemplateSpecializationType record. TYPE_TEMPLATE_SPECIALIZATION = 30, - /// \brief An DependentNameType record. - TYPE_DEPENDENT_NAME = 31 + /// \brief A DependentNameType record. + TYPE_DEPENDENT_NAME = 31, + /// \brief A DependentTemplateSpecializationType record. + TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32 }; /// \brief The type IDs for special types constructed by semantic diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 498e804cc699..5bd3c0481a0e 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -2160,15 +2160,11 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return Context->getTypeDeclType(cast(GetDecl(Record[0]))); case pch::TYPE_ELABORATED: { - if (Record.size() != 2) { - Error("incorrect encoding of elaborated type"); - return QualType(); - } - unsigned Tag = Record[1]; - // FIXME: Deserialize the qualifier (C++ only) - return Context->getElaboratedType((ElaboratedTypeKeyword) Tag, - /* NNS */ 0, - GetType(Record[0])); + unsigned Idx = 0; + ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++]; + NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); + QualType NamedType = GetType(Record[Idx++]); + return Context->getElaboratedType(Keyword, NNS, NamedType); } case pch::TYPE_OBJC_INTERFACE: { @@ -2224,6 +2220,20 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx); return Context->getDependentNameType(Keyword, NNS, Name, QualType()); } + + case pch::TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: { + unsigned Idx = 0; + ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++]; + NestedNameSpecifier *NNS = ReadNestedNameSpecifier(Record, Idx); + const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx); + unsigned NumArgs = Record[Idx++]; + llvm::SmallVector Args; + Args.reserve(NumArgs); + while (NumArgs--) + Args.push_back(ReadTemplateArgument(Record, Idx)); + return Context->getDependentTemplateSpecializationType(Keyword, NNS, Name, + Args.size(), Args.data()); + } case pch::TYPE_TEMPLATE_SPECIALIZATION: { unsigned Idx = 0; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 21ea5fcdc829..3c42d474dc08 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -261,15 +261,20 @@ PCHTypeWriter::VisitDependentNameType(const DependentNameType *T) { void PCHTypeWriter::VisitDependentTemplateSpecializationType( const DependentTemplateSpecializationType *T) { - // FIXME: Serialize this type (C++ only) - assert(false && "Cannot serialize dependent template specialization types"); + Record.push_back(T->getKeyword()); + Writer.AddNestedNameSpecifier(T->getQualifier(), Record); + Writer.AddIdentifierRef(T->getIdentifier(), Record); + Record.push_back(T->getNumArgs()); + for (DependentTemplateSpecializationType::iterator + I = T->begin(), E = T->end(); I != E; ++I) + Writer.AddTemplateArgument(*I, Record); + Code = pch::TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION; } void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) { - Writer.AddTypeRef(T->getNamedType(), Record); Record.push_back(T->getKeyword()); - // FIXME: Serialize the qualifier (C++ only) - assert(T->getQualifier() == 0 && "Cannot serialize qualified name types"); + Writer.AddNestedNameSpecifier(T->getQualifier(), Record); + Writer.AddTypeRef(T->getNamedType(), Record); Code = pch::TYPE_ELABORATED; }