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.

llvm-svn: 106532
This commit is contained in:
Argyrios Kyrtzidis 2010-06-22 09:54:51 +00:00
parent 1e63c74f60
commit cb6f346873
4 changed files with 105 additions and 2 deletions

View File

@ -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<int>::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,

View File

@ -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

View File

@ -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<FunctionTemplateDecl *>())
return TK_FunctionTemplate;
if (TemplateOrSpecialization.is<MemberSpecializationInfo *>())
return TK_MemberSpecialization;
if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>())
return TK_FunctionTemplateSpecialization;
if (TemplateOrSpecialization.is
<DependentFunctionTemplateSpecializationInfo*>())
return TK_DependentFunctionTemplateSpecialization;
assert(false && "Did we miss a TemplateOrSpecialization type?");
return TK_NonTemplate;
}
FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
return cast<FunctionDecl>(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,

View File

@ -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