clang 20.0.0git
PtrTypesSemantics.cpp
Go to the documentation of this file.
1//=======- PtrTypesSemantics.cpp ---------------------------------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "PtrTypesSemantics.h"
10#include "ASTUtils.h"
12#include "clang/AST/Decl.h"
13#include "clang/AST/DeclCXX.h"
14#include "clang/AST/ExprCXX.h"
16#include <optional>
17
18using namespace clang;
19
20namespace {
21
22bool hasPublicMethodInBaseClass(const CXXRecordDecl *R, StringRef NameToMatch) {
23 assert(R);
24 assert(R->hasDefinition());
25
26 for (const CXXMethodDecl *MD : R->methods()) {
27 const auto MethodName = safeGetName(MD);
28 if (MethodName == NameToMatch && MD->getAccess() == AS_public)
29 return true;
30 }
31 return false;
32}
33
34} // namespace
35
36namespace clang {
37
38std::optional<const clang::CXXRecordDecl *>
39hasPublicMethodInBase(const CXXBaseSpecifier *Base, StringRef NameToMatch) {
40 assert(Base);
41
42 const Type *T = Base->getType().getTypePtrOrNull();
43 if (!T)
44 return std::nullopt;
45
47 if (!R)
48 return std::nullopt;
49 if (!R->hasDefinition())
50 return std::nullopt;
51
52 return hasPublicMethodInBaseClass(R, NameToMatch) ? R : nullptr;
53}
54
55std::optional<bool> isSmartPtrCompatible(const CXXRecordDecl *R,
56 StringRef IncMethodName,
57 StringRef DecMethodName) {
58 assert(R);
59
60 R = R->getDefinition();
61 if (!R)
62 return std::nullopt;
63
64 bool hasRef = hasPublicMethodInBaseClass(R, IncMethodName);
65 bool hasDeref = hasPublicMethodInBaseClass(R, DecMethodName);
66 if (hasRef && hasDeref)
67 return true;
68
69 CXXBasePaths Paths;
70 Paths.setOrigin(const_cast<CXXRecordDecl *>(R));
71
72 bool AnyInconclusiveBase = false;
73 const auto hasPublicRefInBase = [&](const CXXBaseSpecifier *Base,
74 CXXBasePath &) {
75 auto hasRefInBase = clang::hasPublicMethodInBase(Base, IncMethodName);
76 if (!hasRefInBase) {
77 AnyInconclusiveBase = true;
78 return false;
79 }
80 return (*hasRefInBase) != nullptr;
81 };
82
83 hasRef = hasRef || R->lookupInBases(hasPublicRefInBase, Paths,
84 /*LookupInDependent =*/true);
85 if (AnyInconclusiveBase)
86 return std::nullopt;
87
88 Paths.clear();
89 const auto hasPublicDerefInBase = [&](const CXXBaseSpecifier *Base,
90 CXXBasePath &) {
91 auto hasDerefInBase = clang::hasPublicMethodInBase(Base, DecMethodName);
92 if (!hasDerefInBase) {
93 AnyInconclusiveBase = true;
94 return false;
95 }
96 return (*hasDerefInBase) != nullptr;
97 };
98 hasDeref = hasDeref || R->lookupInBases(hasPublicDerefInBase, Paths,
99 /*LookupInDependent =*/true);
100 if (AnyInconclusiveBase)
101 return std::nullopt;
102
103 return hasRef && hasDeref;
104}
105
106std::optional<bool> isRefCountable(const clang::CXXRecordDecl *R) {
107 return isSmartPtrCompatible(R, "ref", "deref");
108}
109
110std::optional<bool> isCheckedPtrCapable(const clang::CXXRecordDecl *R) {
111 return isSmartPtrCompatible(R, "incrementCheckedPtrCount",
112 "decrementCheckedPtrCount");
113}
114
115bool isRefType(const std::string &Name) {
116 return Name == "Ref" || Name == "RefAllowingPartiallyDestroyed" ||
117 Name == "RefPtr" || Name == "RefPtrAllowingPartiallyDestroyed";
118}
119
120bool isCheckedPtr(const std::string &Name) {
121 return Name == "CheckedPtr" || Name == "CheckedRef";
122}
123
125 assert(F);
126 const std::string &FunctionName = safeGetName(F);
127
128 return isRefType(FunctionName) || FunctionName == "adoptRef" ||
129 FunctionName == "UniqueRef" || FunctionName == "makeUniqueRef" ||
130 FunctionName == "makeUniqueRefWithoutFastMallocCheck"
131
132 || FunctionName == "String" || FunctionName == "AtomString" ||
133 FunctionName == "UniqueString"
134 // FIXME: Implement as attribute.
135 || FunctionName == "Identifier";
136}
137
139 assert(F);
140 return isCheckedPtr(safeGetName(F));
141}
142
145}
146
147template <typename Predicate>
148static bool isPtrOfType(const clang::QualType T, Predicate Pred) {
149 QualType type = T;
150 while (!type.isNull()) {
151 if (auto *elaboratedT = type->getAs<ElaboratedType>()) {
152 type = elaboratedT->desugar();
153 continue;
154 }
155 auto *SpecialT = type->getAs<TemplateSpecializationType>();
156 if (!SpecialT)
157 return false;
158 auto *Decl = SpecialT->getTemplateName().getAsTemplateDecl();
159 if (!Decl)
160 return false;
161 return Pred(Decl->getNameAsString());
162 }
163 return false;
164}
165
167 return isPtrOfType(
168 T, [](auto Name) { return isRefType(Name) || isCheckedPtr(Name); });
169}
170
172 return isPtrOfType(T, [](auto Name) {
173 return isRefType(Name) || isCheckedPtr(Name) || Name == "unique_ptr" ||
174 Name == "UniqueRef" || Name == "LazyUniqueRef";
175 });
176}
177
178std::optional<bool> isUncounted(const QualType T) {
179 if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T)) {
180 if (auto *Decl = Subst->getAssociatedDecl()) {
182 return false;
183 }
184 }
186}
187
188std::optional<bool> isUnchecked(const QualType T) {
189 if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T)) {
190 if (auto *Decl = Subst->getAssociatedDecl()) {
192 return false;
193 }
194 }
196}
197
198std::optional<bool> isUncounted(const CXXRecordDecl* Class)
199{
200 // Keep isRefCounted first as it's cheaper.
201 if (!Class || isRefCounted(Class))
202 return false;
203
204 std::optional<bool> IsRefCountable = isRefCountable(Class);
205 if (!IsRefCountable)
206 return std::nullopt;
207
208 return (*IsRefCountable);
209}
210
211std::optional<bool> isUnchecked(const CXXRecordDecl *Class) {
212 if (!Class || isCheckedPtr(Class))
213 return false; // Cheaper than below
215}
216
217std::optional<bool> isUncountedPtr(const QualType T) {
218 if (T->isPointerType() || T->isReferenceType()) {
219 if (auto *CXXRD = T->getPointeeCXXRecordDecl())
220 return isUncounted(CXXRD);
221 }
222 return false;
223}
224
225std::optional<bool> isUncheckedPtr(const QualType T) {
226 if (T->isPointerType() || T->isReferenceType()) {
227 if (auto *CXXRD = T->getPointeeCXXRecordDecl())
228 return isUnchecked(CXXRD);
229 }
230 return false;
231}
232
233std::optional<bool> isUnsafePtr(const QualType T) {
234 if (T->isPointerType() || T->isReferenceType()) {
235 if (auto *CXXRD = T->getPointeeCXXRecordDecl()) {
236 auto isUncountedPtr = isUncounted(CXXRD);
237 auto isUncheckedPtr = isUnchecked(CXXRD);
239 return *isUncountedPtr || *isUncheckedPtr;
240 if (isUncountedPtr)
241 return *isUncountedPtr;
242 return isUncheckedPtr;
243 }
244 }
245 return false;
246}
247
248std::optional<bool> isGetterOfSafePtr(const CXXMethodDecl *M) {
249 assert(M);
250
251 if (isa<CXXMethodDecl>(M)) {
252 const CXXRecordDecl *calleeMethodsClass = M->getParent();
253 auto className = safeGetName(calleeMethodsClass);
254 auto method = safeGetName(M);
255
256 if (isCheckedPtr(className) && (method == "get" || method == "ptr"))
257 return true;
258
259 if ((isRefType(className) && (method == "get" || method == "ptr")) ||
260 ((className == "String" || className == "AtomString" ||
261 className == "AtomStringImpl" || className == "UniqueString" ||
262 className == "UniqueStringImpl" || className == "Identifier") &&
263 method == "impl"))
264 return true;
265
266 // Ref<T> -> T conversion
267 // FIXME: Currently allowing any Ref<T> -> whatever cast.
268 if (isRefType(className)) {
269 if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M))
270 return isUnsafePtr(maybeRefToRawOperator->getConversionType());
271 }
272
273 if (isCheckedPtr(className)) {
274 if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M))
275 return isUnsafePtr(maybeRefToRawOperator->getConversionType());
276 }
277 }
278 return false;
279}
280
282 assert(R);
283 if (auto *TmplR = R->getTemplateInstantiationPattern()) {
284 // FIXME: String/AtomString/UniqueString
285 const auto &ClassName = safeGetName(TmplR);
286 return isRefType(ClassName);
287 }
288 return false;
289}
290
292 assert(R);
293 if (auto *TmplR = R->getTemplateInstantiationPattern()) {
294 const auto &ClassName = safeGetName(TmplR);
295 return isCheckedPtr(ClassName);
296 }
297 return false;
298}
299
301 assert(F);
302 if (isCtorOfRefCounted(F))
303 return true;
304
305 // FIXME: check # of params == 1
306 const auto FunctionName = safeGetName(F);
307 if (FunctionName == "getPtr" || FunctionName == "WeakPtr" ||
308 FunctionName == "dynamicDowncast" || FunctionName == "downcast" ||
309 FunctionName == "checkedDowncast" ||
310 FunctionName == "uncheckedDowncast" || FunctionName == "bitwise_cast")
311 return true;
312
313 return false;
314}
315
316bool isSingleton(const FunctionDecl *F) {
317 assert(F);
318 // FIXME: check # of params == 1
319 if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(F)) {
320 if (!MethodDecl->isStatic())
321 return false;
322 }
323 const auto &NameStr = safeGetName(F);
324 StringRef Name = NameStr; // FIXME: Make safeGetName return StringRef.
325 return Name == "singleton" || Name.ends_with("Singleton");
326}
327
328// We only care about statements so let's use the simple
329// (non-recursive) visitor.
331 : public ConstStmtVisitor<TrivialFunctionAnalysisVisitor, bool> {
332
333 // Returns false if at least one child is non-trivial.
334 bool VisitChildren(const Stmt *S) {
335 for (const Stmt *Child : S->children()) {
336 if (Child && !Visit(Child))
337 return false;
338 }
339
340 return true;
341 }
342
343 template <typename StmtOrDecl, typename CheckFunction>
344 bool WithCachedResult(const StmtOrDecl *S, CheckFunction Function) {
345 auto CacheIt = Cache.find(S);
346 if (CacheIt != Cache.end())
347 return CacheIt->second;
348
349 // Treat a recursive statement to be trivial until proven otherwise.
350 auto [RecursiveIt, IsNew] = RecursiveFn.insert(std::make_pair(S, true));
351 if (!IsNew)
352 return RecursiveIt->second;
353
354 bool Result = Function();
355
356 if (!Result) {
357 for (auto &It : RecursiveFn)
358 It.second = false;
359 }
360 RecursiveIt = RecursiveFn.find(S);
361 assert(RecursiveIt != RecursiveFn.end());
362 Result = RecursiveIt->second;
363 RecursiveFn.erase(RecursiveIt);
364 Cache[S] = Result;
365
366 return Result;
367 }
368
369public:
370 using CacheTy = TrivialFunctionAnalysis::CacheTy;
371
373
374 bool IsFunctionTrivial(const Decl *D) {
375 return WithCachedResult(D, [&]() {
376 if (auto *CtorDecl = dyn_cast<CXXConstructorDecl>(D)) {
377 for (auto *CtorInit : CtorDecl->inits()) {
378 if (!Visit(CtorInit->getInit()))
379 return false;
380 }
381 }
382 const Stmt *Body = D->getBody();
383 if (!Body)
384 return false;
385 return Visit(Body);
386 });
387 }
388
389 bool VisitStmt(const Stmt *S) {
390 // All statements are non-trivial unless overriden later.
391 // Don't even recurse into children by default.
392 return false;
393 }
394
396 // A compound statement is allowed as long each individual sub-statement
397 // is trivial.
398 return WithCachedResult(CS, [&]() { return VisitChildren(CS); });
399 }
400
401 bool VisitReturnStmt(const ReturnStmt *RS) {
402 // A return statement is allowed as long as the return value is trivial.
403 if (auto *RV = RS->getRetValue())
404 return Visit(RV);
405 return true;
406 }
407
408 bool VisitDeclStmt(const DeclStmt *DS) { return VisitChildren(DS); }
409 bool VisitDoStmt(const DoStmt *DS) { return VisitChildren(DS); }
410 bool VisitIfStmt(const IfStmt *IS) {
411 return WithCachedResult(IS, [&]() { return VisitChildren(IS); });
412 }
413 bool VisitForStmt(const ForStmt *FS) {
414 return WithCachedResult(FS, [&]() { return VisitChildren(FS); });
415 }
417 return WithCachedResult(FS, [&]() { return VisitChildren(FS); });
418 }
419 bool VisitWhileStmt(const WhileStmt *WS) {
420 return WithCachedResult(WS, [&]() { return VisitChildren(WS); });
421 }
422 bool VisitSwitchStmt(const SwitchStmt *SS) { return VisitChildren(SS); }
423 bool VisitCaseStmt(const CaseStmt *CS) { return VisitChildren(CS); }
424 bool VisitDefaultStmt(const DefaultStmt *DS) { return VisitChildren(DS); }
425
426 // break, continue, goto, and label statements are always trivial.
427 bool VisitBreakStmt(const BreakStmt *) { return true; }
428 bool VisitContinueStmt(const ContinueStmt *) { return true; }
429 bool VisitGotoStmt(const GotoStmt *) { return true; }
430 bool VisitLabelStmt(const LabelStmt *) { return true; }
431
433 // Unary operators are trivial if its operand is trivial except co_await.
434 return UO->getOpcode() != UO_Coawait && Visit(UO->getSubExpr());
435 }
436
438 // Binary operators are trivial if their operands are trivial.
439 return Visit(BO->getLHS()) && Visit(BO->getRHS());
440 }
441
443 // Compound assignment operator such as |= is trivial if its
444 // subexpresssions are trivial.
445 return VisitChildren(CAO);
446 }
447
449 return VisitChildren(ASE);
450 }
451
453 // Ternary operators are trivial if their conditions & values are trivial.
454 return VisitChildren(CO);
455 }
456
457 bool VisitAtomicExpr(const AtomicExpr *E) { return VisitChildren(E); }
458
460 // Any static_assert is considered trivial.
461 return true;
462 }
463
464 bool VisitCallExpr(const CallExpr *CE) {
465 if (!checkArguments(CE))
466 return false;
467
468 auto *Callee = CE->getDirectCallee();
469 if (!Callee)
470 return false;
471 const auto &Name = safeGetName(Callee);
472
473 if (Callee->isInStdNamespace() &&
474 (Name == "addressof" || Name == "forward" || Name == "move"))
475 return true;
476
477 if (Name == "WTFCrashWithInfo" || Name == "WTFBreakpointTrap" ||
478 Name == "WTFReportBacktrace" ||
479 Name == "WTFCrashWithSecurityImplication" || Name == "WTFCrash" ||
480 Name == "WTFReportAssertionFailure" || Name == "isMainThread" ||
481 Name == "isMainThreadOrGCThread" || Name == "isMainRunLoop" ||
482 Name == "isWebThread" || Name == "isUIThread" ||
483 Name == "mayBeGCThread" || Name == "compilerFenceForCrash" ||
484 Name == "bitwise_cast" || Name.find("__builtin") == 0 ||
485 Name == "__libcpp_verbose_abort")
486 return true;
487
488 return IsFunctionTrivial(Callee);
489 }
490
491 bool
493 // Non-type template paramter is compile time constant and trivial.
494 return true;
495 }
496
498 return VisitChildren(E);
499 }
500
502 // A predefined identifier such as "func" is considered trivial.
503 return true;
504 }
505
507 if (!checkArguments(MCE))
508 return false;
509
510 bool TrivialThis = Visit(MCE->getImplicitObjectArgument());
511 if (!TrivialThis)
512 return false;
513
514 auto *Callee = MCE->getMethodDecl();
515 if (!Callee)
516 return false;
517
518 auto Name = safeGetName(Callee);
519 if (Name == "ref" || Name == "incrementCheckedPtrCount")
520 return true;
521
522 std::optional<bool> IsGetterOfRefCounted = isGetterOfSafePtr(Callee);
523 if (IsGetterOfRefCounted && *IsGetterOfRefCounted)
524 return true;
525
526 // Recursively descend into the callee to confirm that it's trivial as well.
527 return IsFunctionTrivial(Callee);
528 }
529
531 if (!checkArguments(OCE))
532 return false;
533 auto *Callee = OCE->getCalleeDecl();
534 if (!Callee)
535 return false;
536 // Recursively descend into the callee to confirm that it's trivial as well.
537 return IsFunctionTrivial(Callee);
538 }
539
541 if (auto *Expr = E->getExpr()) {
542 if (!Visit(Expr))
543 return false;
544 }
545 return true;
546 }
547
548 bool checkArguments(const CallExpr *CE) {
549 for (const Expr *Arg : CE->arguments()) {
550 if (Arg && !Visit(Arg))
551 return false;
552 }
553 return true;
554 }
555
557 for (const Expr *Arg : CE->arguments()) {
558 if (Arg && !Visit(Arg))
559 return false;
560 }
561
562 // Recursively descend into the callee to confirm that it's trivial.
563 return IsFunctionTrivial(CE->getConstructor());
564 }
565
567 return IsFunctionTrivial(E->getConstructor());
568 }
569
570 bool VisitCXXNewExpr(const CXXNewExpr *NE) { return VisitChildren(NE); }
571
573 return Visit(ICE->getSubExpr());
574 }
575
577 return Visit(ECE->getSubExpr());
578 }
579
581 return Visit(VMT->getSubExpr());
582 }
583
585 if (auto *Temp = BTE->getTemporary()) {
586 if (!TrivialFunctionAnalysis::isTrivialImpl(Temp->getDestructor(), Cache))
587 return false;
588 }
589 return Visit(BTE->getSubExpr());
590 }
591
593 return Visit(EWC->getSubExpr());
594 }
595
596 bool VisitParenExpr(const ParenExpr *PE) { return Visit(PE->getSubExpr()); }
597
599 for (const Expr *Child : ILE->inits()) {
600 if (Child && !Visit(Child))
601 return false;
602 }
603 return true;
604 }
605
606 bool VisitMemberExpr(const MemberExpr *ME) {
607 // Field access is allowed but the base pointer may itself be non-trivial.
608 return Visit(ME->getBase());
609 }
610
611 bool VisitCXXThisExpr(const CXXThisExpr *CTE) {
612 // The expression 'this' is always trivial, be it explicit or implicit.
613 return true;
614 }
615
617 // nullptr is trivial.
618 return true;
619 }
620
621 bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
622 // The use of a variable is trivial.
623 return true;
624 }
625
626 // Constant literal expressions are always trivial
627 bool VisitIntegerLiteral(const IntegerLiteral *E) { return true; }
628 bool VisitFloatingLiteral(const FloatingLiteral *E) { return true; }
629 bool VisitFixedPointLiteral(const FixedPointLiteral *E) { return true; }
630 bool VisitCharacterLiteral(const CharacterLiteral *E) { return true; }
631 bool VisitStringLiteral(const StringLiteral *E) { return true; }
632 bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return true; }
633
635 // Constant expressions are trivial.
636 return true;
637 }
638
639private:
640 CacheTy &Cache;
641 CacheTy RecursiveFn;
642};
643
644bool TrivialFunctionAnalysis::isTrivialImpl(
645 const Decl *D, TrivialFunctionAnalysis::CacheTy &Cache) {
647 return V.IsFunctionTrivial(D);
648}
649
650bool TrivialFunctionAnalysis::isTrivialImpl(
651 const Stmt *S, TrivialFunctionAnalysis::CacheTy &Cache) {
653 bool Result = V.Visit(S);
654 assert(Cache.contains(S) && "Top-level statement not properly cached!");
655 return Result;
656}
657
658} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3443
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2718
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6678
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3909
Expr * getLHS() const
Definition: Expr.h:3959
Expr * getRHS() const
Definition: Expr.h:3961
BreakStmt - This represents a break.
Definition: Stmt.h:3007
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1491
CXXTemporary * getTemporary()
Definition: ExprCXX.h:1509
const Expr * getSubExpr() const
Definition: ExprCXX.h:1513
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1546
arg_range arguments()
Definition: ExprCXX.h:1670
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1609
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1268
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1737
Represents a call to a member function that may be written either with member call syntax (e....
Definition: ExprCXX.h:176
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Definition: ExprCXX.cpp:722
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition: ExprCXX.cpp:703
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2078
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2204
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2241
The null pointer literal (C++11 [lex.nullptr])
Definition: ExprCXX.h:765
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:81
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
method_range methods() const
Definition: DeclCXX.h:662
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:565
const CXXRecordDecl * getTemplateInstantiationPattern() const
Retrieve the record declaration from which this record could be instantiated.
Definition: DeclCXX.cpp:2024
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths, bool LookupInDependent=false) const
Look for entities within the base classes of this C++ class, transitively searching all base class su...
bool hasDefinition() const
Definition: DeclCXX.h:572
Represents the this expression in C++.
Definition: ExprCXX.h:1152
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2874
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:3047
arg_range arguments()
Definition: Expr.h:3116
Decl * getCalleeDecl()
Definition: Expr.h:3041
CaseStmt - Represent a case statement.
Definition: Stmt.h:1828
Expr * getSubExpr()
Definition: Expr.h:3597
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4171
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1628
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4262
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:195
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1077
ContinueStmt - This represents a continue.
Definition: Stmt.h:2977
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1265
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1519
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:1076
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2752
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6943
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3799
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3474
This represents one expression.
Definition: Expr.h:110
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2808
const Expr * getSubExpr() const
Definition: Expr.h:1057
Represents a function declaration or definition.
Definition: Decl.h:1935
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2889
IfStmt - This represents an if/then/else.
Definition: Stmt.h:2165
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3724
Describes an C or C++ initializer list.
Definition: Expr.h:5088
ArrayRef< Expr * > inits()
Definition: Expr.h:5128
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2058
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4734
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4751
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3236
Expr * getBase() const
Definition: Expr.h:3313
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2170
const Expr * getSubExpr() const
Definition: Expr.h:2187
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1991
A (possibly-)qualified type.
Definition: Type.h:929
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3046
Expr * getRetValue()
Definition: Stmt.h:3077
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4076
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Definition: StmtVisitor.h:44
Stmt - This represents one statement.
Definition: Stmt.h:84
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1778
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4490
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2415
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6661
bool VisitMemberExpr(const MemberExpr *ME)
bool VisitStringLiteral(const StringLiteral *E)
bool VisitStaticAssertDecl(const StaticAssertDecl *SAD)
bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE)
bool VisitCXXThisExpr(const CXXThisExpr *CTE)
bool VisitUnaryOperator(const UnaryOperator *UO)
bool VisitPredefinedExpr(const PredefinedExpr *E)
bool VisitContinueStmt(const ContinueStmt *)
bool VisitSwitchStmt(const SwitchStmt *SS)
bool VisitCompoundAssignOperator(const CompoundAssignOperator *CAO)
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
bool VisitFixedPointLiteral(const FixedPointLiteral *E)
bool VisitDeclRefExpr(const DeclRefExpr *DRE)
bool VisitIntegerLiteral(const IntegerLiteral *E)
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *VMT)
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E)
bool VisitFloatingLiteral(const FloatingLiteral *E)
TrivialFunctionAnalysis::CacheTy CacheTy
bool VisitConditionalOperator(const ConditionalOperator *CO)
bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
bool VisitCompoundStmt(const CompoundStmt *CS)
bool VisitConstantExpr(const ConstantExpr *CE)
bool VisitImplicitCastExpr(const ImplicitCastExpr *ICE)
bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE)
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E)
bool VisitExprWithCleanups(const ExprWithCleanups *EWC)
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *ASE)
bool VisitCXXNewExpr(const CXXNewExpr *NE)
bool VisitBinaryOperator(const BinaryOperator *BO)
bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE)
bool VisitCXXForRangeStmt(const CXXForRangeStmt *FS)
bool VisitWhileStmt(const WhileStmt *WS)
bool VisitCharacterLiteral(const CharacterLiteral *E)
bool VisitInitListExpr(const InitListExpr *ILE)
bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
bool VisitAtomicExpr(const AtomicExpr *E)
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E)
bool VisitExplicitCastExpr(const ExplicitCastExpr *ECE)
bool VisitParenExpr(const ParenExpr *PE)
bool VisitDefaultStmt(const DefaultStmt *DS)
bool VisitCXXConstructExpr(const CXXConstructExpr *CE)
bool VisitReturnStmt(const ReturnStmt *RS)
The type-property cache.
Definition: Type.cpp:4501
The base class of the type hierarchy.
Definition: Type.h:1828
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1916
bool isPointerType() const
Definition: Type.h:8186
bool isReferenceType() const
Definition: Type.h:8204
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition: Type.cpp:1901
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2622
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2232
Expr * getSubExpr() const
Definition: Expr.h:2277
Opcode getOpcode() const
Definition: Expr.h:2272
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2611
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
bool isCtorOfSafePtr(const clang::FunctionDecl *F)
bool isPtrConversion(const FunctionDecl *F)
std::optional< bool > isCheckedPtrCapable(const clang::CXXRecordDecl *R)
std::optional< bool > isUnchecked(const QualType T)
bool isCtorOfRefCounted(const clang::FunctionDecl *F)
@ Result
The result type of a method or function.
std::optional< bool > isRefCountable(const clang::CXXRecordDecl *R)
std::optional< const clang::CXXRecordDecl * > hasPublicMethodInBase(const CXXBaseSpecifier *Base, StringRef NameToMatch)
bool isSingleton(const FunctionDecl *F)
bool isRefCounted(const CXXRecordDecl *R)
static bool isPtrOfType(const clang::QualType T, Predicate Pred)
std::optional< bool > isSmartPtrCompatible(const CXXRecordDecl *R, StringRef IncMethodName, StringRef DecMethodName)
bool isOwnerPtrType(const clang::QualType T)
bool isSafePtrType(const clang::QualType T)
std::optional< bool > isGetterOfSafePtr(const CXXMethodDecl *M)
bool isRefType(const std::string &Name)
const FunctionProtoType * T
std::optional< bool > isUncountedPtr(const QualType T)
std::string safeGetName(const T *ASTNode)
Definition: ASTUtils.h:81
bool isCtorOfCheckedPtr(const clang::FunctionDecl *F)
bool isCheckedPtr(const std::string &Name)
std::optional< bool > isUnsafePtr(const QualType T)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
std::optional< bool > isUncounted(const QualType T)
@ AS_public
Definition: Specifiers.h:124
std::optional< bool > isUncheckedPtr(const QualType T)