diff options
author | John McCall <rjmccall@apple.com> | 2010-03-10 03:28:59 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-10 03:28:59 +0000 |
commit | 3cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4 (patch) | |
tree | 84f7dae6f0d5da51df0529ca91ff0c7fdf3f152e /lib/AST/ASTContext.cpp | |
parent | d7fdae5ea0158f91f0683044bb3a7dee0426bfe0 (diff) |
Create a new InjectedClassNameType to represent bare-word references to the
injected class name of a class template or class template partial specialization.
This is a non-canonical type; the canonical type is still a template
specialization type. This becomes the TypeForDecl of the pattern declaration,
which cleans up some amount of code (and complicates some other parts, but
whatever).
Fixes PR6326 and probably a few others, primarily by re-establishing a few
invariants about TypeLoc sizes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98134 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index e2c80a6da5..f134bfdf1f 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -888,6 +888,10 @@ ASTContext::getTypeInfo(const Type *T) { case Type::QualifiedName: return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr()); + case Type::InjectedClassName: + return getTypeInfo(cast<InjectedClassNameType>(T) + ->getUnderlyingType().getTypePtr()); + case Type::TemplateSpecialization: assert(getCanonicalType(T) != T && "Cannot request the size of a dependent type"); @@ -1918,6 +1922,39 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, return QualType(FTP, 0); } +#ifndef NDEBUG +static bool NeedsInjectedClassNameType(const RecordDecl *D) { + if (!isa<CXXRecordDecl>(D)) return false; + const CXXRecordDecl *RD = cast<CXXRecordDecl>(D); + if (isa<ClassTemplatePartialSpecializationDecl>(RD)) + return true; + if (RD->getDescribedClassTemplate() && + !isa<ClassTemplateSpecializationDecl>(RD)) + return true; + return false; +} +#endif + +/// getInjectedClassNameType - Return the unique reference to the +/// injected class name type for the specified templated declaration. +QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl, + QualType TST) { + assert(NeedsInjectedClassNameType(Decl)); + if (Decl->TypeForDecl) { + assert(isa<InjectedClassNameType>(Decl->TypeForDecl)); + } else if (CXXRecordDecl *PrevDecl + = cast_or_null<CXXRecordDecl>(Decl->getPreviousDeclaration())) { + assert(PrevDecl->TypeForDecl && "previous declaration has no type"); + Decl->TypeForDecl = PrevDecl->TypeForDecl; + assert(isa<InjectedClassNameType>(Decl->TypeForDecl)); + } else { + Decl->TypeForDecl = new (*this, TypeAlignment) + InjectedClassNameType(Decl, TST, TST->getCanonicalTypeInternal()); + Types.push_back(Decl->TypeForDecl); + } + return QualType(Decl->TypeForDecl, 0); +} + /// getTypeDeclType - Return the unique reference to the type for the /// specified type declaration. QualType ASTContext::getTypeDeclType(const TypeDecl *Decl, @@ -1936,8 +1973,10 @@ QualType ASTContext::getTypeDeclType(const TypeDecl *Decl, if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) { if (PrevDecl) Decl->TypeForDecl = PrevDecl->TypeForDecl; - else + else { + assert(!NeedsInjectedClassNameType(Record)); Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record); + } } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) { if (PrevDecl) Decl->TypeForDecl = PrevDecl->TypeForDecl; @@ -2022,6 +2061,24 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, return QualType(TypeParm, 0); } +TypeSourceInfo * +ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name, + SourceLocation NameLoc, + const TemplateArgumentListInfo &Args, + QualType CanonType) { + QualType TST = getTemplateSpecializationType(Name, Args, CanonType); + + TypeSourceInfo *DI = CreateTypeSourceInfo(TST); + TemplateSpecializationTypeLoc TL + = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc()); + TL.setTemplateNameLoc(NameLoc); + TL.setLAngleLoc(Args.getLAngleLoc()); + TL.setRAngleLoc(Args.getRAngleLoc()); + for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) + TL.setArgLocInfo(i, Args[i].getLocInfo()); + return DI; +} + QualType ASTContext::getTemplateSpecializationType(TemplateName Template, const TemplateArgumentListInfo &Args, |