brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · 6181ac8 Raw
70 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "IncorrectEnableIfCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::bugprone {16 17namespace {18 19AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,20              ast_matchers::internal::Matcher<TypeLoc>, InnerMatcher) {21  if (Node.getIdentifier() != nullptr || !Node.hasDefaultArgument() ||22      Node.getDefaultArgument().getArgument().isNull())23    return false;24 25  const TypeLoc DefaultArgTypeLoc =26      Node.getDefaultArgument().getTypeSourceInfo()->getTypeLoc();27  return InnerMatcher.matches(DefaultArgTypeLoc, Finder, Builder);28}29 30} // namespace31 32void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {33  Finder->addMatcher(34      templateTypeParmDecl(35          hasUnnamedDefaultArgument(templateSpecializationTypeLoc(36                                        loc(qualType(hasDeclaration(namedDecl(37                                            hasName("::std::enable_if"))))))38                                        .bind("enable_if_specialization")))39          .bind("enable_if"),40      this);41}42 43void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {44  const auto *EnableIf =45      Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");46  const auto *EnableIfSpecializationLoc =47      Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(48          "enable_if_specialization");49 50  if (!EnableIf || !EnableIfSpecializationLoc)51    return;52 53  const SourceManager &SM = *Result.SourceManager;54  const SourceLocation RAngleLoc =55      SM.getExpansionLoc(EnableIfSpecializationLoc->getRAngleLoc());56 57  auto Diag = diag(EnableIf->getBeginLoc(),58                   "incorrect std::enable_if usage detected; use "59                   "'typename std::enable_if<...>::type'");60  // FIXME: This should handle the enable_if specialization already having an61  // elaborated keyword.62  if (!getLangOpts().CPlusPlus20) {63    Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),64                                       "typename ");65  }66  Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");67}68 69} // namespace clang::tidy::bugprone70