clang: lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp Source File (original) (raw)

2

9

11

12namespace {

13

14using ast_matchers::callee;

18using ast_matchers::hasCanonicalType;

21using ast_matchers::ofClass;

22using ast_matchers::parameterCountIs;

25using ast_matchers::returns;

26

27CanQualType getLikeReturnType(QualType RT) {

28 if (!RT.isNull() && RT->isPointerType()) {

29 return RT->getPointeeType()

30 ->getCanonicalTypeUnqualified()

31 .getUnqualifiedType();

32 }

33 return {};

34}

35

36CanQualType valueLikeReturnType(QualType RT) {

37 if (!RT.isNull() && RT->isReferenceType()) {

38 return RT.getNonReferenceType()

39 ->getCanonicalTypeUnqualified()

40 .getUnqualifiedType();

41 }

42 return {};

43}

44

45CanQualType pointerLikeReturnType(const CXXRecordDecl &RD) {

46

47

48 CanQualType StarReturnType, ArrowReturnType;

49 for (const auto *MD : RD.methods()) {

50

51

52

53 if (!MD->isConst() || MD->getNumParams() != 0)

54 continue;

55 switch (MD->getOverloadedOperator()) {

56 case OO_Star:

57 StarReturnType = valueLikeReturnType(MD->getReturnType());

58 break;

59 case OO_Arrow:

60 ArrowReturnType = getLikeReturnType(MD->getReturnType());

61 break;

62 default:

63 break;

64 }

65 }

66 if (!StarReturnType.isNull() && !ArrowReturnType.isNull() &&

67 StarReturnType == ArrowReturnType)

68 return StarReturnType;

69

70 return {};

71}

72

73QualType findReturnType(const CXXRecordDecl &RD, StringRef MethodName) {

74 for (const auto *MD : RD.methods()) {

75

76

77

78 if (!MD->isConst() || MD->getNumParams() != 0 ||

79 MD->getOverloadedOperator() != OO_None)

80 continue;

81 clang::IdentifierInfo *II = MD->getIdentifier();

82 if (II && II->isStr(MethodName))

83 return MD->getReturnType();

84 }

85 return {};

86}

87

88}

89}

90

91

92

93namespace {

94

95using clang::dataflow::findReturnType;

96using clang::dataflow::getLikeReturnType;

97using clang::dataflow::pointerLikeReturnType;

98using clang::dataflow::valueLikeReturnType;

99

101 clang::StringRef, MethodName) {

102 auto RT = pointerLikeReturnType(Node);

103 if (RT.isNull())

104 return false;

105 return getLikeReturnType(findReturnType(Node, MethodName)) == RT;

106}

107

109 clang::StringRef, MethodName) {

110 auto RT = pointerLikeReturnType(Node);

111 if (RT.isNull())

112 return false;

113 return valueLikeReturnType(findReturnType(Node, MethodName)) == RT;

114}

115

117 auto RT = pointerLikeReturnType(Node);

118 if (RT.isNull())

119 return false;

120 return getLikeReturnType(findReturnType(Node, "get")) == RT ||

121 valueLikeReturnType(findReturnType(Node, "value")) == RT;

122}

123

125 return !pointerLikeReturnType(Node).isNull();

126}

127

128}

129

131

137 ofClass(smartPointerClassWithGetOrValue()))));

138}

139

144 returns(hasCanonicalType(pointerType())),

145 ofClass(smartPointerClassWithGetOrValue()))));

146}

147

153 ofClass(pointerClass()))));

154}

155

160 returns(hasCanonicalType(pointerType())),

161 ofClass(pointerClass()))));

162}

163

167 parameterCountIs(0), returns(hasCanonicalType(referenceType())),

169 ofClass(smartPointerClassWithValueLike(MethodName)))));

170}

171

175 parameterCountIs(0), returns(hasCanonicalType(pointerType())),

176 hasName(MethodName), ofClass(smartPointerClassWithGetLike(MethodName)))));

177}

178

181 const FunctionDecl *CanonicalCallee = nullptr;

184 if (Callee == nullptr)

185 return nullptr;

