From: Argyrios Kyrtzidis Date: Tue, 22 Jun 2010 09:54:51 +0000 (+0000) Subject: Make it easier to read/write the template part of FunctionDecl. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0913557c800c8a712fb554032a833619f23bc56;p=clang Make it easier to read/write the template part of FunctionDecl. Introduce: -FunctionDecl::getTemplatedKind() which returns an enum signifying what kind of templated FunctionDecl it is. -An overload of FunctionDecl::setFunctionTemplateSpecialization() which accepts arrays of TemplateArguments and TemplateArgumentLocs -A constructor to TemplateArgumentList which accepts an array of TemplateArguments. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106532 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index f4ca149b5a..0561f75365 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1106,6 +1106,15 @@ public: None, Extern, Static, PrivateExtern }; + /// \brief The kind of templated function a FunctionDecl can be. + enum TemplatedKind { + TK_NonTemplate, + TK_FunctionTemplate, + TK_MemberSpecialization, + TK_FunctionTemplateSpecialization, + TK_DependentFunctionTemplateSpecialization + }; + private: /// ParamInfo - new[]'d array of pointers to VarDecls for the formal /// parameters of this function. This is null if a prototype or if there are @@ -1398,6 +1407,9 @@ public: /// X::A is required, it will be instantiated from the /// declaration returned by getInstantiatedFromMemberFunction(). FunctionDecl *getInstantiatedFromMemberFunction() const; + + /// \brief What kind of templated function this is. + TemplatedKind getTemplatedKind() const; /// \brief If this function is an instantiation of a member function of a /// class template specialization, retrieves the member specialization @@ -1480,8 +1492,6 @@ public: /// \brief Specify that this function declaration is actually a function /// template specialization. /// - /// \param Context the AST context in which this function resides. - /// /// \param Template the function template that this function template /// specialization specializes. /// @@ -1493,12 +1503,46 @@ public: /// be inserted. /// /// \param TSK the kind of template specialization this is. + /// + /// \param TemplateArgsAsWritten location info of template arguments. void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, const TemplateArgumentList *TemplateArgs, void *InsertPos, TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, const TemplateArgumentListInfo *TemplateArgsAsWritten = 0); + /// \brief Specify that this function declaration is actually a function + /// template specialization. + /// + /// \param Template the function template that this function template + /// specialization specializes. + /// + /// \param NumTemplateArgs number of template arguments that produced this + /// function template specialization from the template. + /// + /// \param TemplateArgs array of template arguments that produced this + /// function template specialization from the template. + /// + /// \param TSK the kind of template specialization this is. + /// + /// \param NumTemplateArgsAsWritten number of template arguments that produced + /// this function template specialization from the template. + /// + /// \param TemplateArgsAsWritten array of location info for the template + /// arguments. + /// + /// \param LAngleLoc location of left angle token. + /// + /// \param RAngleLoc location of right angle token. + void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, + unsigned NumTemplateArgs, + const TemplateArgument *TemplateArgs, + TemplateSpecializationKind TSK, + unsigned NumTemplateArgsAsWritten, + TemplateArgumentLoc *TemplateArgsAsWritten, + SourceLocation LAngleLoc, + SourceLocation RAngleLoc); + /// \brief Specifies that this function declaration is actually a /// dependent function template specialization. void setDependentTemplateSpecialization(ASTContext &Context, diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 3e4966e84d..552b8ee5b3 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -180,6 +180,11 @@ public: TemplateArgumentListBuilder &Builder, bool TakeArgs); + /// TemplateArgumentList - It copies the template arguments into a locally + /// new[]'d array. + TemplateArgumentList(ASTContext &Context, + unsigned NumArgs, const TemplateArgument *Args); + /// Produces a shallow copy of the given template argument list. This /// assumes that the input argument list outlives it. This takes the list as /// a pointer to avoid looking like a copy constructor, since this really diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c912af878a..5fc6fb0481 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1228,6 +1228,23 @@ const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const { return 0; } +FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const { + if (TemplateOrSpecialization.isNull()) + return TK_NonTemplate; + if (TemplateOrSpecialization.is()) + return TK_FunctionTemplate; + if (TemplateOrSpecialization.is()) + return TK_MemberSpecialization; + if (TemplateOrSpecialization.is()) + return TK_FunctionTemplateSpecialization; + if (TemplateOrSpecialization.is + ()) + return TK_DependentFunctionTemplateSpecialization; + + assert(false && "Did we miss a TemplateOrSpecialization type?"); + return TK_NonTemplate; +} + FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) return cast(Info->getInstantiatedFrom()); @@ -1366,6 +1383,27 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, } } +void +FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, + unsigned NumTemplateArgs, + const TemplateArgument *TemplateArgs, + TemplateSpecializationKind TSK, + unsigned NumTemplateArgsAsWritten, + TemplateArgumentLoc *TemplateArgsAsWritten, + SourceLocation LAngleLoc, + SourceLocation RAngleLoc) { + ASTContext &Ctx = getASTContext(); + TemplateArgumentList *TemplArgs + = new (Ctx) TemplateArgumentList(Ctx, NumTemplateArgs, TemplateArgs); + TemplateArgumentListInfo *TemplArgsInfo + = new (Ctx) TemplateArgumentListInfo(LAngleLoc, RAngleLoc); + for (unsigned i=0; i != NumTemplateArgsAsWritten; ++i) + TemplArgsInfo->addArgument(TemplateArgsAsWritten[i]); + + setFunctionTemplateSpecialization(Template, TemplArgs, /*InsertPos=*/0, TSK, + TemplArgsInfo); +} + void FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context, const UnresolvedSetImpl &Templates, diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index a318de656f..3ac32bc80b 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -391,6 +391,22 @@ TemplateArgumentList::TemplateArgumentList(ASTContext &Context, } } +TemplateArgumentList::TemplateArgumentList(ASTContext &Context, + unsigned NumArgs, + const TemplateArgument *Args) + : NumFlatArguments(NumArgs), + NumStructuredArguments(NumArgs) { + + TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs]; + std::copy(Args, Args+NumArgs, NewArgs); + FlatArguments.setPointer(NewArgs); + FlatArguments.setInt(1); // Owns the pointer. + + // Just reuse the flat arguments array. + StructuredArguments.setPointer(NewArgs); + StructuredArguments.setInt(0); // Doesn't own the pointer. +} + /// Produces a shallow copy of the given template argument list. This /// assumes that the input argument list outlives it. This takes the list as /// a pointer to avoid looking like a copy constructor, since this really