10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Lex/Lexer.h"
20 void PostfixOperatorCheck::registerMatchers(MatchFinder *Finder) {
21 Finder->addMatcher(functionDecl(hasAnyOverloadedOperatorName(
"++",
"--"),
22 unless(isInstantiated()))
27 void PostfixOperatorCheck::check(
const MatchFinder::MatchResult &Result) {
28 const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"decl");
31 if (
const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
32 HasThis = MethodDecl->isInstance();
35 if (FuncDecl->getNumParams() != (HasThis ? 1 : 2))
38 SourceRange ReturnRange = FuncDecl->getReturnTypeSourceRange();
39 SourceLocation
Location = ReturnRange.getBegin();
43 QualType
ReturnType = FuncDecl->getReturnType();
46 if (
const auto *RefType =
ReturnType->getAs<ReferenceType>()) {
47 auto Diag = diag(
Location,
"overloaded %0 returns a reference instead of a "
48 "constant object type")
52 RefType->getPointeeTypeAsWritten()->getAs<TypedefType>())
55 QualType ReplaceType =
56 ReturnType.getNonReferenceType().getLocalUnqualifiedType();
59 if (!
ReturnType->getPointeeType().isConstQualified())
60 ReplaceType.addConst();
62 Diag << FixItHint::CreateReplacement(
64 ReplaceType.getAsString(Result.Context->getPrintingPolicy()) +
" ");
74 diag(
Location,
"overloaded %0 returns a non-constant object instead of a "
75 "constant object type")
79 Diag << FixItHint::CreateInsertion(
Location,
"const ");