187 if (RD == nullptr)

188 return nullptr;

189 for (const auto *MD : RD->methods()) {

190 if (MD->getOverloadedOperator() == OO_Star && MD->isConst() &&

191 MD->getNumParams() == 0 && MD->getReturnType()->isReferenceType()) {

192 CanonicalCallee = MD;

193 break;

194 }

195 }

196 return CanonicalCallee;

197}

198

199}

#define AST_MATCHER(Type, DefineMatcher)

AST_MATCHER(Type, DefineMatcher) { ... } defines a zero parameter function named DefineMatcher() that...

#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)

AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } defines a single-parameter function name...

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines an enumeration for C++ overloaded operators.

C Language Family Type Representation.

Represents a static or instance method of a struct/union/class.

Represents a C++ struct/union/class.

method_range methods() const

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

FunctionDecl * getDirectCallee()

If the callee is a FunctionDecl, return it. Otherwise return null.

Represents a function declaration or definition.

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

internal::Matcher< NamedDecl > hasName(StringRef Name)

Matches NamedDecl nodes that have the specified name.

const internal::VariadicDynCastAllOfMatcher< Stmt, CXXMemberCallExpr > cxxMemberCallExpr

Matches member call expressions.

internal::Matcher< Stmt > StatementMatcher

const internal::VariadicDynCastAllOfMatcher< Stmt, CXXOperatorCallExpr > cxxOperatorCallExpr

Matches overloaded operator calls.

const AstTypeMatcher< PointerType > pointerType

internal::PolymorphicMatcher< internal::HasOverloadedOperatorNameMatcher, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl), std::vector< std::string > > hasOverloadedOperatorName(StringRef Name)

Matches overloaded operator names.

const internal::VariadicDynCastAllOfMatcher< Decl, CXXMethodDecl > cxxMethodDecl

Matches method declarations.

const AstTypeMatcher< ReferenceType > referenceType

Dataflow Directional Tag Classes.

ast_matchers::StatementMatcher isSmartPointerLikeValueMethodCall(clang::StringRef MethodName="value")

Definition SmartPointerAccessorCaching.cpp:165

ast_matchers::StatementMatcher isPointerLikeOperatorStar()

Matchers: For now, these match on any class with an operator* or operator-> where the return types ha...

Definition SmartPointerAccessorCaching.cpp:148

internal::Matcher< NamedDecl > hasName(StringRef Name)

Matches NamedDecl nodes that have the specified name.

const internal::VariadicDynCastAllOfMatcher< Stmt, CXXMemberCallExpr > cxxMemberCallExpr

Matches member call expressions.

ast_matchers::StatementMatcher isSmartPointerLikeOperatorArrow()

Definition SmartPointerAccessorCaching.cpp:140

const internal::VariadicDynCastAllOfMatcher< Stmt, CXXOperatorCallExpr > cxxOperatorCallExpr

Matches overloaded operator calls.

const AstTypeMatcher< PointerType > pointerType

internal::PolymorphicMatcher< internal::HasOverloadedOperatorNameMatcher, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl), std::vector< std::string > > hasOverloadedOperatorName(StringRef Name)

Matches overloaded operator names.

const FunctionDecl * getCanonicalSmartPointerLikeOperatorCallee(const CallExpr *CE)

Returns the "canonical" callee for smart pointer operators (* and ->) as a key for caching.

Definition SmartPointerAccessorCaching.cpp:180

ast_matchers::StatementMatcher isSmartPointerLikeOperatorStar()

Definition SmartPointerAccessorCaching.cpp:132

const internal::VariadicDynCastAllOfMatcher< Decl, CXXMethodDecl > cxxMethodDecl

Matches method declarations.

ast_matchers::StatementMatcher isSmartPointerLikeGetMethodCall(clang::StringRef MethodName="get")

Definition SmartPointerAccessorCaching.cpp:173

ast_matchers::StatementMatcher isPointerLikeOperatorArrow()

Definition SmartPointerAccessorCaching.cpp:156

const AstTypeMatcher< ReferenceType > referenceType

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

@ OO_None

Not an overloaded operator.