225 auto EmitValueWarning = [
this, &Result](
const NestedNameSpecifierLoc &QualLoc,
226 SourceLocation EndLoc) {
227 SourceLocation TemplateNameEndLoc;
229 QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
230 TemplateNameEndLoc = Lexer::getLocForEndOfToken(
231 TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
232 Result.Context->getLangOpts());
236 if (EndLoc.isMacroID() || QualLoc.getEndLoc().isMacroID() ||
237 TemplateNameEndLoc.isMacroID()) {
240 diag(QualLoc.getBeginLoc(),
"use c++17 style variable templates");
243 diag(QualLoc.getBeginLoc(),
"use c++17 style variable templates")
244 << FixItHint::CreateInsertion(TemplateNameEndLoc,
"_v")
245 << FixItHint::CreateRemoval({QualLoc.getEndLoc(), EndLoc});
248 auto EmitTypeWarning = [
this, &Result](
const NestedNameSpecifierLoc &QualLoc,
249 SourceLocation EndLoc,
250 SourceLocation TypenameLoc) {
251 SourceLocation TemplateNameEndLoc;
253 QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
254 TemplateNameEndLoc = Lexer::getLocForEndOfToken(
255 TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
256 Result.Context->getLangOpts());
260 if (EndLoc.isMacroID() || QualLoc.getEndLoc().isMacroID() ||
261 TemplateNameEndLoc.isMacroID() || TypenameLoc.isMacroID()) {
264 diag(QualLoc.getBeginLoc(),
"use c++14 style type templates");
267 auto Diag = diag(QualLoc.getBeginLoc(),
"use c++14 style type templates");
269 if (TypenameLoc.isValid())
270 Diag << FixItHint::CreateRemoval(TypenameLoc);
271 Diag << FixItHint::CreateInsertion(TemplateNameEndLoc,
"_t")
272 << FixItHint::CreateRemoval({QualLoc.getEndLoc(), EndLoc});
275 if (
const auto *DRE = Result.Nodes.getNodeAs<DeclRefExpr>(
Bind)) {
276 if (!DRE->hasQualifier())
278 if (
const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
279 DRE->getQualifier().getAsRecordDecl())) {
281 EmitValueWarning(DRE->getQualifierLoc(), DRE->getEndLoc());
286 if (
const auto *TL = Result.Nodes.getNodeAs<TypedefTypeLoc>(
Bind)) {
287 const NestedNameSpecifierLoc QualLoc = TL->getQualifierLoc();
288 const NestedNameSpecifier NNS = QualLoc.getNestedNameSpecifier();
289 if (
const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
290 NNS.getAsRecordDecl())) {
292 EmitTypeWarning(TL->getQualifierLoc(), TL->getEndLoc(),
293 TL->getElaboratedKeywordLoc());
298 if (
const auto *DSDRE =
299 Result.Nodes.getNodeAs<DependentScopeDeclRefExpr>(
Bind)) {
301 EmitValueWarning(DSDRE->getQualifierLoc(), DSDRE->getEndLoc());
305 if (
const auto *DNTL = Result.Nodes.getNodeAs<DependentNameTypeLoc>(
Bind)) {
306 const NestedNameSpecifierLoc QualLoc = DNTL->getQualifierLoc();
308 EmitTypeWarning(QualLoc, DNTL->getEndLoc(),
309 DNTL->getElaboratedKeywordLoc());
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.