Comment AST: Add support for variable templates

We treat them as variables of course, though if they have function
pointer type we treat them as functions, i.e. allow parameter and return
value specifications. Just like VarDecls.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D111266
This commit is contained in:
Aaron Puchert 2021-11-09 22:24:44 +01:00
parent 4d63824300
commit 63ef0e17e2
3 changed files with 57 additions and 2 deletions

View File

@ -1031,8 +1031,8 @@ struct DeclInfo {
ClassKind, ClassKind,
/// Something that we consider a "variable": /// Something that we consider a "variable":
/// \li namespace scope variables; /// \li namespace scope variables and variable templates;
/// \li static and non-static class data members; /// \li static and non-static class data members and member templates;
/// \li enumerators. /// \li enumerators.
VariableKind, VariableKind,

View File

@ -294,6 +294,12 @@ void DeclInfo::fill() {
Kind = ClassKind; Kind = ClassKind;
break; break;
case Decl::Var: case Decl::Var:
if (const VarTemplateDecl *VTD =
cast<VarDecl>(CommentDecl)->getDescribedVarTemplate()) {
TemplateKind = TemplateSpecialization;
TemplateParameters = VTD->getTemplateParameters();
}
LLVM_FALLTHROUGH;
case Decl::Field: case Decl::Field:
case Decl::EnumConstant: case Decl::EnumConstant:
case Decl::ObjCIvar: case Decl::ObjCIvar:
@ -305,6 +311,15 @@ void DeclInfo::fill() {
TSI = PD->getTypeSourceInfo(); TSI = PD->getTypeSourceInfo();
Kind = VariableKind; Kind = VariableKind;
break; break;
case Decl::VarTemplate: {
const VarTemplateDecl *VTD = cast<VarTemplateDecl>(CommentDecl);
Kind = VariableKind;
TemplateKind = Template;
TemplateParameters = VTD->getTemplateParameters();
if (const VarDecl *VD = VTD->getTemplatedDecl())
TSI = VD->getTypeSourceInfo();
break;
}
case Decl::Namespace: case Decl::Namespace:
Kind = NamespaceKind; Kind = NamespaceKind;
break; break;

View File

@ -1323,6 +1323,17 @@ namespace AllowParamAndReturnsOnFunctionPointerVars {
*/ */
int (*functionPointerVariable)(int i); int (*functionPointerVariable)(int i);
#if __cplusplus >= 201402L
/**
* functionPointerVariableTemplate
*
* @param i is something.
* @returns integer.
*/
template<typename T>
int (*functionPointerVariableTemplate)(T i);
#endif
struct HasFields { struct HasFields {
/** /**
* functionPointerField * functionPointerField
@ -1331,6 +1342,18 @@ struct HasFields {
* @returns integer. * @returns integer.
*/ */
int (*functionPointerField)(int i); int (*functionPointerField)(int i);
#if __cplusplus >= 201402L
/**
* functionPointerTemplateMember
*
* @tparam T some type.
* @param i is integer.
* @returns integer.
*/
template<typename T>
static int (*functionPointerTemplateMember)(int i);
#endif
}; };
// expected-warning@+5 {{parameter 'p' not found in the function declaration}} // expected-warning@+5 {{parameter 'p' not found in the function declaration}}
@ -1343,6 +1366,23 @@ struct HasFields {
*/ */
void (*functionPointerVariableThatLeadsNowhere)(); void (*functionPointerVariableThatLeadsNowhere)();
#if __cplusplus >= 201402L
// expected-warning@+8 {{template parameter 'X' not found in the template declaration}}
// expected-note@+7 {{did you mean 'T'?}}
// expected-warning@+7 {{parameter 'p' not found in the function declaration}}
// expected-note@+6 {{did you mean 'x'?}}
// expected-warning@+6 {{'\returns' command used in a comment that is attached to a function returning void}}
/**
* functionPointerVariable
*
* \tparam X typo
* \param p not here.
* \returns integer.
*/
template<typename T>
void (*functionPointerVariableTemplateThatLeadsNowhere)(T x);
#endif
// Still warn about param/returns commands for variables that don't specify // Still warn about param/returns commands for variables that don't specify
// the type directly: // the type directly: