10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
19 void MisplacedConstCheck::registerMatchers(MatchFinder *Finder) {
20 auto NonConstAndNonFunctionPointerType = hasType(pointerType(unless(
21 pointee(anyOf(isConstQualified(), ignoringParens(functionType()))))));
25 hasType(isConstQualified()),
26 hasType(typedefType(hasDeclaration(anyOf(
27 typedefDecl(NonConstAndNonFunctionPointerType).bind(
"typedef"),
28 typeAliasDecl(NonConstAndNonFunctionPointerType)
29 .bind(
"typeAlias"))))))
38 if (!QT->isPointerType())
41 Qualifiers Quals = QT.getLocalQualifiers();
44 QualType NewQT = Context.getPointerType(
46 return NewQT.withCVRQualifiers(Quals.getCVRQualifiers());
49 void MisplacedConstCheck::check(
const MatchFinder::MatchResult &Result) {
50 const auto *Var = Result.Nodes.getNodeAs<ValueDecl>(
"decl");
51 ASTContext &
Ctx = *Result.Context;
52 QualType CanQT = Var->getType().getCanonicalType();
54 SourceLocation AliasLoc;
55 const char *AliasType;
56 if (
const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>(
"typedef")) {
57 AliasLoc = Typedef->getLocation();
58 AliasType =
"typedef";
59 }
else if (
const auto *TypeAlias =
60 Result.Nodes.getNodeAs<TypeAliasDecl>(
"typeAlias")) {
61 AliasLoc = TypeAlias->getLocation();
62 AliasType =
"type alias";
64 llvm_unreachable(
"registerMatchers has registered an unknown matcher,"
68 diag(Var->getLocation(),
"%0 declared with a const-qualified %1; "
69 "results in the type being '%2' instead of '%3'")
70 << Var << AliasType << CanQT.getAsString(
Ctx.getPrintingPolicy())
72 .getAsString(
Ctx.getPrintingPolicy());
73 diag(AliasLoc,
"%0 declared here", DiagnosticIDs::Note) << AliasType;