forked from OSchip/llvm-project
Fix type printing of array template args
The code example: ``` constexpr const char kEta[] = "Eta"; template <const char*, typename T> class Column {}; using quick = Column<kEta,double>; void lookup() { quick c1; c1.ls(); } ``` emits error: no member named 'ls' in 'Column<&kEta, double>'. The patch fixes the printed type name by not printing the ampersand for array types. Differential Revision: https://reviews.llvm.org/D36368
This commit is contained in:
parent
be8ad4e98e
commit
8518742104
|
@ -80,6 +80,26 @@ static void printIntegral(const TemplateArgument &TemplArg,
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned getArrayDepth(QualType type) {
|
||||
unsigned count = 0;
|
||||
while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
|
||||
count++;
|
||||
type = arrayType->getElementType();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
|
||||
// Generally, if the parameter type is a pointer, we must be taking the
|
||||
// address of something and need a &. However, if the argument is an array,
|
||||
// this could be implicit via array-to-pointer decay.
|
||||
if (!paramType->isPointerType())
|
||||
return paramType->isMemberPointerType();
|
||||
if (argType->isArrayType())
|
||||
return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TemplateArgument Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -363,8 +383,10 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!getParamTypeForDecl()->isReferenceType())
|
||||
Out << '&';
|
||||
if (auto *VD = dyn_cast<ValueDecl>(ND)) {
|
||||
if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
|
||||
Out << "&";
|
||||
}
|
||||
ND->printQualifiedName(Out);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,12 @@ void fn_tmpl() {}
|
|||
template void fn_tmpl<int, freefunc>();
|
||||
// CHECK-DAG: "fn_tmpl<int,&freefunc>"
|
||||
|
||||
template <typename T, void (*)(void)>
|
||||
void fn_tmpl_typecheck() {}
|
||||
|
||||
template void fn_tmpl_typecheck<int, &freefunc>();
|
||||
// CHECK-DAG: "fn_tmpl_typecheck<int,&freefunc>"
|
||||
|
||||
template <typename A, typename B, typename C> struct ClassTemplate { A a; B b; C c; };
|
||||
ClassTemplate<char, short, ClassTemplate<int, int, int> > f;
|
||||
// This will only show up in normal debug builds. The space in `> >` is
|
||||
|
|
|
@ -77,3 +77,40 @@ namespace ReferenceToConstexpr {
|
|||
};
|
||||
void f(C<a> ca) { ca.f({}, 0); }
|
||||
}
|
||||
|
||||
using FourChars = const char[4];
|
||||
constexpr FourChars kEta = "Eta";
|
||||
constexpr const char kDes[4] = "Des";
|
||||
constexpr const char *kNull = "Phi";
|
||||
constexpr const char **kZero[] = {};
|
||||
|
||||
template <const char *, typename T> class Column {};
|
||||
template <const char[], typename T> class Dolumn {};
|
||||
template <const char (*)[4], typename T> class Folumn {};
|
||||
template <FourChars *, typename T> class Golumn {};
|
||||
template <const char *const *, typename T> class Holumn {};
|
||||
template <const char *const *const *, typename T> class Jolumn {};
|
||||
template <const char **const (*)[0], typename T> class Iolumn {};
|
||||
|
||||
class container {
|
||||
public:
|
||||
int a;
|
||||
};
|
||||
template <int container::*> class Kolumn {};
|
||||
|
||||
void lookup() {
|
||||
Column<kEta, double>().ls(); // expected-error {{<kEta,}}
|
||||
Column<kDes, double>().ls(); // expected-error {{<kDes,}}
|
||||
Column<nullptr, double>().ls(); // expected-error {{<nullptr,}}
|
||||
Dolumn<kEta, double>().ls(); // expected-error {{<kEta,}}
|
||||
Dolumn<kDes, double>().ls(); // expected-error {{<kDes,}}
|
||||
Folumn<&kEta, double>().ls(); // expected-error {{<&kEta,}}
|
||||
Folumn<&kDes, double>().ls(); // expected-error {{<&kDes,}}
|
||||
Golumn<&kEta, double>().ls(); // expected-error {{<&kEta,}}
|
||||
Golumn<&kDes, double>().ls(); // expected-error {{<&kDes,}}
|
||||
Holumn<&kNull, double>().ls(); // expected-error {{<&kNull,}}
|
||||
Jolumn<kZero, double>().ls(); // expected-error {{<kZero,}}
|
||||
Iolumn<&kZero, double>().ls(); // expected-error {{<&kZero,}}
|
||||
Kolumn<&container::a>().ls(); // expected-error {{<&container::a}}
|
||||
Kolumn<nullptr>().ls(); // expected-error {{<nullptr}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue