123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- //===--- MisplacedConstCheck.cpp - clang-tidy------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "MisplacedConstCheck.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/ASTMatchers/ASTMatchFinder.h"
- using namespace clang::ast_matchers;
- namespace clang::tidy::misc {
- void MisplacedConstCheck::registerMatchers(MatchFinder *Finder) {
- auto NonConstAndNonFunctionPointerType = hasType(pointerType(unless(
- pointee(anyOf(isConstQualified(), ignoringParens(functionType()))))));
- Finder->addMatcher(
- valueDecl(hasType(qualType(
- isConstQualified(),
- elaboratedType(namesType(typedefType(hasDeclaration(
- anyOf(typedefDecl(NonConstAndNonFunctionPointerType)
- .bind("typedef"),
- typeAliasDecl(NonConstAndNonFunctionPointerType)
- .bind("typeAlias")))))))))
- .bind("decl"),
- this);
- }
- static QualType guessAlternateQualification(ASTContext &Context, QualType QT) {
- // We're given a QualType from a typedef where the qualifiers apply to the
- // pointer instead of the pointee. Strip the const qualifier from the pointer
- // type and add it to the pointee instead.
- if (!QT->isPointerType())
- return QT;
- Qualifiers Quals = QT.getLocalQualifiers();
- Quals.removeConst();
- QualType NewQT = Context.getPointerType(
- QualType(QT->getPointeeType().getTypePtr(), Qualifiers::Const));
- return NewQT.withCVRQualifiers(Quals.getCVRQualifiers());
- }
- void MisplacedConstCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *Var = Result.Nodes.getNodeAs<ValueDecl>("decl");
- ASTContext &Ctx = *Result.Context;
- QualType CanQT = Var->getType().getCanonicalType();
- SourceLocation AliasLoc;
- const char *AliasType;
- if (const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>("typedef")) {
- AliasLoc = Typedef->getLocation();
- AliasType = "typedef";
- } else if (const auto *TypeAlias =
- Result.Nodes.getNodeAs<TypeAliasDecl>("typeAlias")) {
- AliasLoc = TypeAlias->getLocation();
- AliasType = "type alias";
- } else {
- llvm_unreachable("registerMatchers has registered an unknown matcher,"
- " code out of sync");
- }
- diag(Var->getLocation(), "%0 declared with a const-qualified %1; "
- "results in the type being '%2' instead of '%3'")
- << Var << AliasType << CanQT.getAsString(Ctx.getPrintingPolicy())
- << guessAlternateQualification(Ctx, CanQT)
- .getAsString(Ctx.getPrintingPolicy());
- diag(AliasLoc, "%0 declared here", DiagnosticIDs::Note) << AliasType;
- }
- } // namespace clang::tidy::misc
|