11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/Lex/Lexer.h" 21 void PostfixOperatorCheck::registerMatchers(MatchFinder *Finder) {
22 if (!getLangOpts().CPlusPlus)
25 Finder->addMatcher(functionDecl(anyOf(hasOverloadedOperatorName(
"++"),
26 hasOverloadedOperatorName(
"--")),
27 unless(isInstantiated()))
32 void PostfixOperatorCheck::check(
const MatchFinder::MatchResult &
Result) {
33 const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"decl");
36 if (
const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
37 HasThis = MethodDecl->isInstance();
40 if (FuncDecl->getNumParams() != (HasThis ? 1 : 2))
43 SourceRange ReturnRange = FuncDecl->getReturnTypeSourceRange();
44 SourceLocation
Location = ReturnRange.getBegin();
45 if (!Location.isValid())
48 QualType
ReturnType = FuncDecl->getReturnType();
51 if (
const auto *RefType = ReturnType->getAs<ReferenceType>()) {
52 auto Diag = diag(Location,
"overloaded %0 returns a reference instead of a " 53 "constant object type")
56 if (Location.isMacroID() || ReturnType->getAs<TypedefType>() ||
57 RefType->getPointeeTypeAsWritten()->getAs<TypedefType>())
60 QualType ReplaceType =
61 ReturnType.getNonReferenceType().getLocalUnqualifiedType();
64 if (!ReturnType->getPointeeType().isConstQualified())
65 ReplaceType.addConst();
67 Diag << FixItHint::CreateReplacement(
69 ReplaceType.getAsString(Result.Context->getPrintingPolicy()) +
" ");
74 if (ReturnType.isConstQualified() || ReturnType->isBuiltinType() ||
75 ReturnType->isPointerType())
79 diag(Location,
"overloaded %0 returns a non-constant object instead of a " 80 "constant object type")
83 if (!Location.isMacroID() && !ReturnType->getAs<TypedefType>())
84 Diag << FixItHint::CreateInsertion(Location,
"const ");
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//