brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · ff58505 Raw
71 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 "StdAllocatorConstCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11 12using namespace clang::ast_matchers;13 14namespace clang::tidy::portability {15 16void StdAllocatorConstCheck::registerMatchers(MatchFinder *Finder) {17  // Match std::allocator<const T>.18  auto AllocatorConst = qualType(hasCanonicalType(19      recordType(hasDeclaration(classTemplateSpecializationDecl(20          hasName("::std::allocator"),21          hasTemplateArgument(0,22                              refersToType(qualType(isConstQualified()))))))));23 24  auto HasContainerName =25      hasAnyName("::std::vector", "::std::deque", "::std::list",26                 "::std::multiset", "::std::set", "::std::unordered_multiset",27                 "::std::unordered_set", "::absl::flat_hash_set");28 29  // Match `std::vector<const T> var;` and other common containers like deque,30  // list, and absl::flat_hash_set. Containers like queue and stack use deque31  // but do not directly use std::allocator as a template argument, so they32  // aren't caught.33  Finder->addMatcher(34      typeLoc(35          anyOf(templateSpecializationTypeLoc(),36                qualifiedTypeLoc(37                    hasUnqualifiedLoc(templateSpecializationTypeLoc()))),38          loc(qualType(anyOf(39              recordType(hasDeclaration(classTemplateSpecializationDecl(40                  HasContainerName,41                  anyOf(42                      hasTemplateArgument(1, refersToType(AllocatorConst)),43                      hasTemplateArgument(2, refersToType(AllocatorConst)),44                      hasTemplateArgument(3, refersToType(AllocatorConst)))))),45              // Match std::vector<const dependent>46              templateSpecializationType(47                  templateArgumentCountIs(1),48                  hasTemplateArgument(49                      0, refersToType(qualType(isConstQualified()))),50                  hasDeclaration(namedDecl(HasContainerName)))))))51          .bind("type_loc"),52      this);53}54 55void StdAllocatorConstCheck::check(const MatchFinder::MatchResult &Result) {56  const auto *T = Result.Nodes.getNodeAs<TypeLoc>("type_loc");57  if (!T)58    return;59  // Exclude TypeLoc matches in STL headers.60  if (isSystem(Result.Context->getSourceManager().getFileCharacteristic(61          T->getBeginLoc())))62    return;63 64  diag(T->getBeginLoc(),65       "container using std::allocator<const T> is a deprecated libc++ "66       "extension; remove const for compatibility with other standard "67       "libraries");68}69 70} // namespace clang::tidy::portability71