Clang Project

clang_source_code/lib/Analysis/BodyFarm.cpp
1//== BodyFarm.cpp  - Factory for conjuring up fake bodies ----------*- 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// BodyFarm is a factory for creating faux implementations for functions/methods
10// for analysis purposes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Analysis/BodyFarm.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/CXXInheritance.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/ExprCXX.h"
20#include "clang/AST/ExprObjC.h"
21#include "clang/AST/NestedNameSpecifier.h"
22#include "clang/Analysis/CodeInjector.h"
23#include "clang/Basic/OperatorKinds.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/Support/Debug.h"
26
27#define DEBUG_TYPE "body-farm"
28
29using namespace clang;
30
31//===----------------------------------------------------------------------===//
32// Helper creation functions for constructing faux ASTs.
33//===----------------------------------------------------------------------===//
34
35static bool isDispatchBlock(QualType Ty) {
36  // Is it a block pointer?
37  const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
38  if (!BPT)
39    return false;
40
41  // Check if the block pointer type takes no arguments and
42  // returns void.
43  const FunctionProtoType *FT =
44  BPT->getPointeeType()->getAs<FunctionProtoType>();
45  return FT && FT->getReturnType()->isVoidType() && FT->getNumParams() == 0;
46}
47
48namespace {
49class ASTMaker {
50public:
51  ASTMaker(ASTContext &C) : C(C) {}
52
53  /// Create a new BinaryOperator representing a simple assignment.
54  BinaryOperator *makeAssignment(const Expr *LHSconst Expr *RHSQualType Ty);
55
56  /// Create a new BinaryOperator representing a comparison.
57  BinaryOperator *makeComparison(const Expr *LHSconst Expr *RHS,
58                                 BinaryOperator::Opcode Op);
59
60  /// Create a new compound stmt using the provided statements.
61  CompoundStmt *makeCompound(ArrayRef<Stmt*>);
62
63  /// Create a new DeclRefExpr for the referenced variable.
64  DeclRefExpr *makeDeclRefExpr(const VarDecl *D,
65                               bool RefersToEnclosingVariableOrCapture = false);
66
67  /// Create a new UnaryOperator representing a dereference.
68  UnaryOperator *makeDereference(const Expr *ArgQualType Ty);
69
70  /// Create an implicit cast for an integer conversion.
71  Expr *makeIntegralCast(const Expr *ArgQualType Ty);
72
73  /// Create an implicit cast to a builtin boolean type.
74  ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
75
76  /// Create an implicit cast for lvalue-to-rvaluate conversions.
77  ImplicitCastExpr *makeLvalueToRvalue(const Expr *ArgQualType Ty);
78
79  /// Make RValue out of variable declaration, creating a temporary
80  /// DeclRefExpr in the process.
81  ImplicitCastExpr *
82  makeLvalueToRvalue(const VarDecl *Decl,
83                     bool RefersToEnclosingVariableOrCapture = false);
84
85  /// Create an implicit cast of the given type.
86  ImplicitCastExpr *makeImplicitCast(const Expr *ArgQualType Ty,
87                                     CastKind CK = CK_LValueToRValue);
88
89  /// Create an Objective-C bool literal.
90  ObjCBoolLiteralExpr *makeObjCBool(bool Val);
91
92  /// Create an Objective-C ivar reference.
93  ObjCIvarRefExpr *makeObjCIvarRef(const Expr *Baseconst ObjCIvarDecl *IVar);
94
95  /// Create a Return statement.
96  ReturnStmt *makeReturn(const Expr *RetVal);
97
98  /// Create an integer literal expression of the given type.
99  IntegerLiteral *makeIntegerLiteral(uint64_t ValueQualType Ty);
100
101  /// Create a member expression.
102  MemberExpr *makeMemberExpression(Expr *baseValueDecl *MemberDecl,
103                                   bool IsArrow = false,
104                                   ExprValueKind ValueKind = VK_LValue);
105
106  /// Returns a *first* member field of a record declaration with a given name.
107  /// \return an nullptr if no member with such a name exists.
108  ValueDecl *findMemberField(const RecordDecl *RDStringRef Name);
109
110private:
111  ASTContext &C;
112};
113}
114
115BinaryOperator *ASTMaker::makeAssignment(const Expr *LHSconst Expr *RHS,
116                                         QualType Ty) {
117 return new (CBinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
118                               BO_AssignTyVK_RValue,
119                               OK_OrdinarySourceLocation(), FPOptions());
120}
121
122BinaryOperator *ASTMaker::makeComparison(const Expr *LHSconst Expr *RHS,
123                                         BinaryOperator::Opcode Op) {
124  assert(BinaryOperator::isLogicalOp(Op) ||
125         BinaryOperator::isComparisonOp(Op));
126  return new (CBinaryOperator(const_cast<Expr*>(LHS),
127                                const_cast<Expr*>(RHS),
128                                Op,
129                                C.getLogicalOperationType(),
130                                VK_RValue,
131                                OK_OrdinarySourceLocation(), FPOptions());
132}
133
134CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
135  return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation());
136}
137
138DeclRefExpr *ASTMaker::makeDeclRefExpr(
139    const VarDecl *D,
140    bool RefersToEnclosingVariableOrCapture) {
141  QualType Type = D->getType().getNonReferenceType();
142
143  DeclRefExpr *DR = DeclRefExpr::Create(
144      CNestedNameSpecifierLoc(), SourceLocation(), const_cast<VarDecl *>(D),
145      RefersToEnclosingVariableOrCaptureSourceLocation(), TypeVK_LValue);
146  return DR;
147}
148
149UnaryOperator *ASTMaker::makeDereference(const Expr *ArgQualType Ty) {
150  return new (CUnaryOperator(const_cast<Expr*>(Arg), UO_DerefTy,
151                               VK_LValueOK_OrdinarySourceLocation(),
152                              /*CanOverflow*/ false);
153}
154
155ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *ArgQualType Ty) {
156  return makeImplicitCast(ArgTyCK_LValueToRValue);
157}
158
159ImplicitCastExpr *
160ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
161                             bool RefersToEnclosingVariableOrCapture) {
162  QualType Type = Arg->getType().getNonReferenceType();
163  return makeLvalueToRvalue(makeDeclRefExpr(Arg,
164                                            RefersToEnclosingVariableOrCapture),
165                            Type);
166}
167
168ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *ArgQualType Ty,
169                                             CastKind CK) {
170  return ImplicitCastExpr::Create(CTy,
171                                  /* CastKind=*/ CK,
172                                  /* Expr=*/ const_cast<Expr *>(Arg),
173                                  /* CXXCastPath=*/ nullptr,
174                                  /* ExprValueKind=*/ VK_RValue);
175}
176
177Expr *ASTMaker::makeIntegralCast(const Expr *ArgQualType Ty) {
178  if (Arg->getType() == Ty)
179    return const_cast<Expr*>(Arg);
180
181  return ImplicitCastExpr::Create(CTyCK_IntegralCast,
182                                  const_cast<Expr*>(Arg), nullptrVK_RValue);
183}
184
185ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
186  return ImplicitCastExpr::Create(CC.BoolTyCK_IntegralToBoolean,
187                                  const_cast<Expr*>(Arg), nullptrVK_RValue);
188}
189
190ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
191  QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
192  return new (CObjCBoolLiteralExpr(ValTySourceLocation());
193}
194
195ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
196                                           const ObjCIvarDecl *IVar) {
197  return new (CObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
198                                 IVar->getType(), SourceLocation(),
199                                 SourceLocation(), const_cast<Expr*>(Base),
200                                 /*arrow=*/true/*free=*/false);
201}
202
203ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
204  return ReturnStmt::Create(CSourceLocation(), const_cast<Expr *>(RetVal),
205                            /* NRVOCandidate=*/nullptr);
206}
207
208IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t ValueQualType Ty) {
209  llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
210  return IntegerLiteral::Create(C, APValue, Ty, SourceLocation());
211}
212
213MemberExpr *ASTMaker::makeMemberExpression(Expr *baseValueDecl *MemberDecl,
214                                           bool IsArrow,
215                                           ExprValueKind ValueKind) {
216
217  DeclAccessPair FoundDecl = DeclAccessPair::make(MemberDeclAS_public);
218  return MemberExpr::Create(
219      CbaseIsArrowSourceLocation(), NestedNameSpecifierLoc(),
220      SourceLocation(), MemberDeclFoundDecl,
221      DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
222      /* TemplateArgumentListInfo=*/ nullptrMemberDecl->getType(), ValueKind,
223      OK_Ordinary);
224}
225
226ValueDecl *ASTMaker::findMemberField(const RecordDecl *RDStringRef Name) {
227
228  CXXBasePaths Paths(
229      /* FindAmbiguities=*/false,
230      /* RecordPaths=*/false,
231      /* DetectVirtual=*/ false);
232  const IdentifierInfo &II = C.Idents.get(Name);
233  DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
234
235  DeclContextLookupResult Decls = RD->lookup(DeclName);
236  for (NamedDecl *FoundDecl : Decls)
237    if (!FoundDecl->getDeclContext()->isFunctionOrMethod())
238      return cast<ValueDecl>(FoundDecl);
239
240  return nullptr;
241}
242
243//===----------------------------------------------------------------------===//
244// Creation functions for faux ASTs.
245//===----------------------------------------------------------------------===//
246
247typedef Stmt *(*FunctionFarmer)(ASTContext &Cconst FunctionDecl *D);
248
249static CallExpr *create_call_once_funcptr_call(ASTContext &CASTMaker M,
250                                               const ParmVarDecl *Callback,
251                                               ArrayRef<Expr *> CallArgs) {
252
253  QualType Ty = Callback->getType();
254  DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
255  Expr *SubExpr;
256  if (Ty->isRValueReferenceType()) {
257    SubExpr = M.makeImplicitCast(
258        CallTy.getNonReferenceType(), CK_LValueToRValue);
259  } else if (Ty->isLValueReferenceType() &&
260             Call->getType()->isFunctionType()) {
261    Ty = C.getPointerType(Ty.getNonReferenceType());
262    SubExpr = M.makeImplicitCast(CallTyCK_FunctionToPointerDecay);
263  } else if (Ty->isLValueReferenceType()
264             && Call->getType()->isPointerType()
265             && Call->getType()->getPointeeType()->isFunctionType()){
266    SubExpr = Call;
267  } else {
268    llvm_unreachable("Unexpected state");
269  }
270
271  return CallExpr::Create(C, SubExpr, CallArgs, C.VoidTy, VK_RValue,
272                          SourceLocation());
273}
274
275static CallExpr *create_call_once_lambda_call(ASTContext &CASTMaker M,
276                                              const ParmVarDecl *Callback,
277                                              CXXRecordDecl *CallbackDecl,
278                                              ArrayRef<Expr *> CallArgs) {
279  assert(CallbackDecl != nullptr);
280  isLambda()", "/home/seafit/code_projects/clang_source/clang/lib/Analysis/BodyFarm.cpp", 280, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CallbackDecl->isLambda());
281  FunctionDecl *callOperatorDecl = CallbackDecl->getLambdaCallOperator();
282  assert(callOperatorDecl != nullptr);
283
284  DeclRefExpr *callOperatorDeclRef =
285      DeclRefExpr::Create(/* Ctx =*/ C,
286                          /* QualifierLoc =*/ NestedNameSpecifierLoc(),
287                          /* TemplateKWLoc =*/ SourceLocation(),
288                          const_cast<FunctionDecl *>(callOperatorDecl),
289                          /* RefersToEnclosingVariableOrCapture=*/ false,
290                          /* NameLoc =*/ SourceLocation(),
291                          /* T =*/ callOperatorDecl->getType(),
292                          /* VK =*/ VK_LValue);
293
294  return CXXOperatorCallExpr::Create(
295      /*AstContext=*/C, OO_Call, callOperatorDeclRef,
296      /*args=*/CallArgs,
297      /*QualType=*/C.VoidTy,
298      /*ExprValueType=*/VK_RValue,
299      /*SourceLocation=*/SourceLocation(), FPOptions());
300}
301
302/// Create a fake body for std::call_once.
303/// Emulates the following function body:
304///
305/// \code
306/// typedef struct once_flag_s {
307///   unsigned long __state = 0;
308/// } once_flag;
309/// template<class Callable>
310/// void call_once(once_flag& o, Callable func) {
311///   if (!o.__state) {
312///     func();
313///   }
314///   o.__state = 1;
315/// }
316/// \endcode
317static Stmt *create_call_once(ASTContext &Cconst FunctionDecl *D) {
318  LLVM_DEBUG(llvm::dbgs() << "Generating body for call_once\n");
319
320  // We need at least two parameters.
321  if (D->param_size() < 2)
322    return nullptr;
323
324  ASTMaker M(C);
325
326  const ParmVarDecl *Flag = D->getParamDecl(0);
327  const ParmVarDecl *Callback = D->getParamDecl(1);
328
329  if (!Callback->getType()->isReferenceType()) {
330    llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
331    return nullptr;
332  }
333  if (!Flag->getType()->isReferenceType()) {
334    llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
335    return nullptr;
336  }
337
338  QualType CallbackType = Callback->getType().getNonReferenceType();
339
340  // Nullable pointer, non-null iff function is a CXXRecordDecl.
341  CXXRecordDecl *CallbackRecordDecl = CallbackType->getAsCXXRecordDecl();
342  QualType FlagType = Flag->getType().getNonReferenceType();
343  auto *FlagRecordDecl = FlagType->getAsRecordDecl();
344
345  if (!FlagRecordDecl) {
346    LLVM_DEBUG(llvm::dbgs() << "Flag field is not a record: "
347                            << "unknown std::call_once implementation, "
348                            << "ignoring the call.\n");
349    return nullptr;
350  }
351
352  // We initially assume libc++ implementation of call_once,
353  // where the once_flag struct has a field `__state_`.
354  ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl"__state_");
355
356  // Otherwise, try libstdc++ implementation, with a field
357  // `_M_once`
358  if (!FlagFieldDecl) {
359    FlagFieldDecl = M.findMemberField(FlagRecordDecl"_M_once");
360  }
361
362  if (!FlagFieldDecl) {
363    LLVM_DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
364                            << "std::once_flag struct: unknown std::call_once "
365                            << "implementation, ignoring the call.");
366    return nullptr;
367  }
368
369  bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
370  if (CallbackRecordDecl && !isLambdaCall) {
371    LLVM_DEBUG(llvm::dbgs()
372               << "Not supported: synthesizing body for functors when "
373               << "body farming std::call_once, ignoring the call.");
374    return nullptr;
375  }
376
377  SmallVector<Expr *, 5CallArgs;
378  const FunctionProtoType *CallbackFunctionType;
379  if (isLambdaCall) {
380
381    // Lambda requires callback itself inserted as a first parameter.
382    CallArgs.push_back(
383        M.makeDeclRefExpr(Callback,
384                          /* RefersToEnclosingVariableOrCapture=*/ true));
385    CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator()
386                               ->getType()
387                               ->getAs<FunctionProtoType>();
388  } else if (!CallbackType->getPointeeType().isNull()) {
389    CallbackFunctionType =
390        CallbackType->getPointeeType()->getAs<FunctionProtoType>();
391  } else {
392    CallbackFunctionType = CallbackType->getAs<FunctionProtoType>();
393  }
394
395  if (!CallbackFunctionType)
396    return nullptr;
397
398  // First two arguments are used for the flag and for the callback.
399  if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
400    LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
401                            << "params passed to std::call_once, "
402                            << "ignoring the call\n");
403    return nullptr;
404  }
405
406  // All arguments past first two ones are passed to the callback,
407  // and we turn lvalues into rvalues if the argument is not passed by
408  // reference.
409  for (unsigned int ParamIdx = 2ParamIdx < D->getNumParams(); ParamIdx++) {
410    const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx);
411    if (PDecl &&
412        CallbackFunctionType->getParamType(ParamIdx - 2)
413                .getNonReferenceType()
414                .getCanonicalType() !=
415            PDecl->getType().getNonReferenceType().getCanonicalType()) {
416      LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
417                              << "params passed to std::call_once, "
418                              << "ignoring the call\n");
419      return nullptr;
420    }
421    Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
422    if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
423      QualType PTy = PDecl->getType().getNonReferenceType();
424      ParamExpr = M.makeLvalueToRvalue(ParamExprPTy);
425    }
426    CallArgs.push_back(ParamExpr);
427  }
428
429  CallExpr *CallbackCall;
430  if (isLambdaCall) {
431
432    CallbackCall = create_call_once_lambda_call(C, M, Callback,
433                                                CallbackRecordDecl, CallArgs);
434  } else {
435
436    // Function pointer case.
437    CallbackCall = create_call_once_funcptr_call(C, M, Callback, CallArgs);
438  }
439
440  DeclRefExpr *FlagDecl =
441      M.makeDeclRefExpr(Flag,
442                        /* RefersToEnclosingVariableOrCapture=*/true);
443
444
445  MemberExpr *Deref = M.makeMemberExpression(FlagDeclFlagFieldDecl);
446  isLValue()", "/home/seafit/code_projects/clang_source/clang/lib/Analysis/BodyFarm.cpp", 446, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Deref->isLValue());
447  QualType DerefType = Deref->getType();
448
449  // Negation predicate.
450  UnaryOperator *FlagCheck = new (CUnaryOperator(
451      /* input=*/
452      M.makeImplicitCast(M.makeLvalueToRvalue(DerefDerefType), DerefType,
453                         CK_IntegralToBoolean),
454      /* opc=*/ UO_LNot,
455      /* QualType=*/ C.IntTy,
456      /* ExprValueKind=*/ VK_RValue,
457      /* ExprObjectKind=*/ OK_OrdinarySourceLocation(),
458      /* CanOverflow*/ false);
459
460  // Create assignment.
461  BinaryOperator *FlagAssignment = M.makeAssignment(
462      DerefM.makeIntegralCast(M.makeIntegerLiteral(1C.IntTy), DerefType),
463      DerefType);
464
465  auto *Out =
466      IfStmt::Create(CSourceLocation(),
467                     /* IsConstexpr=*/false,
468                     /* init=*/nullptr,
469                     /* var=*/nullptr,
470                     /* cond=*/FlagCheck,
471                     /* then=*/M.makeCompound({CallbackCallFlagAssignment}));
472
473  return Out;
474}
475
476/// Create a fake body for dispatch_once.
477static Stmt *create_dispatch_once(ASTContext &Cconst FunctionDecl *D) {
478  // Check if we have at least two parameters.
479  if (D->param_size() != 2)
480    return nullptr;
481
482  // Check if the first parameter is a pointer to integer type.
483  const ParmVarDecl *Predicate = D->getParamDecl(0);
484  QualType PredicateQPtrTy = Predicate->getType();
485  const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
486  if (!PredicatePtrTy)
487    return nullptr;
488  QualType PredicateTy = PredicatePtrTy->getPointeeType();
489  if (!PredicateTy->isIntegerType())
490    return nullptr;
491
492  // Check if the second parameter is the proper block type.
493  const ParmVarDecl *Block = D->getParamDecl(1);
494  QualType Ty = Block->getType();
495  if (!isDispatchBlock(Ty))
496    return nullptr;
497
498  // Everything checks out.  Create a fakse body that checks the predicate,
499  // sets it, and calls the block.  Basically, an AST dump of:
500  //
501  // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
502  //  if (*predicate != ~0l) {
503  //    *predicate = ~0l;
504  //    block();
505  //  }
506  // }
507
508  ASTMaker M(C);
509
510  // (1) Create the call.
511  CallExpr *CE = CallExpr::Create(
512      /*ASTContext=*/C,
513      /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block),
514      /*args=*/None,
515      /*QualType=*/C.VoidTy,
516      /*ExprValueType=*/VK_RValue,
517      /*SourceLocation=*/SourceLocation());
518
519  // (2) Create the assignment to the predicate.
520  Expr *DoneValue =
521      new (CUnaryOperator(M.makeIntegerLiteral(0C.LongTy), UO_NotC.LongTy,
522                            VK_RValueOK_OrdinarySourceLocation(),
523                            /*CanOverflow*/false);
524
525  BinaryOperator *B =
526    M.makeAssignment(
527       M.makeDereference(
528          M.makeLvalueToRvalue(
529            M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
530            PredicateTy),
531       M.makeIntegralCast(DoneValuePredicateTy),
532       PredicateTy);
533
534  // (3) Create the compound statement.
535  Stmt *Stmts[] = { BCE };
536  CompoundStmt *CS = M.makeCompound(Stmts);
537
538  // (4) Create the 'if' condition.
539  ImplicitCastExpr *LValToRval =
540    M.makeLvalueToRvalue(
541      M.makeDereference(
542        M.makeLvalueToRvalue(
543          M.makeDeclRefExpr(Predicate),
544          PredicateQPtrTy),
545        PredicateTy),
546    PredicateTy);
547
548  Expr *GuardCondition = M.makeComparison(LValToRvalDoneValueBO_NE);
549  // (5) Create the 'if' statement.
550  auto *If = IfStmt::Create(CSourceLocation(),
551                            /* IsConstexpr=*/false,
552                            /* init=*/nullptr,
553                            /* var=*/nullptr,
554                            /* cond=*/GuardCondition,
555                            /* then=*/CS);
556  return If;
557}
558
559/// Create a fake body for dispatch_sync.
560static Stmt *create_dispatch_sync(ASTContext &Cconst FunctionDecl *D) {
561  // Check if we have at least two parameters.
562  if (D->param_size() != 2)
563    return nullptr;
564
565  // Check if the second parameter is a block.
566  const ParmVarDecl *PV = D->getParamDecl(1);
567  QualType Ty = PV->getType();
568  if (!isDispatchBlock(Ty))
569    return nullptr;
570
571  // Everything checks out.  Create a fake body that just calls the block.
572  // This is basically just an AST dump of:
573  //
574  // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
575  //   block();
576  // }
577  //
578  ASTMaker M(C);
579  DeclRefExpr *DR = M.makeDeclRefExpr(PV);
580  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DRTy);
581  CallExpr *CE =
582      CallExpr::Create(C, ICE, None, C.VoidTy, VK_RValue, SourceLocation());
583  return CE;
584}
585
586static Stmt *create_OSAtomicCompareAndSwap(ASTContext &Cconst FunctionDecl *D)
587{
588  // There are exactly 3 arguments.
589  if (D->param_size() != 3)
590    return nullptr;
591
592  // Signature:
593  // _Bool OSAtomicCompareAndSwapPtr(void *__oldValue,
594  //                                 void *__newValue,
595  //                                 void * volatile *__theValue)
596  // Generate body:
597  //   if (oldValue == *theValue) {
598  //    *theValue = newValue;
599  //    return YES;
600  //   }
601  //   else return NO;
602
603  QualType ResultTy = D->getReturnType();
604  bool isBoolean = ResultTy->isBooleanType();
605  if (!isBoolean && !ResultTy->isIntegralType(C))
606    return nullptr;
607
608  const ParmVarDecl *OldValue = D->getParamDecl(0);
609  QualType OldValueTy = OldValue->getType();
610
611  const ParmVarDecl *NewValue = D->getParamDecl(1);
612  QualType NewValueTy = NewValue->getType();
613
614  assert(OldValueTy == NewValueTy);
615
616  const ParmVarDecl *TheValue = D->getParamDecl(2);
617  QualType TheValueTy = TheValue->getType();
618  const PointerType *PT = TheValueTy->getAs<PointerType>();
619  if (!PT)
620    return nullptr;
621  QualType PointeeTy = PT->getPointeeType();
622
623  ASTMaker M(C);
624  // Construct the comparison.
625  Expr *Comparison =
626    M.makeComparison(
627      M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
628      M.makeLvalueToRvalue(
629        M.makeDereference(
630          M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
631          PointeeTy),
632        PointeeTy),
633      BO_EQ);
634
635  // Construct the body of the IfStmt.
636  Stmt *Stmts[2];
637  Stmts[0] =
638    M.makeAssignment(
639      M.makeDereference(
640        M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
641        PointeeTy),
642      M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
643      NewValueTy);
644
645  Expr *BoolVal = M.makeObjCBool(true);
646  Expr *RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
647                           : M.makeIntegralCast(BoolValResultTy);
648  Stmts[1] = M.makeReturn(RetVal);
649  CompoundStmt *Body = M.makeCompound(Stmts);
650
651  // Construct the else clause.
652  BoolVal = M.makeObjCBool(false);
653  RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
654                     : M.makeIntegralCast(BoolValResultTy);
655  Stmt *Else = M.makeReturn(RetVal);
656
657  /// Construct the If.
658  auto *If = IfStmt::Create(CSourceLocation(),
659                            /* IsConstexpr=*/false,
660                            /* init=*/nullptr,
661                            /* var=*/nullptrComparisonBody,
662                            SourceLocation(), Else);
663
664  return If;
665}
666
667Stmt *BodyFarm::getBody(const FunctionDecl *D) {
668  D = D->getCanonicalDecl();
669
670  Optional<Stmt *> &Val = Bodies[D];
671  if (Val.hasValue())
672    return Val.getValue();
673
674  Val = nullptr;
675
676  if (D->getIdentifier() == nullptr)
677    return nullptr;
678
679  StringRef Name = D->getName();
680  if (Name.empty())
681    return nullptr;
682
683  FunctionFarmer FF;
684
685  if (Name.startswith("OSAtomicCompareAndSwap") ||
686      Name.startswith("objc_atomicCompareAndSwap")) {
687    FF = create_OSAtomicCompareAndSwap;
688  } else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) {
689    FF = create_call_once;
690  } else {
691    FF = llvm::StringSwitch<FunctionFarmer>(Name)
692          .Case("dispatch_sync", create_dispatch_sync)
693          .Case("dispatch_once", create_dispatch_once)
694          .Default(nullptr);
695  }
696
697  if (FF) { Val = FF(CD); }
698  else if (Injector) { Val = Injector->getBody(D); }
699  return Val.getValue();
700}
701
702static const ObjCIvarDecl *findBackingIvar(const ObjCPropertyDecl *Prop) {
703  const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
704
705  if (IVar)
706    return IVar;
707
708  // When a readonly property is shadowed in a class extensions with a
709  // a readwrite property, the instance variable belongs to the shadowing
710  // property rather than the shadowed property. If there is no instance
711  // variable on a readonly property, check to see whether the property is
712  // shadowed and if so try to get the instance variable from shadowing
713  // property.
714  if (!Prop->isReadOnly())
715    return nullptr;
716
717  auto *Container = cast<ObjCContainerDecl>(Prop->getDeclContext());
718  const ObjCInterfaceDecl *PrimaryInterface = nullptr;
719  if (auto *InterfaceDecl = dyn_cast<ObjCInterfaceDecl>(Container)) {
720    PrimaryInterface = InterfaceDecl;
721  } else if (auto *CategoryDecl = dyn_cast<ObjCCategoryDecl>(Container)) {
722    PrimaryInterface = CategoryDecl->getClassInterface();
723  } else if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container)) {
724    PrimaryInterface = ImplDecl->getClassInterface();
725  } else {
726    return nullptr;
727  }
728
729  // FindPropertyVisibleInPrimaryClass() looks first in class extensions, so it
730  // is guaranteed to find the shadowing property, if it exists, rather than
731  // the shadowed property.
732  auto *ShadowingProp = PrimaryInterface->FindPropertyVisibleInPrimaryClass(
733      Prop->getIdentifier(), Prop->getQueryKind());
734  if (ShadowingProp && ShadowingProp != Prop) {
735    IVar = ShadowingProp->getPropertyIvarDecl();
736  }
737
738  return IVar;
739}
740
741static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
742                                      const ObjCPropertyDecl *Prop) {
743  // First, find the backing ivar.
744  const ObjCIvarDecl *IVar = findBackingIvar(Prop);
745  if (!IVar)
746    return nullptr;
747
748  // Ignore weak variables, which have special behavior.
749  if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
750    return nullptr;
751
752  // Look to see if Sema has synthesized a body for us. This happens in
753  // Objective-C++ because the return value may be a C++ class type with a
754  // non-trivial copy constructor. We can only do this if we can find the
755  // @synthesize for this property, though (or if we know it's been auto-
756  // synthesized).
757  const ObjCImplementationDecl *ImplDecl =
758    IVar->getContainingInterface()->getImplementation();
759  if (ImplDecl) {
760    for (const auto *I : ImplDecl->property_impls()) {
761      if (I->getPropertyDecl() != Prop)
762        continue;
763
764      if (I->getGetterCXXConstructor()) {
765        ASTMaker M(Ctx);
766        return M.makeReturn(I->getGetterCXXConstructor());
767      }
768    }
769  }
770
771  // Sanity check that the property is the same type as the ivar, or a
772  // reference to it, and that it is either an object pointer or trivially
773  // copyable.
774  if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
775                                  Prop->getType().getNonReferenceType()))
776    return nullptr;
777  if (!IVar->getType()->isObjCLifetimeType() &&
778      !IVar->getType().isTriviallyCopyableType(Ctx))
779    return nullptr;
780
781  // Generate our body:
782  //   return self->_ivar;
783  ASTMaker M(Ctx);
784
785  const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl();
786  if (!selfVar)
787    return nullptr;
788
789  Expr *loadedIVar =
790    M.makeObjCIvarRef(
791      M.makeLvalueToRvalue(
792        M.makeDeclRefExpr(selfVar),
793        selfVar->getType()),
794      IVar);
795
796  if (!Prop->getType()->isReferenceType())
797    loadedIVar = M.makeLvalueToRvalue(loadedIVarIVar->getType());
798
799  return M.makeReturn(loadedIVar);
800}
801
802Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
803  // We currently only know how to synthesize property accessors.
804  if (!D->isPropertyAccessor())
805    return nullptr;
806
807  D = D->getCanonicalDecl();
808
809  // We should not try to synthesize explicitly redefined accessors.
810  // We do not know for sure how they behave.
811  if (!D->isImplicit())
812    return nullptr;
813
814  Optional<Stmt *> &Val = Bodies[D];
815  if (Val.hasValue())
816    return Val.getValue();
817  Val = nullptr;
818
819  const ObjCPropertyDecl *Prop = D->findPropertyDecl();
820  if (!Prop)
821    return nullptr;
822
823  // For now, we only synthesize getters.
824  // Synthesizing setters would cause false negatives in the
825  // RetainCountChecker because the method body would bind the parameter
826  // to an instance variable, causing it to escape. This would prevent
827  // warning in the following common scenario:
828  //
829  //  id foo = [[NSObject alloc] init];
830  //  self.foo = foo; // We should warn that foo leaks here.
831  //
832  if (D->param_size() != 0)
833    return nullptr;
834
835  Val = createObjCPropertyGetter(CProp);
836
837  return Val.getValue();
838}
839
clang::BodyFarm::getBody
clang::BodyFarm::getBody