224 auto EmitValueWarning = [
this, &Result](
const NestedNameSpecifierLoc &QualLoc,
225 SourceLocation EndLoc) {
226 SourceLocation TemplateNameEndLoc;
228 QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
229 TemplateNameEndLoc = Lexer::getLocForEndOfToken(
230 TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
231 Result.Context->getLangOpts());
235 if (EndLoc.isMacroID() || QualLoc.getEndLoc().isMacroID() ||
236 TemplateNameEndLoc.isMacroID()) {
239 diag(QualLoc.getBeginLoc(),
"use c++17 style variable templates");
242 diag(QualLoc.getBeginLoc(),
"use c++17 style variable templates")
243 << FixItHint::CreateInsertion(TemplateNameEndLoc,
"_v")
244 << FixItHint::CreateRemoval({QualLoc.getEndLoc(), EndLoc});
247 auto EmitTypeWarning = [
this, &Result](
const NestedNameSpecifierLoc &QualLoc,
248 SourceLocation EndLoc,
249 SourceLocation TypenameLoc) {
250 SourceLocation TemplateNameEndLoc;
252 QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
253 TemplateNameEndLoc = Lexer::getLocForEndOfToken(
254 TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
255 Result.Context->getLangOpts());
259 if (EndLoc.isMacroID() || QualLoc.getEndLoc().isMacroID() ||
260 TemplateNameEndLoc.isMacroID() || TypenameLoc.isMacroID()) {
263 diag(QualLoc.getBeginLoc(),
"use c++14 style type templates");
266 auto Diag = diag(QualLoc.getBeginLoc(),
"use c++14 style type templates");
268 if (TypenameLoc.isValid())
269 Diag << FixItHint::CreateRemoval(TypenameLoc);
270 Diag << FixItHint::CreateInsertion(TemplateNameEndLoc,
"_t")
271 << FixItHint::CreateRemoval({QualLoc.getEndLoc(), EndLoc});
274 if (
const auto *DRE = Result.Nodes.getNodeAs<DeclRefExpr>(
Bind)) {
275 if (!DRE->hasQualifier())
277 if (
const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
278 DRE->getQualifier().getAsRecordDecl())) {
280 EmitValueWarning(DRE->getQualifierLoc(), DRE->getEndLoc());
285 if (
const auto *TL = Result.Nodes.getNodeAs<TypedefTypeLoc>(
Bind)) {
286 const NestedNameSpecifierLoc QualLoc = TL->getQualifierLoc();
287 const NestedNameSpecifier NNS = QualLoc.getNestedNameSpecifier();
288 if (
const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
289 NNS.getAsRecordDecl())) {
291 EmitTypeWarning(TL->getQualifierLoc(), TL->getEndLoc(),
292 TL->getElaboratedKeywordLoc());
297 if (
const auto *DSDRE =
298 Result.Nodes.getNodeAs<DependentScopeDeclRefExpr>(
Bind)) {
300 EmitValueWarning(DSDRE->getQualifierLoc(), DSDRE->getEndLoc());
304 if (
const auto *DNTL = Result.Nodes.getNodeAs<DependentNameTypeLoc>(
Bind)) {
305 const NestedNameSpecifierLoc QualLoc = DNTL->getQualifierLoc();
307 EmitTypeWarning(QualLoc, DNTL->getEndLoc(),
308 DNTL->getElaboratedKeywordLoc());
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.