From: Argyrios Kyrtzidis Date: Fri, 2 Jul 2010 11:55:11 +0000 (+0000) Subject: - Allow a typedef type to be read from PCH even if its decl is currently initializing. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9763e221e16026ddf487d2564ed349d2c874a1a1;p=clang - Allow a typedef type to be read from PCH even if its decl is currently initializing. - Fix creation of TemplateSpecializationType. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107471 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 3ccdede8e6..b3545e8192 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -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()); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0be1778260..604cf2b5cf 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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 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 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, diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index be763d51ca..330cd9a5c6 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2116,12 +2116,15 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return Context->getTypeDeclType( cast(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(GetDecl(Record[0]))); + TypedefDecl *Decl = cast(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 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 diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 41815314d7..f91f76c1b4 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -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; }