clang 19.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,
23 const char *NameToMatch) {
24 assert(R);
25 assert(R->hasDefinition());
26
27 for (const CXXMethodDecl *MD : R->methods()) {
28 const auto MethodName = safeGetName(MD);
29 if (MethodName == NameToMatch && MD->getAccess() == AS_public)
30 return true;
31 }
32 return false;
33}
34
35} // namespace
36
37namespace clang {
38
39std::optional<const clang::CXXRecordDecl *>
40hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch) {
41 assert(Base);
42
43 const Type *T = Base->getType().getTypePtrOrNull();
44 if (!T)
45 return std::nullopt;
46
48 if (!R)
49 return std::nullopt;
50 if (!R->hasDefinition())
51 return std::nullopt;
52
53 return hasPublicMethodInBaseClass(R, NameToMatch) ? R : nullptr;
54}
55
56std::optional<bool> isRefCountable(const CXXRecordDecl* R)
57{
58 assert(R);
59
60 R = R->getDefinition();
61 if (!R)
62 return std::nullopt;
63
64 bool hasRef = hasPublicMethodInBaseClass(R, "ref");
65 bool hasDeref = hasPublicMethodInBaseClass(R, "deref");
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 =
74 [&AnyInconclusiveBase](const CXXBaseSpecifier *Base, CXXBasePath &) {
75 auto hasRefInBase = clang::hasPublicMethodInBase(Base, "ref");
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 =
90 [&AnyInconclusiveBase](const CXXBaseSpecifier *Base, CXXBasePath &) {
91 auto hasDerefInBase = clang::hasPublicMethodInBase(Base, "deref");
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
106bool isRefType(const std::string &Name) {
107 return Name == "Ref" || Name == "RefAllowingPartiallyDestroyed" ||
108 Name == "RefPtr" || Name == "RefPtrAllowingPartiallyDestroyed";
109}
110
112 assert(F);
113 const std::string &FunctionName = safeGetName(F);
114
115 return isRefType(FunctionName) || FunctionName == "makeRef" ||
116 FunctionName == "makeRefPtr" || FunctionName == "UniqueRef" ||
117 FunctionName == "makeUniqueRef" ||
118 FunctionName == "makeUniqueRefWithoutFastMallocCheck"
119
120 || FunctionName == "String" || FunctionName == "AtomString" ||
121 FunctionName == "UniqueString"
122 // FIXME: Implement as attribute.
123 || FunctionName == "Identifier";
124}
125
127 assert(F);
129 while (!type.isNull()) {
130 if (auto *elaboratedT = type->getAs<ElaboratedType>()) {
131 type = elaboratedT->desugar();
132 continue;
133 }
134 if (auto *specialT = type->getAs<TemplateSpecializationType>()) {
135 if (auto *decl = specialT->getTemplateName().getAsTemplateDecl()) {
136 auto name = decl->getNameAsString();
137 return isRefType(name);
138 }
139 return false;
140 }
141 return false;
142 }
143 return false;
144}
145
146std::optional<bool> isUncounted(const CXXRecordDecl* Class)
147{
148 // Keep isRefCounted first as it's cheaper.
149 if (isRefCounted(Class))
150 return false;
151
152 std::optional<bool> IsRefCountable = isRefCountable(Class);
153 if (!IsRefCountable)
154 return std::nullopt;
155
156 return (*IsRefCountable);
157}
158
159std::optional<bool> isUncountedPtr(const Type* T)
160{
161 assert(T);
162
163 if (T->isPointerType() || T->isReferenceType()) {
164 if (auto *CXXRD = T->getPointeeCXXRecordDecl()) {
165 return isUncounted(CXXRD);
166 }
167 }
168 return false;
169}
170
171std::optional<bool> isGetterOfRefCounted(const CXXMethodDecl* M)
172{
173 assert(M);
174
175 if (isa<CXXMethodDecl>(M)) {
176 const CXXRecordDecl *calleeMethodsClass = M->getParent();
177 auto className = safeGetName(calleeMethodsClass);
178 auto method = safeGetName(M);
179
180 if ((isRefType(className) && (method == "get" || method == "ptr")) ||
181 ((className == "String" || className == "AtomString" ||
182 className == "AtomStringImpl" || className == "UniqueString" ||
183 className == "UniqueStringImpl" || className == "Identifier") &&
184 method == "impl"))
185 return true;
186
187 // Ref<T> -> T conversion
188 // FIXME: Currently allowing any Ref<T> -> whatever cast.
189 if (isRefType(className)) {
190 if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
191 if (auto *targetConversionType =
192 maybeRefToRawOperator->getConversionType().getTypePtrOrNull()) {
193 return isUncountedPtr(targetConversionType);
194 }
195 }
196 }
197 }
198 return false;
199}
200
202 assert(R);
203 if (auto *TmplR = R->getTemplateInstantiationPattern()) {
204 // FIXME: String/AtomString/UniqueString
205 const auto &ClassName = safeGetName(TmplR);
206 return isRefType(ClassName);
207 }
208 return false;
209}
210
212 assert(F);
213 if (isCtorOfRefCounted(F))
214 return true;
215
216 // FIXME: check # of params == 1
217 const auto FunctionName = safeGetName(F);
218 if (FunctionName == "getPtr" || FunctionName == "WeakPtr" ||
219 FunctionName == "dynamicDowncast" || FunctionName == "downcast" ||
220 FunctionName == "checkedDowncast" ||
221 FunctionName == "uncheckedDowncast" || FunctionName == "bitwise_cast")
222 return true;
223
224 return false;
225}
226
227bool isSingleton(const FunctionDecl *F) {
228 assert(F);
229 // FIXME: check # of params == 1
230 if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(F)) {
231 if (!MethodDecl->isStatic())
232 return false;
233 }
234 const auto &Name = safeGetName(F);
235 std::string SingletonStr = "singleton";
236 auto index = Name.find(SingletonStr);
237 return index != std::string::npos &&
238 index == Name.size() - SingletonStr.size();
239}
240
241// We only care about statements so let's use the simple
242// (non-recursive) visitor.
244 : public ConstStmtVisitor<TrivialFunctionAnalysisVisitor, bool> {
245
246 // Returns false if at least one child is non-trivial.
247 bool VisitChildren(const Stmt *S) {
248 for (const Stmt *Child : S->children()) {
249 if (Child && !Visit(Child))
250 return false;
251 }
252
253 return true;
254 }
255
256 template <typename CheckFunction>
257 bool WithCachedResult(const Stmt *S, CheckFunction Function) {
258 // If the statement isn't in the cache, conservatively assume that
259 // it's not trivial until analysis completes. Insert false to the cache
260 // first to avoid infinite recursion.
261 auto [It, IsNew] = Cache.insert(std::make_pair(S, false));
262 if (!IsNew)
263 return It->second;
264 bool Result = Function();
265 Cache[S] = Result;
266 return Result;
267 }
268
269public:
270 using CacheTy = TrivialFunctionAnalysis::CacheTy;
271
273
274 bool VisitStmt(const Stmt *S) {
275 // All statements are non-trivial unless overriden later.
276 // Don't even recurse into children by default.
277 return false;
278 }
279
281 // A compound statement is allowed as long each individual sub-statement
282 // is trivial.
283 return WithCachedResult(CS, [&]() { return VisitChildren(CS); });
284 }
285
286 bool VisitReturnStmt(const ReturnStmt *RS) {
287 // A return statement is allowed as long as the return value is trivial.
288 if (auto *RV = RS->getRetValue())
289 return Visit(RV);
290 return true;
291 }
292
293 bool VisitDeclStmt(const DeclStmt *DS) { return VisitChildren(DS); }
294 bool VisitDoStmt(const DoStmt *DS) { return VisitChildren(DS); }
295 bool VisitIfStmt(const IfStmt *IS) {
296 return WithCachedResult(IS, [&]() { return VisitChildren(IS); });
297 }
298 bool VisitForStmt(const ForStmt *FS) {
299 return WithCachedResult(FS, [&]() { return VisitChildren(FS); });
300 }
302 return WithCachedResult(FS, [&]() { return VisitChildren(FS); });
303 }
304 bool VisitWhileStmt(const WhileStmt *WS) {
305 return WithCachedResult(WS, [&]() { return VisitChildren(WS); });
306 }
307 bool VisitSwitchStmt(const SwitchStmt *SS) { return VisitChildren(SS); }
308 bool VisitCaseStmt(const CaseStmt *CS) { return VisitChildren(CS); }
309 bool VisitDefaultStmt(const DefaultStmt *DS) { return VisitChildren(DS); }
310
311 // break, continue, goto, and label statements are always trivial.
312 bool VisitBreakStmt(const BreakStmt *) { return true; }
313 bool VisitContinueStmt(const ContinueStmt *) { return true; }
314 bool VisitGotoStmt(const GotoStmt *) { return true; }
315 bool VisitLabelStmt(const LabelStmt *) { return true; }
316
318 // Unary operators are trivial if its operand is trivial except co_await.
319 return UO->getOpcode() != UO_Coawait && Visit(UO->getSubExpr());
320 }
321
323 // Binary operators are trivial if their operands are trivial.
324 return Visit(BO->getLHS()) && Visit(BO->getRHS());
325 }
326
328 // Compound assignment operator such as |= is trivial if its
329 // subexpresssions are trivial.
330 return VisitChildren(CAO);
331 }
332
334 return VisitChildren(ASE);
335 }
336
338 // Ternary operators are trivial if their conditions & values are trivial.
339 return VisitChildren(CO);
340 }
341
342 bool VisitAtomicExpr(const AtomicExpr *E) { return VisitChildren(E); }
343
345 // Any static_assert is considered trivial.
346 return true;
347 }
348
349 bool VisitCallExpr(const CallExpr *CE) {
350 if (!checkArguments(CE))
351 return false;
352
353 auto *Callee = CE->getDirectCallee();
354 if (!Callee)
355 return false;
356 const auto &Name = safeGetName(Callee);
357
358 if (Callee->isInStdNamespace() &&
359 (Name == "addressof" || Name == "forward" || Name == "move"))
360 return true;
361
362 if (Name == "WTFCrashWithInfo" || Name == "WTFBreakpointTrap" ||
363 Name == "WTFCrashWithSecurityImplication" || Name == "WTFCrash" ||
364 Name == "WTFReportAssertionFailure" || Name == "isMainThread" ||
365 Name == "isMainThreadOrGCThread" || Name == "isMainRunLoop" ||
366 Name == "isWebThread" || Name == "isUIThread" ||
367 Name == "mayBeGCThread" || Name == "compilerFenceForCrash" ||
368 Name == "bitwise_cast" || Name.find("__builtin") == 0)
369 return true;
370
371 return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache);
372 }
373
374 bool
376 // Non-type template paramter is compile time constant and trivial.
377 return true;
378 }
379
381 return VisitChildren(E);
382 }
383
385 // A predefined identifier such as "func" is considered trivial.
386 return true;
387 }
388
390 if (!checkArguments(MCE))
391 return false;
392
393 bool TrivialThis = Visit(MCE->getImplicitObjectArgument());
394 if (!TrivialThis)
395 return false;
396
397 auto *Callee = MCE->getMethodDecl();
398 if (!Callee)
399 return false;
400
401 std::optional<bool> IsGetterOfRefCounted = isGetterOfRefCounted(Callee);
402 if (IsGetterOfRefCounted && *IsGetterOfRefCounted)
403 return true;
404
405 // Recursively descend into the callee to confirm that it's trivial as well.
406 return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache);
407 }
408
410 if (!checkArguments(OCE))
411 return false;
412 auto *Callee = OCE->getCalleeDecl();
413 if (!Callee)
414 return false;
415 // Recursively descend into the callee to confirm that it's trivial as well.
416 return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache);
417 }
418
420 if (auto *Expr = E->getExpr()) {
421 if (!Visit(Expr))
422 return false;
423 }
424 return true;
425 }
426
427 bool checkArguments(const CallExpr *CE) {
428 for (const Expr *Arg : CE->arguments()) {
429 if (Arg && !Visit(Arg))
430 return false;
431 }
432 return true;
433 }
434
436 for (const Expr *Arg : CE->arguments()) {
437 if (Arg && !Visit(Arg))
438 return false;
439 }
440
441 // Recursively descend into the callee to confirm that it's trivial.
442 return TrivialFunctionAnalysis::isTrivialImpl(CE->getConstructor(), Cache);
443 }
444
445 bool VisitCXXNewExpr(const CXXNewExpr *NE) { return VisitChildren(NE); }
446
448 return Visit(ICE->getSubExpr());
449 }
450
452 return Visit(ECE->getSubExpr());
453 }
454
456 return Visit(VMT->getSubExpr());
457 }
458
460 if (auto *Temp = BTE->getTemporary()) {
461 if (!TrivialFunctionAnalysis::isTrivialImpl(Temp->getDestructor(), Cache))
462 return false;
463 }
464 return Visit(BTE->getSubExpr());
465 }
466
468 return Visit(EWC->getSubExpr());
469 }
470
471 bool VisitParenExpr(const ParenExpr *PE) { return Visit(PE->getSubExpr()); }
472
474 for (const Expr *Child : ILE->inits()) {
475 if (Child && !Visit(Child))
476 return false;
477 }
478 return true;
479 }
480
481 bool VisitMemberExpr(const MemberExpr *ME) {
482 // Field access is allowed but the base pointer may itself be non-trivial.
483 return Visit(ME->getBase());
484 }
485
486 bool VisitCXXThisExpr(const CXXThisExpr *CTE) {
487 // The expression 'this' is always trivial, be it explicit or implicit.
488 return true;
489 }
490
492 // nullptr is trivial.
493 return true;
494 }
495
496 bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
497 // The use of a variable is trivial.
498 return true;
499 }
500
501 // Constant literal expressions are always trivial
502 bool VisitIntegerLiteral(const IntegerLiteral *E) { return true; }
503 bool VisitFloatingLiteral(const FloatingLiteral *E) { return true; }
504 bool VisitFixedPointLiteral(const FixedPointLiteral *E) { return true; }
505 bool VisitCharacterLiteral(const CharacterLiteral *E) { return true; }
506 bool VisitStringLiteral(const StringLiteral *E) { return true; }
507 bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return true; }
508
510 // Constant expressions are trivial.
511 return true;
512 }
513
514private:
515 CacheTy &Cache;
516};
517
518bool TrivialFunctionAnalysis::isTrivialImpl(
519 const Decl *D, TrivialFunctionAnalysis::CacheTy &Cache) {
520 // If the function isn't in the cache, conservatively assume that
521 // it's not trivial until analysis completes. This makes every recursive
522 // function non-trivial. This also guarantees that each function
523 // will be scanned at most once.
524 auto [It, IsNew] = Cache.insert(std::make_pair(D, false));
525 if (!IsNew)
526 return It->second;
527
529
530 if (auto *CtorDecl = dyn_cast<CXXConstructorDecl>(D)) {
531 for (auto *CtorInit : CtorDecl->inits()) {
532 if (!V.Visit(CtorInit->getInit()))
533 return false;
534 }
535 }
536
537 const Stmt *Body = D->getBody();
538 if (!Body)
539 return false;
540
541 bool Result = V.Visit(Body);
542 if (Result)
543 Cache[D] = true;
544
545 return Result;
546}
547
548bool TrivialFunctionAnalysis::isTrivialImpl(
549 const Stmt *S, TrivialFunctionAnalysis::CacheTy &Cache) {
550 // If the statement isn't in the cache, conservatively assume that
551 // it's not trivial until analysis completes. Unlike a function case,
552 // we don't insert an entry into the cache until Visit returns
553 // since Visit* functions themselves make use of the cache.
554
556 bool Result = V.Visit(S);
557 assert(Cache.contains(S) && "Top-level statement not properly cached!");
558 return Result;
559}
560
561} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3285
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:2664
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6437
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3840
Expr * getLHS() const
Definition: Expr.h:3889
Expr * getRHS() const
Definition: Expr.h:3891
BreakStmt - This represents a break.
Definition: Stmt.h:2980
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:1487
CXXTemporary * getTemporary()
Definition: ExprCXX.h:1505
const Expr * getSubExpr() const
Definition: ExprCXX.h:1509
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:720
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1542
arg_range arguments()
Definition: ExprCXX.h:1666
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1605
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1264
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition: StmtCXX.h:135
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:673
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition: ExprCXX.cpp:654
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2186
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2236
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:661
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:564
const CXXRecordDecl * getTemplateInstantiationPattern() const
Retrieve the record declaration from which this record could be instantiated.
Definition: DeclCXX.cpp:1930
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:571
Represents the this expression in C++.
Definition: ExprCXX.h:1148
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2820
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:2990
arg_range arguments()
Definition: Expr.h:3059
Decl * getCalleeDecl()
Definition: Expr.h:2984
CaseStmt - Represent a case statement.
Definition: Stmt.h:1801
Expr * getSubExpr()
Definition: Expr.h:3533
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4088
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1606
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4179
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:1072
ContinueStmt - This represents a continue.
Definition: Stmt.h:2950
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1497
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:1077
DoStmt - This represents a 'do/while' stmt.
Definition: Stmt.h:2725
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6371
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3730
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3467
This represents one expression.
Definition: Expr.h:110
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition: Stmt.h:2781
const Expr * getSubExpr() const
Definition: Expr.h:1052
Represents a function declaration or definition.
Definition: Decl.h:1971
QualType getReturnType() const
Definition: Decl.h:2754
GotoStmt - This represents a direct goto.
Definition: Stmt.h:2862
IfStmt - This represents an if/then/else.
Definition: Stmt.h:2138
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3655
Describes an C or C++ initializer list.
Definition: Expr.h:4847
ArrayRef< Expr * > inits()
Definition: Expr.h:4887
LabelStmt - Represents a label, which has a substatement.
Definition: Stmt.h:2031
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4710
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4727
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3172
Expr * getBase() const
Definition: Expr.h:3249
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2130
const Expr * getSubExpr() const
Definition: Expr.h:2145
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:1986
A (possibly-)qualified type.
Definition: Type.h:940
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition: Stmt.h:3019
Expr * getRetValue()
Definition: Stmt.h:3050
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4058
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:1773
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4466
SwitchStmt - This represents a 'switch' stmt.
Definition: Stmt.h:2388
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6089
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 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:4376
The base class of the type hierarchy.
Definition: Type.h:1813
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1871
bool isPointerType() const
Definition: Type.h:7612
bool isReferenceType() const
Definition: Type.h:7624
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:1856
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2568
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2183
Expr * getSubExpr() const
Definition: Expr.h:2228
Opcode getOpcode() const
Definition: Expr.h:2223
WhileStmt - This represents a 'while' stmt.
Definition: Stmt.h:2584
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
std::optional< bool > isGetterOfRefCounted(const CXXMethodDecl *M)
std::optional< bool > isUncountedPtr(const Type *T)
bool isPtrConversion(const FunctionDecl *F)
bool isCtorOfRefCounted(const clang::FunctionDecl *F)
std::optional< bool > isUncounted(const CXXRecordDecl *Class)
std::optional< const clang::CXXRecordDecl * > hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch)
std::optional< bool > isRefCountable(const CXXRecordDecl *R)
@ Result
The result type of a method or function.
bool isSingleton(const FunctionDecl *F)
bool isRefCounted(const CXXRecordDecl *R)
bool isReturnValueRefCounted(const clang::FunctionDecl *F)
bool isRefType(const std::string &Name)
const FunctionProtoType * T
std::string safeGetName(const T *ASTNode)
Definition: ASTUtils.h:68
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ AS_public
Definition: Specifiers.h:121