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"
15 #include "clang/AST/StmtVisitor.h"
16 #include <optional>
17 
18 using namespace clang;
19 
20 namespace {
21 
22 bool 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 
37 namespace clang {
38 
39 std::optional<const clang::CXXRecordDecl *>
40 hasPublicMethodInBase(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 
47  const CXXRecordDecl *R = T->getAsCXXRecordDecl();
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 
56 std::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 
106 bool 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);
128  QualType type = F->getReturnType();
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 
146 std::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 
159 std::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 
171 std::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 
201 bool isRefCounted(const CXXRecordDecl *R) {
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 
227 bool 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 
269 public:
270  using CacheTy = TrivialFunctionAnalysis::CacheTy;
271 
273 
274  bool IsFunctionTrivial(const Decl *D) {
275  auto CacheIt = Cache.find(D);
276  if (CacheIt != Cache.end())
277  return CacheIt->second;
278 
279  // Treat a recursive function call to be trivial until proven otherwise.
280  auto [RecursiveIt, IsNew] = RecursiveFn.insert(std::make_pair(D, true));
281  if (!IsNew)
282  return RecursiveIt->second;
283 
284  bool Result = [&]() {
285  if (auto *CtorDecl = dyn_cast<CXXConstructorDecl>(D)) {
286  for (auto *CtorInit : CtorDecl->inits()) {
287  if (!Visit(CtorInit->getInit()))
288  return false;
289  }
290  }
291  const Stmt *Body = D->getBody();
292  if (!Body)
293  return false;
294  return Visit(Body);
295  }();
296 
297  if (!Result) {
298  // D and its mutually recursive callers are all non-trivial.
299  for (auto &It : RecursiveFn)
300  It.second = false;
301  }
302  RecursiveIt = RecursiveFn.find(D);
303  assert(RecursiveIt != RecursiveFn.end());
304  Result = RecursiveIt->second;
305  RecursiveFn.erase(RecursiveIt);
306  Cache[D] = Result;
307 
308  return Result;
309  }
310 
311  bool VisitStmt(const Stmt *S) {
312  // All statements are non-trivial unless overriden later.
313  // Don't even recurse into children by default.
314  return false;
315  }
316 
317  bool VisitCompoundStmt(const CompoundStmt *CS) {
318  // A compound statement is allowed as long each individual sub-statement
319  // is trivial.
320  return WithCachedResult(CS, [&]() { return VisitChildren(CS); });
321  }
322 
323  bool VisitReturnStmt(const ReturnStmt *RS) {
324  // A return statement is allowed as long as the return value is trivial.
325  if (auto *RV = RS->getRetValue())
326  return Visit(RV);
327  return true;
328  }
329 
330  bool VisitDeclStmt(const DeclStmt *DS) { return VisitChildren(DS); }
331  bool VisitDoStmt(const DoStmt *DS) { return VisitChildren(DS); }
332  bool VisitIfStmt(const IfStmt *IS) {
333  return WithCachedResult(IS, [&]() { return VisitChildren(IS); });
334  }
335  bool VisitForStmt(const ForStmt *FS) {
336  return WithCachedResult(FS, [&]() { return VisitChildren(FS); });
337  }
339  return WithCachedResult(FS, [&]() { return VisitChildren(FS); });
340  }
341  bool VisitWhileStmt(const WhileStmt *WS) {
342  return WithCachedResult(WS, [&]() { return VisitChildren(WS); });
343  }
344  bool VisitSwitchStmt(const SwitchStmt *SS) { return VisitChildren(SS); }
345  bool VisitCaseStmt(const CaseStmt *CS) { return VisitChildren(CS); }
346  bool VisitDefaultStmt(const DefaultStmt *DS) { return VisitChildren(DS); }
347 
348  // break, continue, goto, and label statements are always trivial.
349  bool VisitBreakStmt(const BreakStmt *) { return true; }
350  bool VisitContinueStmt(const ContinueStmt *) { return true; }
351  bool VisitGotoStmt(const GotoStmt *) { return true; }
352  bool VisitLabelStmt(const LabelStmt *) { return true; }
353 
355  // Unary operators are trivial if its operand is trivial except co_await.
356  return UO->getOpcode() != UO_Coawait && Visit(UO->getSubExpr());
357  }
358 
360  // Binary operators are trivial if their operands are trivial.
361  return Visit(BO->getLHS()) && Visit(BO->getRHS());
362  }
363 
365  // Compound assignment operator such as |= is trivial if its
366  // subexpresssions are trivial.
367  return VisitChildren(CAO);
368  }
369 
371  return VisitChildren(ASE);
372  }
373 
375  // Ternary operators are trivial if their conditions & values are trivial.
376  return VisitChildren(CO);
377  }
378 
379  bool VisitAtomicExpr(const AtomicExpr *E) { return VisitChildren(E); }
380 
382  // Any static_assert is considered trivial.
383  return true;
384  }
385 
386  bool VisitCallExpr(const CallExpr *CE) {
387  if (!checkArguments(CE))
388  return false;
389 
390  auto *Callee = CE->getDirectCallee();
391  if (!Callee)
392  return false;
393  const auto &Name = safeGetName(Callee);
394 
395  if (Callee->isInStdNamespace() &&
396  (Name == "addressof" || Name == "forward" || Name == "move"))
397  return true;
398 
399  if (Name == "WTFCrashWithInfo" || Name == "WTFBreakpointTrap" ||
400  Name == "WTFCrashWithSecurityImplication" || Name == "WTFCrash" ||
401  Name == "WTFReportAssertionFailure" || Name == "isMainThread" ||
402  Name == "isMainThreadOrGCThread" || Name == "isMainRunLoop" ||
403  Name == "isWebThread" || Name == "isUIThread" ||
404  Name == "mayBeGCThread" || Name == "compilerFenceForCrash" ||
405  Name == "bitwise_cast" || Name.find("__builtin") == 0)
406  return true;
407 
408  return IsFunctionTrivial(Callee);
409  }
410 
411  bool
413  // Non-type template paramter is compile time constant and trivial.
414  return true;
415  }
416 
418  return VisitChildren(E);
419  }
420 
422  // A predefined identifier such as "func" is considered trivial.
423  return true;
424  }
425 
427  if (!checkArguments(MCE))
428  return false;
429 
430  bool TrivialThis = Visit(MCE->getImplicitObjectArgument());
431  if (!TrivialThis)
432  return false;
433 
434  auto *Callee = MCE->getMethodDecl();
435  if (!Callee)
436  return false;
437 
438  std::optional<bool> IsGetterOfRefCounted = isGetterOfRefCounted(Callee);
439  if (IsGetterOfRefCounted && *IsGetterOfRefCounted)
440  return true;
441 
442  // Recursively descend into the callee to confirm that it's trivial as well.
443  return IsFunctionTrivial(Callee);
444  }
445 
447  if (!checkArguments(OCE))
448  return false;
449  auto *Callee = OCE->getCalleeDecl();
450  if (!Callee)
451  return false;
452  // Recursively descend into the callee to confirm that it's trivial as well.
453  return IsFunctionTrivial(Callee);
454  }
455 
457  if (auto *Expr = E->getExpr()) {
458  if (!Visit(Expr))
459  return false;
460  }
461  return true;
462  }
463 
464  bool checkArguments(const CallExpr *CE) {
465  for (const Expr *Arg : CE->arguments()) {
466  if (Arg && !Visit(Arg))
467  return false;
468  }
469  return true;
470  }
471 
473  for (const Expr *Arg : CE->arguments()) {
474  if (Arg && !Visit(Arg))
475  return false;
476  }
477 
478  // Recursively descend into the callee to confirm that it's trivial.
479  return IsFunctionTrivial(CE->getConstructor());
480  }
481 
482  bool VisitCXXNewExpr(const CXXNewExpr *NE) { return VisitChildren(NE); }
483 
485  return Visit(ICE->getSubExpr());
486  }
487 
489  return Visit(ECE->getSubExpr());
490  }
491 
493  return Visit(VMT->getSubExpr());
494  }
495 
497  if (auto *Temp = BTE->getTemporary()) {
498  if (!TrivialFunctionAnalysis::isTrivialImpl(Temp->getDestructor(), Cache))
499  return false;
500  }
501  return Visit(BTE->getSubExpr());
502  }
503 
505  return Visit(EWC->getSubExpr());
506  }
507 
508  bool VisitParenExpr(const ParenExpr *PE) { return Visit(PE->getSubExpr()); }
509 
510  bool VisitInitListExpr(const InitListExpr *ILE) {
511  for (const Expr *Child : ILE->inits()) {
512  if (Child && !Visit(Child))
513  return false;
514  }
515  return true;
516  }
517 
518  bool VisitMemberExpr(const MemberExpr *ME) {
519  // Field access is allowed but the base pointer may itself be non-trivial.
520  return Visit(ME->getBase());
521  }
522 
523  bool VisitCXXThisExpr(const CXXThisExpr *CTE) {
524  // The expression 'this' is always trivial, be it explicit or implicit.
525  return true;
526  }
527 
529  // nullptr is trivial.
530  return true;
531  }
532 
533  bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
534  // The use of a variable is trivial.
535  return true;
536  }
537 
538  // Constant literal expressions are always trivial
539  bool VisitIntegerLiteral(const IntegerLiteral *E) { return true; }
540  bool VisitFloatingLiteral(const FloatingLiteral *E) { return true; }
541  bool VisitFixedPointLiteral(const FixedPointLiteral *E) { return true; }
542  bool VisitCharacterLiteral(const CharacterLiteral *E) { return true; }
543  bool VisitStringLiteral(const StringLiteral *E) { return true; }
544  bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return true; }
545 
546  bool VisitConstantExpr(const ConstantExpr *CE) {
547  // Constant expressions are trivial.
548  return true;
549  }
550 
551 private:
552  CacheTy &Cache;
553  CacheTy RecursiveFn;
554 };
555 
556 bool TrivialFunctionAnalysis::isTrivialImpl(
557  const Decl *D, TrivialFunctionAnalysis::CacheTy &Cache) {
559  return V.IsFunctionTrivial(D);
560 }
561 
562 bool TrivialFunctionAnalysis::isTrivialImpl(
563  const Stmt *S, TrivialFunctionAnalysis::CacheTy &Cache) {
564  // If the statement isn't in the cache, conservatively assume that
565  // it's not trivial until analysis completes. Unlike a function case,
566  // we don't insert an entry into the cache until Visit returns
567  // since Visit* functions themselves make use of the cache.
568 
570  bool Result = V.Visit(S);
571  assert(Cache.contains(S) && "Top-level statement not properly cached!");
572  return Result;
573 }
574 
575 } // namespace clang
#define V(N, I)
Definition: ASTContext.h:3299
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:2716
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6478
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3892
Expr * getRHS() const
Definition: Expr.h:3943
Expr * getLHS() const
Definition: Expr.h:3941
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
const Expr * getSubExpr() const
Definition: ExprCXX.h:1509
CXXTemporary * getTemporary()
Definition: ExprCXX.h:1505
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
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
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:564
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:2872
arg_range arguments()
Definition: Expr.h:3111
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:3042
Decl * getCalleeDecl()
Definition: Expr.h:3036
CaseStmt - Represent a case statement.
Definition: Stmt.h:1801
Expr * getSubExpr()
Definition: Expr.h:3585
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4140
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1606
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:4231
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:6383
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3782
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:1972
QualType getReturnType() const
Definition: Decl.h:2757
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:3707
Describes an C or C++ initializer list.
Definition: Expr.h:4888
ArrayRef< Expr * > inits()
Definition: Expr.h:4928
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:4721
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4738
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3224
Expr * getBase() const
Definition: Expr.h:3301
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2182
const Expr * getSubExpr() const
Definition: Expr.h:2197
[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:4477
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:6101
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:4392
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:1881
bool isPointerType() const
Definition: Type.h:7624
bool isReferenceType() const
Definition: Type.h:7636
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:1866
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2620
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2235
Opcode getOpcode() const
Definition: Expr.h:2275
Expr * getSubExpr() const
Definition: Expr.h:2280
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.
bool NE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:869
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
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)
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