MisplacedConstCheck.cpp
2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//===--- 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 {
namespace tidy {
namespace misc {
void MisplacedConstCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
valueDecl(hasType(isConstQualified()),
hasType(typedefType(hasDeclaration(
typedefDecl(hasType(pointerType(unless(pointee(
anyOf(isConstQualified(),
ignoringParens(functionType())))))))
.bind("typedef")))))
.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");
const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>("typedef");
ASTContext &Ctx = *Result.Context;
QualType CanQT = Var->getType().getCanonicalType();
diag(Var->getLocation(), "%0 declared with a const-qualified typedef type; "
"results in the type being '%1' instead of '%2'")
<< Var << CanQT.getAsString(Ctx.getPrintingPolicy())
<< guessAlternateQualification(Ctx, CanQT)
.getAsString(Ctx.getPrintingPolicy());
diag(Typedef->getLocation(), "typedef declared here", DiagnosticIDs::Note);
}
} // namespace misc
} // namespace tidy
} // namespace clang