- Allow a typedef type to be read from PCH even if its decl is currently initializing.

- Fix creation of TemplateSpecializationType.

llvm-svn: 107471
This commit is contained in:
Argyrios Kyrtzidis 2010-07-02 11:55:11 +00:00
parent e3029a7e7b
commit 45a83f9acc
4 changed files with 66 additions and 45 deletions

View File

@ -614,7 +614,7 @@ public:
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
QualType getTypedefType(const TypedefDecl *Decl);
QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType());
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST);
@ -630,6 +630,10 @@ public:
unsigned NumArgs,
QualType Canon = QualType());
QualType getCanonicalTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
unsigned NumArgs);
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgumentListInfo &Args,
QualType Canon = QualType());

View File

@ -1787,10 +1787,12 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) {
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
QualType ASTContext::getTypedefType(const TypedefDecl *Decl) {
QualType
ASTContext::getTypedefType(const TypedefDecl *Decl, QualType Canonical) {
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
if (Canonical.isNull())
Canonical = getCanonicalType(Decl->getUnderlyingType());
Decl->TypeForDecl = new(*this, TypeAlignment)
TypedefType(Type::Typedef, Decl, Canonical);
Types.push_back(Decl->TypeForDecl);
@ -1894,41 +1896,8 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
QualType Canon) {
if (!Canon.isNull())
Canon = getCanonicalType(Canon);
else {
// Build the canonical template specialization type.
TemplateName CanonTemplate = getCanonicalTemplateName(Template);
llvm::SmallVector<TemplateArgument, 4> CanonArgs;
CanonArgs.reserve(NumArgs);
for (unsigned I = 0; I != NumArgs; ++I)
CanonArgs.push_back(getCanonicalTemplateArgument(Args[I]));
// Determine whether this canonical template specialization type already
// exists.
llvm::FoldingSetNodeID ID;
TemplateSpecializationType::Profile(ID, CanonTemplate,
CanonArgs.data(), NumArgs, *this);
void *InsertPos = 0;
TemplateSpecializationType *Spec
= TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
if (!Spec) {
// Allocate a new canonical template specialization type.
void *Mem = Allocate((sizeof(TemplateSpecializationType) +
sizeof(TemplateArgument) * NumArgs),
TypeAlignment);
Spec = new (Mem) TemplateSpecializationType(CanonTemplate,
CanonArgs.data(), NumArgs,
Canon);
Types.push_back(Spec);
TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
}
if (Canon.isNull())
Canon = QualType(Spec, 0);
assert(Canon->isDependentType() &&
"Non-dependent template-id type must have a canonical type");
}
else
Canon = getCanonicalTemplateSpecializationType(Template, Args, NumArgs);
// Allocate the (non-canonical) template specialization type, but don't
// try to unique it: these types typically have location information that
@ -1945,6 +1914,44 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
return QualType(Spec, 0);
}
QualType
ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template,
const TemplateArgument *Args,
unsigned NumArgs) {
// Build the canonical template specialization type.
TemplateName CanonTemplate = getCanonicalTemplateName(Template);
llvm::SmallVector<TemplateArgument, 4> CanonArgs;
CanonArgs.reserve(NumArgs);
for (unsigned I = 0; I != NumArgs; ++I)
CanonArgs.push_back(getCanonicalTemplateArgument(Args[I]));
// Determine whether this canonical template specialization type already
// exists.
llvm::FoldingSetNodeID ID;
TemplateSpecializationType::Profile(ID, CanonTemplate,
CanonArgs.data(), NumArgs, *this);
void *InsertPos = 0;
TemplateSpecializationType *Spec
= TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
if (!Spec) {
// Allocate a new canonical template specialization type.
void *Mem = Allocate((sizeof(TemplateSpecializationType) +
sizeof(TemplateArgument) * NumArgs),
TypeAlignment);
Spec = new (Mem) TemplateSpecializationType(CanonTemplate,
CanonArgs.data(), NumArgs,
QualType());
Types.push_back(Spec);
TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
}
assert(Spec->isDependentType() &&
"Non-dependent template-id type must have a canonical type");
return QualType(Spec, 0);
}
QualType
ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,

View File

@ -2116,12 +2116,15 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
return Context->getTypeDeclType(
cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
case pch::TYPE_TYPEDEF:
if (Record.size() != 1) {
case pch::TYPE_TYPEDEF: {
if (Record.size() != 2) {
Error("incorrect encoding of typedef type");
return QualType();
}
return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
TypedefDecl *Decl = cast<TypedefDecl>(GetDecl(Record[0]));
QualType Canonical = GetType(Record[1]);
return Context->getTypedefType(Decl, Canonical);
}
case pch::TYPE_TYPEOF_EXPR:
return Context->getTypeOfExprType(ReadExpr());
@ -2251,8 +2254,12 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
llvm::SmallVector<TemplateArgument, 8> Args;
ReadTemplateArgumentList(Args, Record, Idx);
QualType Canon = GetType(Record[Idx++]);
return Context->getTemplateSpecializationType(Name, Args.data(),Args.size(),
Canon);
if (Canon.isNull())
return Context->getCanonicalTemplateSpecializationType(Name, Args.data(),
Args.size());
else
return Context->getTemplateSpecializationType(Name, Args.data(),
Args.size(), Canon);
}
}
// Suppress a GCC warning

View File

@ -173,6 +173,8 @@ void PCHTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
void PCHTypeWriter::VisitTypedefType(const TypedefType *T) {
Writer.AddDeclRef(T->getDecl(), Record);
assert(!T->isCanonicalUnqualified() && "Invalid typedef ?");
Writer.AddTypeRef(T->getCanonicalTypeInternal(), Record);
Code = pch::TYPE_TYPEDEF;
}
@ -223,8 +225,9 @@ PCHTypeWriter::VisitTemplateSpecializationType(
for (TemplateSpecializationType::iterator ArgI = T->begin(), ArgE = T->end();
ArgI != ArgE; ++ArgI)
Writer.AddTemplateArgument(*ArgI, Record);
QualType Canon = T->getCanonicalTypeInternal();
Writer.AddTypeRef(Canon.getTypePtr() != T ? Canon : QualType(), Record);
Writer.AddTypeRef(T->isCanonicalUnqualified() ? QualType()
: T->getCanonicalTypeInternal(),
Record);
Code = pch::TYPE_TEMPLATE_SPECIALIZATION;
}