diff options
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 206 |
1 files changed, 135 insertions, 71 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index f1bd1b67d21e..7836b3f827ce 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -25,7 +25,7 @@ using namespace clang; TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, - Decl **Params, unsigned NumParams, + NamedDecl **Params, unsigned NumParams, SourceLocation RAngleLoc) : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), NumParams(NumParams) { @@ -35,31 +35,32 @@ TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, TemplateParameterList * TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc, - SourceLocation LAngleLoc, Decl **Params, + SourceLocation LAngleLoc, NamedDecl **Params, unsigned NumParams, SourceLocation RAngleLoc) { - unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams; + unsigned Size = sizeof(TemplateParameterList) + + sizeof(NamedDecl *) * NumParams; unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment; void *Mem = C.Allocate(Size, Align); - return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, + return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, NumParams, RAngleLoc); } unsigned TemplateParameterList::getMinRequiredArguments() const { unsigned NumRequiredArgs = size(); - iterator Param = const_cast<TemplateParameterList *>(this)->end(), + iterator Param = const_cast<TemplateParameterList *>(this)->end(), ParamBegin = const_cast<TemplateParameterList *>(this)->begin(); while (Param != ParamBegin) { --Param; - + if (!(*Param)->isTemplateParameterPack() && - !(isa<TemplateTypeParmDecl>(*Param) && + !(isa<TemplateTypeParmDecl>(*Param) && cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) && !(isa<NonTypeTemplateParmDecl>(*Param) && cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) && !(isa<TemplateTemplateParmDecl>(*Param) && cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument())) break; - + --NumRequiredArgs; } @@ -94,16 +95,23 @@ void FunctionTemplateDecl::Destroy(ASTContext &C) { Spec != SpecEnd; ++Spec) C.Deallocate(&*Spec); } - + Decl::Destroy(C); } +FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() { + FunctionTemplateDecl *FunTmpl = this; + while (FunTmpl->getPreviousDeclaration()) + FunTmpl = FunTmpl->getPreviousDeclaration(); + return FunTmpl; +} + FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() { // Find the first declaration of this function template. FunctionTemplateDecl *First = this; while (First->getPreviousDeclaration()) First = First->getPreviousDeclaration(); - + if (First->CommonOrPrev.isNull()) { // FIXME: Allocate with the ASTContext First->CommonOrPrev = new Common; @@ -115,6 +123,13 @@ FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() { // ClassTemplateDecl Implementation //===----------------------------------------------------------------------===// +ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() { + ClassTemplateDecl *Template = this; + while (Template->getPreviousDeclaration()) + Template = Template->getPreviousDeclaration(); + return Template; +} + ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -128,7 +143,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, else CommonPtr = new (C) Common; - return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, + return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl, CommonPtr); } @@ -147,6 +162,21 @@ void ClassTemplateDecl::Destroy(ASTContext& C) { C.Deallocate((void*)this); } +ClassTemplatePartialSpecializationDecl * +ClassTemplateDecl::findPartialSpecialization(QualType T) { + ASTContext &Context = getASTContext(); + typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator + partial_spec_iterator; + for (partial_spec_iterator P = getPartialSpecializations().begin(), + PEnd = getPartialSpecializations().end(); + P != PEnd; ++P) { + if (Context.hasSameType(Context.getTypeDeclType(&*P), T)) + return &*P; + } + + return 0; +} + QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { if (!CommonPtr->InjectedClassNameType.isNull()) return CommonPtr->InjectedClassNameType; @@ -157,52 +187,32 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { // better to fix that redundancy. TemplateParameterList *Params = getTemplateParameters(); - llvm::SmallVector<TemplateArgument, 16> TemplateArgs; - llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs; TemplateArgs.reserve(Params->size()); - CanonTemplateArgs.reserve(Params->size()); - - for (TemplateParameterList::iterator - Param = Params->begin(), ParamEnd = Params->end(); + for (TemplateParameterList::iterator Param = Params->begin(), + ParamEnd = Params->end(); Param != ParamEnd; ++Param) { if (isa<TemplateTypeParmDecl>(*Param)) { QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); - TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(), + TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(), ParamType)); - CanonTemplateArgs.push_back( - TemplateArgument((*Param)->getLocation(), - Context.getCanonicalType(ParamType))); - } else if (NonTypeTemplateParmDecl *NTTP = + } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { - // FIXME: Build canonical expression, too! Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), NTTP->getLocation(), NTTP->getType()->isDependentType(), /*Value-dependent=*/true); TemplateArgs.push_back(TemplateArgument(E)); - CanonTemplateArgs.push_back(TemplateArgument(E)); - } else { + } else { TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP)); - CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(), - Context.getCanonicalDecl(TTP))); } } - // FIXME: I should really move the "build-the-canonical-type" logic - // into ASTContext::getTemplateSpecializationType. - TemplateName Name = TemplateName(this); - QualType CanonType = Context.getTemplateSpecializationType( - Context.getCanonicalTemplateName(Name), - &CanonTemplateArgs[0], - CanonTemplateArgs.size()); - CommonPtr->InjectedClassNameType - = Context.getTemplateSpecializationType(Name, + = Context.getTemplateSpecializationType(TemplateName(this), &TemplateArgs[0], - TemplateArgs.size(), - CanonType); + TemplateArgs.size()); return CommonPtr->InjectedClassNameType; } @@ -227,14 +237,13 @@ NonTypeTemplateParmDecl * NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, - SourceLocation TypeSpecStartLoc) { - return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, - TypeSpecStartLoc); + DeclaratorInfo *DInfo) { + return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, DInfo); } SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { return DefaultArgument? DefaultArgument->getSourceRange().getBegin() - : SourceLocation(); + : SourceLocation(); } //===----------------------------------------------------------------------===// @@ -251,7 +260,7 @@ TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { return DefaultArgument? DefaultArgument->getSourceRange().getBegin() - : SourceLocation(); + : SourceLocation(); } //===----------------------------------------------------------------------===// @@ -264,10 +273,10 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) { } /// \brief Construct a template argument pack. -void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, +void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, bool CopyArgs) { assert(isNull() && "Must call setArgumentPack on a null argument"); - + Kind = Pack; Args.NumArgs = NumArgs; Args.CopyArgs = CopyArgs; @@ -275,7 +284,8 @@ void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, Args.Args = args; return; } - + + // FIXME: Allocate in ASTContext Args.Args = new TemplateArgument[NumArgs]; for (unsigned I = 0; I != Args.NumArgs; ++I) Args.Args[I] = args[I]; @@ -292,21 +302,21 @@ void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) { assert(Arg.getAsType()->isCanonical() && "Type must be canonical!"); break; } - + assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!"); - assert(!StructuredArgs && + assert(!StructuredArgs && "Can't append arguments when an argument pack has been added!"); - + if (!FlatArgs) FlatArgs = new TemplateArgument[MaxFlatArgs]; - + FlatArgs[NumFlatArgs++] = Arg; } void TemplateArgumentListBuilder::BeginPack() { assert(!AddingToPack && "Already adding to pack!"); assert(!StructuredArgs && "Argument list already contains a pack!"); - + AddingToPack = true; PackBeginIndex = NumFlatArgs; } @@ -314,24 +324,24 @@ void TemplateArgumentListBuilder::BeginPack() { void TemplateArgumentListBuilder::EndPack() { assert(AddingToPack && "Not adding to pack!"); assert(!StructuredArgs && "Argument list already contains a pack!"); - + AddingToPack = false; StructuredArgs = new TemplateArgument[MaxStructuredArgs]; - + // First copy the flat entries over to the list (if any) for (unsigned I = 0; I != PackBeginIndex; ++I) { NumStructuredArgs++; StructuredArgs[I] = FlatArgs[I]; } - + // Next, set the pack. TemplateArgument *PackArgs = 0; unsigned NumPackArgs = NumFlatArgs - PackBeginIndex; if (NumPackArgs) PackArgs = &FlatArgs[PackBeginIndex]; - - StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, + + StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs, /*CopyArgs=*/false); } @@ -350,19 +360,25 @@ void TemplateArgumentListBuilder::ReleaseArgs() { TemplateArgumentList::TemplateArgumentList(ASTContext &Context, TemplateArgumentListBuilder &Builder, bool TakeArgs) - : FlatArguments(Builder.getFlatArguments(), TakeArgs), - NumFlatArguments(Builder.flatSize()), + : FlatArguments(Builder.getFlatArguments(), TakeArgs), + NumFlatArguments(Builder.flatSize()), StructuredArguments(Builder.getStructuredArguments(), TakeArgs), NumStructuredArguments(Builder.structuredSize()) { - + if (!TakeArgs) return; - + if (Builder.getStructuredArguments() == Builder.getFlatArguments()) StructuredArguments.setInt(0); Builder.ReleaseArgs(); } +TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other) + : FlatArguments(Other.FlatArguments.getPointer(), 1), + NumFlatArguments(Other.flat_size()), + StructuredArguments(Other.StructuredArguments.getPointer(), 1), + NumStructuredArguments(Other.NumStructuredArguments) { } + TemplateArgumentList::~TemplateArgumentList() { // FIXME: Deallocate template arguments } @@ -374,34 +390,66 @@ ClassTemplateSpecializationDecl:: ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, - TemplateArgumentListBuilder &Builder) - : CXXRecordDecl(DK, - SpecializedTemplate->getTemplatedDecl()->getTagKind(), + TemplateArgumentListBuilder &Builder, + ClassTemplateSpecializationDecl *PrevDecl) + : CXXRecordDecl(DK, + SpecializedTemplate->getTemplatedDecl()->getTagKind(), DC, L, // FIXME: Should we use DeclarationName for the name of // class template specializations? - SpecializedTemplate->getIdentifier()), + SpecializedTemplate->getIdentifier(), + PrevDecl), SpecializedTemplate(SpecializedTemplate), TemplateArgs(Context, Builder, /*TakeArgs=*/true), SpecializationKind(TSK_Undeclared) { } - + ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::Create(ASTContext &Context, +ClassTemplateSpecializationDecl::Create(ASTContext &Context, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, ClassTemplateSpecializationDecl *PrevDecl) { ClassTemplateSpecializationDecl *Result - = new (Context)ClassTemplateSpecializationDecl(Context, + = new (Context)ClassTemplateSpecializationDecl(Context, ClassTemplateSpecialization, - DC, L, + DC, L, SpecializedTemplate, - Builder); + Builder, + PrevDecl); Context.getTypeDeclType(Result, PrevDecl); return Result; } +void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) { + if (SpecializedPartialSpecialization *PartialSpec + = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) + C.Deallocate(PartialSpec); + + CXXRecordDecl::Destroy(C); +} + +void +ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, + const PrintingPolicy &Policy, + bool Qualified) const { + NamedDecl::getNameForDiagnostic(S, Policy, Qualified); + + const TemplateArgumentList &TemplateArgs = getTemplateArgs(); + S += TemplateSpecializationType::PrintTemplateArgumentList( + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size(), + Policy); +} + +ClassTemplateDecl * +ClassTemplateSpecializationDecl::getSpecializedTemplate() const { + if (SpecializedPartialSpecialization *PartialSpec + = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) + return PartialSpec->PartialSpecialization->getSpecializedTemplate(); + return SpecializedTemplate.get<ClassTemplateDecl*>(); +} + //===----------------------------------------------------------------------===// // ClassTemplatePartialSpecializationDecl Implementation //===----------------------------------------------------------------------===// @@ -413,11 +461,27 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L, TemplateArgumentListBuilder &Builder, ClassTemplatePartialSpecializationDecl *PrevDecl) { ClassTemplatePartialSpecializationDecl *Result - = new (Context)ClassTemplatePartialSpecializationDecl(Context, + = new (Context)ClassTemplatePartialSpecializationDecl(Context, DC, L, Params, SpecializedTemplate, - Builder); + Builder, PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); Context.getTypeDeclType(Result, PrevDecl); return Result; } + +//===----------------------------------------------------------------------===// +// FriendTemplateDecl Implementation +//===----------------------------------------------------------------------===// + +FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, + DeclContext *DC, + SourceLocation L, + unsigned NParams, + TemplateParameterList **Params, + FriendUnion Friend, + SourceLocation FLoc) { + FriendTemplateDecl *Result + = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); + return Result; +} |