10#include "clang/AST/ASTContext.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
20 if (Node.hasDefinition())
21 return Node.getNumBases() > 0;
28void MultipleInheritanceCheck::addNodeToInterfaceMap(
const CXXRecordDecl *Node,
30 assert(Node->getIdentifier());
31 StringRef Name = Node->getIdentifier()->getName();
32 InterfaceMap.insert(std::make_pair(Name, IsInterface));
38bool MultipleInheritanceCheck::getInterfaceStatus(
const CXXRecordDecl *Node,
39 bool &IsInterface)
const {
40 assert(Node->getIdentifier());
41 StringRef Name = Node->getIdentifier()->getName();
42 auto Pair = InterfaceMap.find(Name);
43 if (Pair == InterfaceMap.end())
45 IsInterface = Pair->second;
49bool MultipleInheritanceCheck::isCurrentClassInterface(
50 const CXXRecordDecl *Node)
const {
52 if (!Node->field_empty())
56 return llvm::none_of(Node->methods(), [](
const CXXMethodDecl *M) {
57 return M->isUserProvided() && !M->isPureVirtual() && !M->isStatic();
61bool MultipleInheritanceCheck::isInterface(
const CXXRecordDecl *Node) {
62 if (!Node->getIdentifier())
66 bool PreviousIsInterfaceResult =
false;
67 if (getInterfaceStatus(Node, PreviousIsInterfaceResult))
68 return PreviousIsInterfaceResult;
71 for (
const auto &I : Node->bases()) {
74 const auto *Base = I.getType()->getAsCXXRecordDecl();
77 assert(Base->isCompleteDefinition());
78 if (!isInterface(Base)) {
79 addNodeToInterfaceMap(Node,
false);
84 bool CurrentClassIsInterface = isCurrentClassInterface(Node);
85 addNodeToInterfaceMap(Node, CurrentClassIsInterface);
86 return CurrentClassIsInterface;
91 Finder->addMatcher(cxxRecordDecl(hasBases(), isDefinition()).bind(
"decl"),
96 if (
const auto *D = Result.Nodes.getNodeAs<CXXRecordDecl>(
"decl")) {
99 unsigned NumConcrete = 0;
100 for (
const auto &I : D->bases()) {
103 const auto *Base = I.getType()->getAsCXXRecordDecl();
106 assert(Base->isCompleteDefinition());
107 if (!isInterface(Base))
113 for (
const auto &V : D->vbases()) {
114 const auto *Base = V.getType()->getAsCXXRecordDecl();
117 assert(Base->isCompleteDefinition());
118 if (!isInterface(Base))
122 if (NumConcrete > 1) {
123 diag(D->getBeginLoc(),
"inheriting multiple classes that aren't "
124 "pure virtual is discouraged");
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
AST_MATCHER(BinaryOperator, isRelationalOperator)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//