1a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//== BodyFarm.cpp  - Factory for conjuring up fake bodies ----------*- C++ -*-//
2a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//
3a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//                     The LLVM Compiler Infrastructure
4a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//
5a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek// This file is distributed under the University of Illinois Open Source
6a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek// License. See LICENSE.TXT for details.
7a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//
8a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//===----------------------------------------------------------------------===//
9a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//
10a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek// BodyFarm is a factory for creating faux implementations for functions/methods
11a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek// for analysis purposes.
12a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//
13a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek//===----------------------------------------------------------------------===//
14a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "BodyFarm.h"
16a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek#include "clang/AST/ASTContext.h"
17a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek#include "clang/AST/Decl.h"
1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/Expr.h"
1948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek#include "clang/AST/ExprObjC.h"
200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#include "clang/Analysis/CodeInjector.h"
2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h"
22a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
23a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekusing namespace clang;
24a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
250a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek//===----------------------------------------------------------------------===//
260a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek// Helper creation functions for constructing faux ASTs.
270a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek//===----------------------------------------------------------------------===//
28a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
29cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenekstatic bool isDispatchBlock(QualType Ty) {
30cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // Is it a block pointer?
31cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  const BlockPointerType *BPT = Ty->getAs<BlockPointerType>();
32cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  if (!BPT)
33cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    return false;
34cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
35cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // Check if the block pointer type takes no arguments and
36cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // returns void.
37cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  const FunctionProtoType *FT =
38cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  BPT->getPointeeType()->getAs<FunctionProtoType>();
3987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return FT && FT->getReturnType()->isVoidType() && FT->getNumParams() == 0;
40cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek}
41cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
42016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremeneknamespace {
43016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenekclass ASTMaker {
44016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenekpublic:
45016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  ASTMaker(ASTContext &C) : C(C) {}
46016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
47b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek  /// Create a new BinaryOperator representing a simple assignment.
48b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek  BinaryOperator *makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty);
49b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek
5048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  /// Create a new BinaryOperator representing a comparison.
5148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  BinaryOperator *makeComparison(const Expr *LHS, const Expr *RHS,
5248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                 BinaryOperator::Opcode Op);
5348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
5448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  /// Create a new compound stmt using the provided statements.
5548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  CompoundStmt *makeCompound(ArrayRef<Stmt*>);
5648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
57a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek  /// Create a new DeclRefExpr for the referenced variable.
58016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  DeclRefExpr *makeDeclRefExpr(const VarDecl *D);
59016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
600b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek  /// Create a new UnaryOperator representing a dereference.
610b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek  UnaryOperator *makeDereference(const Expr *Arg, QualType Ty);
620b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek
63a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek  /// Create an implicit cast for an integer conversion.
645dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  Expr *makeIntegralCast(const Expr *Arg, QualType Ty);
65a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek
6648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  /// Create an implicit cast to a builtin boolean type.
6748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
6848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
699ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek  // Create an implicit cast for lvalue-to-rvaluate conversions.
709ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek  ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);
719ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek
7248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  /// Create an Objective-C bool literal.
7348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  ObjCBoolLiteralExpr *makeObjCBool(bool Val);
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Create an Objective-C ivar reference.
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ObjCIvarRefExpr *makeObjCIvarRef(const Expr *Base, const ObjCIvarDecl *IVar);
7748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
7848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  /// Create a Return statement.
7948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  ReturnStmt *makeReturn(const Expr *RetVal);
8048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
81016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenekprivate:
82016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  ASTContext &C;
83016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek};
84016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek}
85016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
86b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted KremenekBinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
87b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek                                         QualType Ty) {
88b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
89b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek                               BO_Assign, Ty, VK_RValue,
90be9af1288881110e406b87914162eaa59f1e5918Lang Hames                               OK_Ordinary, SourceLocation(), false);
91b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek}
92b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek
9348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted KremenekBinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
9448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                         BinaryOperator::Opcode Op) {
9548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  assert(BinaryOperator::isLogicalOp(Op) ||
9648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek         BinaryOperator::isComparisonOp(Op));
9748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  return new (C) BinaryOperator(const_cast<Expr*>(LHS),
9848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                const_cast<Expr*>(RHS),
9948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                Op,
10048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                C.getLogicalOperationType(),
10148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                VK_RValue,
10248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                                OK_Ordinary, SourceLocation(), false);
10348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek}
10448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
10548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted KremenekCompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
106d36aa359e2f45cd22c7366a015ad94de08044dbbNico Weber  return new (C) CompoundStmt(C, Stmts, SourceLocation(), SourceLocation());
10748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek}
10848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
109016c33d7bbca20c096ad8c7400b70f33aadfb224Ted KremenekDeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
110016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  DeclRefExpr *DR =
111016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek    DeclRefExpr::Create(/* Ctx = */ C,
112016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek                        /* QualifierLoc = */ NestedNameSpecifierLoc(),
113016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek                        /* TemplateKWLoc = */ SourceLocation(),
114016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek                        /* D = */ const_cast<VarDecl*>(D),
1150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                        /* RefersToEnclosingVariableOrCapture = */ false,
116016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek                        /* NameLoc = */ SourceLocation(),
117016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek                        /* T = */ D->getType(),
118016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek                        /* VK = */ VK_LValue);
119016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  return DR;
120016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek}
121016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
1220b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted KremenekUnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
1230b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek  return new (C) UnaryOperator(const_cast<Expr*>(Arg), UO_Deref, Ty,
1240b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek                               VK_LValue, OK_Ordinary, SourceLocation());
1250b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek}
1260b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek
1279ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted KremenekImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
1289ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek  return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
1309ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek}
1319ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek
1325dbd990d7978fb990b61a9bcf1b71314a3e743feTed KremenekExpr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
1335dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  if (Arg->getType() == Ty)
1345dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek    return const_cast<Expr*>(Arg);
1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
136a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek  return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
138a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek}
139a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek
14048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted KremenekImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
14148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
14348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek}
14448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
14548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted KremenekObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
14648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  QualType Ty = C.getBOOLDecl() ? C.getBOOLType() : C.ObjCBuiltinBoolTy;
14748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
14848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek}
14948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
150651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                           const ObjCIvarDecl *IVar) {
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return new (C) ObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 IVar->getType(), SourceLocation(),
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 SourceLocation(), const_cast<Expr*>(Base),
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 /*arrow=*/true, /*free=*/false);
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
15948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted KremenekReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return new (C) ReturnStmt(SourceLocation(), const_cast<Expr*>(RetVal),
1616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                            nullptr);
16248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek}
16348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
1640a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek//===----------------------------------------------------------------------===//
1650a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek// Creation functions for faux ASTs.
1660a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek//===----------------------------------------------------------------------===//
1670a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek
1680a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenektypedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
1690a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek
170cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek/// Create a fake body for dispatch_once.
171cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenekstatic Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
172cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // Check if we have at least two parameters.
173cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  if (D->param_size() != 2)
1746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
175cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
176cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // Check if the first parameter is a pointer to integer type.
177cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  const ParmVarDecl *Predicate = D->getParamDecl(0);
178cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  QualType PredicateQPtrTy = Predicate->getType();
179cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
180cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  if (!PredicatePtrTy)
1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
182cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  QualType PredicateTy = PredicatePtrTy->getPointeeType();
183cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  if (!PredicateTy->isIntegerType())
1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
186cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // Check if the second parameter is the proper block type.
187cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  const ParmVarDecl *Block = D->getParamDecl(1);
188cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  QualType Ty = Block->getType();
189cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  if (!isDispatchBlock(Ty))
1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
192cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // Everything checks out.  Create a fakse body that checks the predicate,
193cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // sets it, and calls the block.  Basically, an AST dump of:
194cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  //
195cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
196cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  //  if (!*predicate) {
197cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  //    *predicate = 1;
198cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  //    block();
199cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  //  }
200cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // }
201cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
202016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  ASTMaker M(C);
203016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
204cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // (1) Create the call.
205016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  DeclRefExpr *DR = M.makeDeclRefExpr(Block);
2069ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
2075543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko  CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
2085543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko                                  SourceLocation());
209cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
210cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // (2) Create the assignment to the predicate.
211cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  IntegerLiteral *IL =
212cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
213cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek                           C.IntTy, SourceLocation());
214fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek  BinaryOperator *B =
215fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek    M.makeAssignment(
216fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek       M.makeDereference(
217fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek          M.makeLvalueToRvalue(
218fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek            M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
219fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek            PredicateTy),
220fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek       M.makeIntegralCast(IL, PredicateTy),
221fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek       PredicateTy);
222fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek
223cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // (3) Create the compound statement.
224176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Stmt *Stmts[] = { B, CE };
225176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CompoundStmt *CS = M.makeCompound(Stmts);
226cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
227cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // (4) Create the 'if' condition.
228fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek  ImplicitCastExpr *LValToRval =
229fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek    M.makeLvalueToRvalue(
230fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek      M.makeDereference(
231fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek        M.makeLvalueToRvalue(
232fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek          M.makeDeclRefExpr(Predicate),
233fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek          PredicateQPtrTy),
234fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek        PredicateTy),
235fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek    PredicateTy);
236fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek
237fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek  UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
238fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek                                           VK_RValue, OK_Ordinary,
239fcf8eba0c78634243383f92a77381e919e7e27efTed Kremenek                                           SourceLocation());
240cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
241cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  // (5) Create the 'if' statement.
2424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  IfStmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr,
2434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              UO, CS);
244cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  return If;
245cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek}
246cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
247a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek/// Create a fake body for dispatch_sync.
248a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekstatic Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
249a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  // Check if we have at least two parameters.
250a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  if (D->param_size() != 2)
2516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
253a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  // Check if the second parameter is a block.
254a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  const ParmVarDecl *PV = D->getParamDecl(1);
255a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  QualType Ty = PV->getType();
256cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek  if (!isDispatchBlock(Ty))
2576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
259a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  // Everything checks out.  Create a fake body that just calls the block.
260a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  // This is basically just an AST dump of:
261a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  //
262a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  // void dispatch_sync(dispatch_queue_t queue, void (^block)(void)) {
263a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  //   block();
264a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  // }
265016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  //
266016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  ASTMaker M(C);
267016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek  DeclRefExpr *DR = M.makeDeclRefExpr(PV);
2680b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
2695543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko  CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
2705543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko                                  SourceLocation());
271a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  return CE;
272a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek}
273a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
27448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenekstatic Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
27548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek{
27648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  // There are exactly 3 arguments.
27748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  if (D->param_size() != 3)
2786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
280ef95aea4fe779730de23ac84536cfd135b13a4b4Anna Zaks  // Signature:
281ef95aea4fe779730de23ac84536cfd135b13a4b4Anna Zaks  // _Bool OSAtomicCompareAndSwapPtr(void *__oldValue,
282ef95aea4fe779730de23ac84536cfd135b13a4b4Anna Zaks  //                                 void *__newValue,
283ef95aea4fe779730de23ac84536cfd135b13a4b4Anna Zaks  //                                 void * volatile *__theValue)
284ef95aea4fe779730de23ac84536cfd135b13a4b4Anna Zaks  // Generate body:
28548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  //   if (oldValue == *theValue) {
28648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  //    *theValue = newValue;
28748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  //    return YES;
28848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  //   }
28948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  //   else return NO;
290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  QualType ResultTy = D->getReturnType();
2925dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  bool isBoolean = ResultTy->isBooleanType();
2935dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  if (!isBoolean && !ResultTy->isIntegralType(C))
2946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
2956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
29648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  const ParmVarDecl *OldValue = D->getParamDecl(0);
29748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  QualType OldValueTy = OldValue->getType();
29848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
29948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  const ParmVarDecl *NewValue = D->getParamDecl(1);
30048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  QualType NewValueTy = NewValue->getType();
30148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
30248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  assert(OldValueTy == NewValueTy);
30348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
30448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  const ParmVarDecl *TheValue = D->getParamDecl(2);
30548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  QualType TheValueTy = TheValue->getType();
30648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  const PointerType *PT = TheValueTy->getAs<PointerType>();
30748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  if (!PT)
3086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
30948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  QualType PointeeTy = PT->getPointeeType();
31048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
31148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  ASTMaker M(C);
31248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  // Construct the comparison.
31348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  Expr *Comparison =
31448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    M.makeComparison(
31548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy),
31648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      M.makeLvalueToRvalue(
31748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        M.makeDereference(
31848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek          M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
31948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek          PointeeTy),
32048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        PointeeTy),
32148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      BO_EQ);
32248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
32348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  // Construct the body of the IfStmt.
32448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  Stmt *Stmts[2];
32548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  Stmts[0] =
32648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    M.makeAssignment(
32748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      M.makeDereference(
32848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy),
32948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        PointeeTy),
33048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy),
33148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      NewValueTy);
3325dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek
3335dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  Expr *BoolVal = M.makeObjCBool(true);
3345dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  Expr *RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
3355dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek                           : M.makeIntegralCast(BoolVal, ResultTy);
3365dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  Stmts[1] = M.makeReturn(RetVal);
337176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  CompoundStmt *Body = M.makeCompound(Stmts);
33848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
33948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  // Construct the else clause.
3405dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  BoolVal = M.makeObjCBool(false);
3415dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  RetVal = isBoolean ? M.makeIntegralCastToBoolean(BoolVal)
3425dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek                     : M.makeIntegralCast(BoolVal, ResultTy);
3435dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek  Stmt *Else = M.makeReturn(RetVal);
34448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
34548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  /// Construct the If.
3464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Stmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr,
3474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                            Comparison, Body, SourceLocation(), Else);
3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
34948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  return If;
35048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek}
35148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
352a43df9539644bf1c258e12710cd69d79b0b078cdTed KremenekStmt *BodyFarm::getBody(const FunctionDecl *D) {
353a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  D = D->getCanonicalDecl();
354a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
355dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie  Optional<Stmt *> &Val = Bodies[D];
356a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  if (Val.hasValue())
357a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek    return Val.getValue();
3586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
3596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Val = nullptr;
3606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
3616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (D->getIdentifier() == nullptr)
3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
363a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
364a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  StringRef Name = D->getName();
365a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  if (Name.empty())
3666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
36748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
36848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  FunctionFarmer FF;
36948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
37048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  if (Name.startswith("OSAtomicCompareAndSwap") ||
37148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek      Name.startswith("objc_atomicCompareAndSwap")) {
37248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    FF = create_OSAtomicCompareAndSwap;
37348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  }
37448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  else {
37548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    FF = llvm::StringSwitch<FunctionFarmer>(Name)
37648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek          .Case("dispatch_sync", create_dispatch_sync)
37748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek          .Case("dispatch_once", create_dispatch_once)
3786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines          .Default(nullptr);
379a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  }
380a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
38148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek  if (FF) { Val = FF(C, D); }
382176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  else if (Injector) { Val = Injector->getBody(D); }
383a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  return Val.getValue();
384a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek}
385a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
3864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic const ObjCIvarDecl *findBackingIvar(const ObjCPropertyDecl *Prop) {
3874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
3884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (IVar)
3904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return IVar;
3914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // When a readonly property is shadowed in a class extensions with a
3934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // a readwrite property, the instance variable belongs to the shadowing
3944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // property rather than the shadowed property. If there is no instance
3954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // variable on a readonly property, check to see whether the property is
3964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // shadowed and if so try to get the instance variable from shadowing
3974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // property.
3984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!Prop->isReadOnly())
3994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return nullptr;
4004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *Container = cast<ObjCContainerDecl>(Prop->getDeclContext());
4024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const ObjCInterfaceDecl *PrimaryInterface = nullptr;
4034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (auto *InterfaceDecl = dyn_cast<ObjCInterfaceDecl>(Container)) {
4044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PrimaryInterface = InterfaceDecl;
4054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else if (auto *CategoryDecl = dyn_cast<ObjCCategoryDecl>(Container)) {
4064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PrimaryInterface = CategoryDecl->getClassInterface();
4074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else if (auto *ImplDecl = dyn_cast<ObjCImplDecl>(Container)) {
4084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    PrimaryInterface = ImplDecl->getClassInterface();
4094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  } else {
4104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return nullptr;
4114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
4124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FindPropertyVisibleInPrimaryClass() looks first in class extensions, so it
4144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // is guaranteed to find the shadowing property, if it exists, rather than
4154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // the shadowed property.
4164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto *ShadowingProp = PrimaryInterface->FindPropertyVisibleInPrimaryClass(
4174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Prop->getIdentifier(), Prop->getQueryKind());
4184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (ShadowingProp && ShadowingProp != Prop) {
4194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    IVar = ShadowingProp->getPropertyIvarDecl();
4204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
4214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
4224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return IVar;
4234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
4244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic Stmt *createObjCPropertyGetter(ASTContext &Ctx,
426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      const ObjCPropertyDecl *Prop) {
427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // First, find the backing ivar.
4284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const ObjCIvarDecl *IVar = findBackingIvar(Prop);
429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!IVar)
4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Ignore weak variables, which have special behavior.
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
4346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Look to see if Sema has synthesized a body for us. This happens in
437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Objective-C++ because the return value may be a C++ class type with a
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // non-trivial copy constructor. We can only do this if we can find the
439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // @synthesize for this property, though (or if we know it's been auto-
440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // synthesized).
441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCImplementationDecl *ImplDecl =
442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    IVar->getContainingInterface()->getImplementation();
443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (ImplDecl) {
444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto *I : ImplDecl->property_impls()) {
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (I->getPropertyDecl() != Prop)
446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        continue;
447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (I->getGetterCXXConstructor()) {
449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        ASTMaker M(Ctx);
450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return M.makeReturn(I->getGetterCXXConstructor());
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Sanity check that the property is the same type as the ivar, or a
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // reference to it, and that it is either an object pointer or trivially
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // copyable.
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                  Prop->getType().getNonReferenceType()))
4606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!IVar->getType()->isObjCLifetimeType() &&
462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      !IVar->getType().isTriviallyCopyableType(Ctx))
4636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Generate our body:
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  //   return self->_ivar;
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASTMaker M(Ctx);
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
469651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl();
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Expr *loadedIVar =
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    M.makeObjCIvarRef(
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      M.makeLvalueToRvalue(
474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        M.makeDeclRefExpr(selfVar),
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        selfVar->getType()),
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      IVar);
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!Prop->getType()->isReferenceType())
479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    loadedIVar = M.makeLvalueToRvalue(loadedIVar, IVar->getType());
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return M.makeReturn(loadedIVar);
482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
484651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesStmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // We currently only know how to synthesize property accessors.
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!D->isPropertyAccessor())
4876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  D = D->getCanonicalDecl();
490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Optional<Stmt *> &Val = Bodies[D];
492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Val.hasValue())
493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return Val.getValue();
4946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Val = nullptr;
495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const ObjCPropertyDecl *Prop = D->findPropertyDecl();
497651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!Prop)
4986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
499651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // For now, we only synthesize getters.
5014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Synthesizing setters would cause false negatives in the
5024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // RetainCountChecker because the method body would bind the parameter
5034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // to an instance variable, causing it to escape. This would prevent
5044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // warning in the following common scenario:
5054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
5064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //  id foo = [[NSObject alloc] init];
5074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //  self.foo = foo; // We should warn that foo leaks here.
5084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (D->param_size() != 0)
5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Val = createObjCPropertyGetter(C, Prop);
513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
514651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return Val.getValue();
515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
517