14f7df9beSJordan Rose //===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
24f7df9beSJordan Rose //
34f7df9beSJordan Rose //                     The LLVM Compiler Infrastructure
44f7df9beSJordan Rose //
54f7df9beSJordan Rose // This file is distributed under the University of Illinois Open Source
64f7df9beSJordan Rose // License. See LICENSE.TXT for details.
74f7df9beSJordan Rose //
84f7df9beSJordan Rose //===----------------------------------------------------------------------===//
94f7df9beSJordan Rose //
104f7df9beSJordan Rose /// \file This file defines CallEvent and its subclasses, which represent path-
114f7df9beSJordan Rose /// sensitive instances of different kinds of function and method calls
124f7df9beSJordan Rose /// (C, C++, and Objective-C).
134f7df9beSJordan Rose //
144f7df9beSJordan Rose //===----------------------------------------------------------------------===//
154f7df9beSJordan Rose 
164f7df9beSJordan Rose #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
174f7df9beSJordan Rose #include "clang/Analysis/ProgramPoint.h"
184f7df9beSJordan Rose #include "clang/AST/ParentMap.h"
194f7df9beSJordan Rose #include "llvm/ADT/SmallSet.h"
204f7df9beSJordan Rose #include "llvm/ADT/StringExtras.h"
214f7df9beSJordan Rose 
224f7df9beSJordan Rose using namespace clang;
234f7df9beSJordan Rose using namespace ento;
244f7df9beSJordan Rose 
254f7df9beSJordan Rose QualType CallEvent::getResultType() const {
264f7df9beSJordan Rose   QualType ResultTy = getDeclaredResultType();
274f7df9beSJordan Rose 
284f7df9beSJordan Rose   if (ResultTy.isNull())
294f7df9beSJordan Rose     ResultTy = getOriginExpr()->getType();
304f7df9beSJordan Rose 
314f7df9beSJordan Rose   return ResultTy;
324f7df9beSJordan Rose }
334f7df9beSJordan Rose 
344f7df9beSJordan Rose static bool isCallbackArg(SVal V, QualType T) {
354f7df9beSJordan Rose   // If the parameter is 0, it's harmless.
364f7df9beSJordan Rose   if (V.isZeroConstant())
374f7df9beSJordan Rose     return false;
384f7df9beSJordan Rose 
394f7df9beSJordan Rose   // If a parameter is a block or a callback, assume it can modify pointer.
404f7df9beSJordan Rose   if (T->isBlockPointerType() ||
414f7df9beSJordan Rose       T->isFunctionPointerType() ||
424f7df9beSJordan Rose       T->isObjCSelType())
434f7df9beSJordan Rose     return true;
444f7df9beSJordan Rose 
454f7df9beSJordan Rose   // Check if a callback is passed inside a struct (for both, struct passed by
464f7df9beSJordan Rose   // reference and by value). Dig just one level into the struct for now.
474f7df9beSJordan Rose 
484f7df9beSJordan Rose   if (isa<PointerType>(T) || isa<ReferenceType>(T))
494f7df9beSJordan Rose     T = T->getPointeeType();
504f7df9beSJordan Rose 
514f7df9beSJordan Rose   if (const RecordType *RT = T->getAsStructureType()) {
524f7df9beSJordan Rose     const RecordDecl *RD = RT->getDecl();
534f7df9beSJordan Rose     for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
544f7df9beSJordan Rose          I != E; ++I) {
554f7df9beSJordan Rose       QualType FieldT = I->getType();
564f7df9beSJordan Rose       if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
574f7df9beSJordan Rose         return true;
584f7df9beSJordan Rose     }
594f7df9beSJordan Rose   }
604f7df9beSJordan Rose 
614f7df9beSJordan Rose   return false;
624f7df9beSJordan Rose }
634f7df9beSJordan Rose 
644f7df9beSJordan Rose bool CallEvent::hasNonZeroCallbackArg() const {
654f7df9beSJordan Rose   unsigned NumOfArgs = getNumArgs();
664f7df9beSJordan Rose 
674f7df9beSJordan Rose   // If calling using a function pointer, assume the function does not
684f7df9beSJordan Rose   // have a callback. TODO: We could check the types of the arguments here.
694f7df9beSJordan Rose   if (!getDecl())
704f7df9beSJordan Rose     return false;
714f7df9beSJordan Rose 
724f7df9beSJordan Rose   unsigned Idx = 0;
734f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = param_type_begin(),
744f7df9beSJordan Rose                                        E = param_type_end();
754f7df9beSJordan Rose        I != E && Idx < NumOfArgs; ++I, ++Idx) {
764f7df9beSJordan Rose     if (NumOfArgs <= Idx)
774f7df9beSJordan Rose       break;
784f7df9beSJordan Rose 
794f7df9beSJordan Rose     if (isCallbackArg(getArgSVal(Idx), *I))
804f7df9beSJordan Rose       return true;
814f7df9beSJordan Rose   }
824f7df9beSJordan Rose 
834f7df9beSJordan Rose   return false;
844f7df9beSJordan Rose }
854f7df9beSJordan Rose 
864f7df9beSJordan Rose /// \brief Returns true if a type is a pointer-to-const or reference-to-const
874f7df9beSJordan Rose /// with no further indirection.
884f7df9beSJordan Rose static bool isPointerToConst(QualType Ty) {
894f7df9beSJordan Rose   QualType PointeeTy = Ty->getPointeeType();
904f7df9beSJordan Rose   if (PointeeTy == QualType())
914f7df9beSJordan Rose     return false;
924f7df9beSJordan Rose   if (!PointeeTy.isConstQualified())
934f7df9beSJordan Rose     return false;
944f7df9beSJordan Rose   if (PointeeTy->isAnyPointerType())
954f7df9beSJordan Rose     return false;
964f7df9beSJordan Rose   return true;
974f7df9beSJordan Rose }
984f7df9beSJordan Rose 
994f7df9beSJordan Rose // Try to retrieve the function declaration and find the function parameter
1004f7df9beSJordan Rose // types which are pointers/references to a non-pointer const.
1014f7df9beSJordan Rose // We will not invalidate the corresponding argument regions.
1024f7df9beSJordan Rose static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
1034f7df9beSJordan Rose                                  const CallEvent &Call) {
1044f7df9beSJordan Rose   unsigned Idx = 0;
1054f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = Call.param_type_begin(),
1064f7df9beSJordan Rose                                       E = Call.param_type_end();
1074f7df9beSJordan Rose        I != E; ++I, ++Idx) {
1084f7df9beSJordan Rose     if (isPointerToConst(*I))
1094f7df9beSJordan Rose       PreserveArgs.insert(Idx);
1104f7df9beSJordan Rose   }
1114f7df9beSJordan Rose }
1124f7df9beSJordan Rose 
1134f7df9beSJordan Rose ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
1144f7df9beSJordan Rose                                               ProgramStateRef Orig) const {
1154f7df9beSJordan Rose   ProgramStateRef Result = (Orig ? Orig : getState());
1164f7df9beSJordan Rose 
1174f7df9beSJordan Rose   SmallVector<const MemRegion *, 8> RegionsToInvalidate;
1184f7df9beSJordan Rose   getExtraInvalidatedRegions(RegionsToInvalidate);
1194f7df9beSJordan Rose 
1204f7df9beSJordan Rose   // Indexes of arguments whose values will be preserved by the call.
1214f7df9beSJordan Rose   llvm::SmallSet<unsigned, 1> PreserveArgs;
1224f7df9beSJordan Rose   if (!argumentsMayEscape())
1234f7df9beSJordan Rose     findPtrToConstParams(PreserveArgs, *this);
1244f7df9beSJordan Rose 
1254f7df9beSJordan Rose   for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
1264f7df9beSJordan Rose     if (PreserveArgs.count(Idx))
1274f7df9beSJordan Rose       continue;
1284f7df9beSJordan Rose 
1294f7df9beSJordan Rose     SVal V = getArgSVal(Idx);
1304f7df9beSJordan Rose 
1314f7df9beSJordan Rose     // If we are passing a location wrapped as an integer, unwrap it and
1324f7df9beSJordan Rose     // invalidate the values referred by the location.
1334f7df9beSJordan Rose     if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
1344f7df9beSJordan Rose       V = Wrapped->getLoc();
1354f7df9beSJordan Rose     else if (!isa<Loc>(V))
1364f7df9beSJordan Rose       continue;
1374f7df9beSJordan Rose 
1384f7df9beSJordan Rose     if (const MemRegion *R = V.getAsRegion()) {
1394f7df9beSJordan Rose       // Invalidate the value of the variable passed by reference.
1404f7df9beSJordan Rose 
1414f7df9beSJordan Rose       // Are we dealing with an ElementRegion?  If the element type is
1424f7df9beSJordan Rose       // a basic integer type (e.g., char, int) and the underlying region
1434f7df9beSJordan Rose       // is a variable region then strip off the ElementRegion.
1444f7df9beSJordan Rose       // FIXME: We really need to think about this for the general case
1454f7df9beSJordan Rose       //   as sometimes we are reasoning about arrays and other times
1464f7df9beSJordan Rose       //   about (char*), etc., is just a form of passing raw bytes.
1474f7df9beSJordan Rose       //   e.g., void *p = alloca(); foo((char*)p);
1484f7df9beSJordan Rose       if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
1494f7df9beSJordan Rose         // Checking for 'integral type' is probably too promiscuous, but
1504f7df9beSJordan Rose         // we'll leave it in for now until we have a systematic way of
1514f7df9beSJordan Rose         // handling all of these cases.  Eventually we need to come up
1524f7df9beSJordan Rose         // with an interface to StoreManager so that this logic can be
1534f7df9beSJordan Rose         // appropriately delegated to the respective StoreManagers while
1544f7df9beSJordan Rose         // still allowing us to do checker-specific logic (e.g.,
1554f7df9beSJordan Rose         // invalidating reference counts), probably via callbacks.
1564f7df9beSJordan Rose         if (ER->getElementType()->isIntegralOrEnumerationType()) {
1574f7df9beSJordan Rose           const MemRegion *superReg = ER->getSuperRegion();
1584f7df9beSJordan Rose           if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
1594f7df9beSJordan Rose               isa<ObjCIvarRegion>(superReg))
1604f7df9beSJordan Rose             R = cast<TypedRegion>(superReg);
1614f7df9beSJordan Rose         }
1624f7df9beSJordan Rose         // FIXME: What about layers of ElementRegions?
1634f7df9beSJordan Rose       }
1644f7df9beSJordan Rose 
1654f7df9beSJordan Rose       // Mark this region for invalidation.  We batch invalidate regions
1664f7df9beSJordan Rose       // below for efficiency.
1674f7df9beSJordan Rose       RegionsToInvalidate.push_back(R);
1684f7df9beSJordan Rose     }
1694f7df9beSJordan Rose   }
1704f7df9beSJordan Rose 
1714f7df9beSJordan Rose   // Invalidate designated regions using the batch invalidation API.
1724f7df9beSJordan Rose   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
1734f7df9beSJordan Rose   //  global variables.
1744f7df9beSJordan Rose   return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(),
1754f7df9beSJordan Rose                                    BlockCount, getLocationContext(),
1764f7df9beSJordan Rose                                    /*Symbols=*/0, this);
1774f7df9beSJordan Rose }
1784f7df9beSJordan Rose 
1794f7df9beSJordan Rose ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
1804f7df9beSJordan Rose                                         const ProgramPointTag *Tag) const {
1814f7df9beSJordan Rose   if (const Expr *E = getOriginExpr()) {
1824f7df9beSJordan Rose     if (IsPreVisit)
1834f7df9beSJordan Rose       return PreStmt(E, getLocationContext(), Tag);
1844f7df9beSJordan Rose     return PostStmt(E, getLocationContext(), Tag);
1854f7df9beSJordan Rose   }
1864f7df9beSJordan Rose 
1874f7df9beSJordan Rose   const Decl *D = getDecl();
1884f7df9beSJordan Rose   assert(D && "Cannot get a program point without a statement or decl");
1894f7df9beSJordan Rose 
1904f7df9beSJordan Rose   SourceLocation Loc = getSourceRange().getBegin();
1914f7df9beSJordan Rose   if (IsPreVisit)
1924f7df9beSJordan Rose     return PreImplicitCall(D, Loc, getLocationContext(), Tag);
1934f7df9beSJordan Rose   return PostImplicitCall(D, Loc, getLocationContext(), Tag);
1944f7df9beSJordan Rose }
1954f7df9beSJordan Rose 
19672ce8e2dSJordan Rose SVal CallEvent::getArgSVal(unsigned Index) const {
19772ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
19872ce8e2dSJordan Rose   if (!ArgE)
19972ce8e2dSJordan Rose     return UnknownVal();
20072ce8e2dSJordan Rose   return getSVal(ArgE);
20172ce8e2dSJordan Rose }
20272ce8e2dSJordan Rose 
20372ce8e2dSJordan Rose SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
20472ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
20572ce8e2dSJordan Rose   if (!ArgE)
20672ce8e2dSJordan Rose     return SourceRange();
20772ce8e2dSJordan Rose   return ArgE->getSourceRange();
20872ce8e2dSJordan Rose }
20972ce8e2dSJordan Rose 
21072ce8e2dSJordan Rose void CallEvent::dump(raw_ostream &Out) const {
21172ce8e2dSJordan Rose   ASTContext &Ctx = getState()->getStateManager().getContext();
21272ce8e2dSJordan Rose   if (const Expr *E = getOriginExpr()) {
21372ce8e2dSJordan Rose     E->printPretty(Out, Ctx, 0, Ctx.getPrintingPolicy());
21472ce8e2dSJordan Rose     Out << "\n";
21572ce8e2dSJordan Rose     return;
21672ce8e2dSJordan Rose   }
21772ce8e2dSJordan Rose 
21872ce8e2dSJordan Rose   if (const Decl *D = getDecl()) {
21972ce8e2dSJordan Rose     Out << "Call to ";
22072ce8e2dSJordan Rose     D->print(Out, Ctx.getPrintingPolicy());
22172ce8e2dSJordan Rose     return;
22272ce8e2dSJordan Rose   }
22372ce8e2dSJordan Rose 
22472ce8e2dSJordan Rose   // FIXME: a string representation of the kind would be nice.
22572ce8e2dSJordan Rose   Out << "Unknown call (type " << getKind() << ")";
22672ce8e2dSJordan Rose }
22772ce8e2dSJordan Rose 
2284f7df9beSJordan Rose 
2294f7df9beSJordan Rose bool CallEvent::mayBeInlined(const Stmt *S) {
23072ce8e2dSJordan Rose   // FIXME: Kill this.
23172ce8e2dSJordan Rose   return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)
23272ce8e2dSJordan Rose                           || isa<CXXConstructExpr>(S);
2334f7df9beSJordan Rose }
2344f7df9beSJordan Rose 
23542e8d649SJordan Rose static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
23642e8d649SJordan Rose                                          CallEvent::BindingsTy &Bindings,
23742e8d649SJordan Rose                                          SValBuilder &SVB,
23842e8d649SJordan Rose                                          const CallEvent &Call,
23942e8d649SJordan Rose                                          CallEvent::param_iterator I,
24042e8d649SJordan Rose                                          CallEvent::param_iterator E) {
24142e8d649SJordan Rose   MemRegionManager &MRMgr = SVB.getRegionManager();
2424f7df9beSJordan Rose 
24342e8d649SJordan Rose   unsigned Idx = 0;
24442e8d649SJordan Rose   for (; I != E; ++I, ++Idx) {
24542e8d649SJordan Rose     const ParmVarDecl *ParamDecl = *I;
24642e8d649SJordan Rose     assert(ParamDecl && "Formal parameter has no decl?");
2474f7df9beSJordan Rose 
24842e8d649SJordan Rose     SVal ArgVal = Call.getArgSVal(Idx);
24942e8d649SJordan Rose     if (!ArgVal.isUnknown()) {
25042e8d649SJordan Rose       Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx));
25142e8d649SJordan Rose       Bindings.push_back(std::make_pair(ParamLoc, ArgVal));
25242e8d649SJordan Rose     }
2534f7df9beSJordan Rose   }
2544f7df9beSJordan Rose 
25542e8d649SJordan Rose   // FIXME: Variadic arguments are not handled at all right now.
25642e8d649SJordan Rose }
25742e8d649SJordan Rose 
25842e8d649SJordan Rose 
25942e8d649SJordan Rose CallEvent::param_iterator AnyFunctionCall::param_begin() const {
26042e8d649SJordan Rose   const FunctionDecl *D = getDecl();
2614f7df9beSJordan Rose   if (!D)
2624f7df9beSJordan Rose     return 0;
2634f7df9beSJordan Rose 
26442e8d649SJordan Rose   return D->param_begin();
26542e8d649SJordan Rose }
26642e8d649SJordan Rose 
26742e8d649SJordan Rose CallEvent::param_iterator AnyFunctionCall::param_end() const {
26842e8d649SJordan Rose   const FunctionDecl *D = getDecl();
26942e8d649SJordan Rose   if (!D)
27042e8d649SJordan Rose     return 0;
27142e8d649SJordan Rose 
27242e8d649SJordan Rose   return D->param_end();
27342e8d649SJordan Rose }
27442e8d649SJordan Rose 
27542e8d649SJordan Rose void AnyFunctionCall::getInitialStackFrameContents(
27642e8d649SJordan Rose                                         const StackFrameContext *CalleeCtx,
27742e8d649SJordan Rose                                         BindingsTy &Bindings) const {
27842e8d649SJordan Rose   const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl());
27942e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
28042e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
28142e8d649SJordan Rose                                D->param_begin(), D->param_end());
2824f7df9beSJordan Rose }
2834f7df9beSJordan Rose 
2844f7df9beSJordan Rose QualType AnyFunctionCall::getDeclaredResultType() const {
2854f7df9beSJordan Rose   const FunctionDecl *D = getDecl();
2864f7df9beSJordan Rose   if (!D)
2874f7df9beSJordan Rose     return QualType();
2884f7df9beSJordan Rose 
2894f7df9beSJordan Rose   return D->getResultType();
2904f7df9beSJordan Rose }
2914f7df9beSJordan Rose 
2924f7df9beSJordan Rose bool AnyFunctionCall::argumentsMayEscape() const {
2934f7df9beSJordan Rose   if (hasNonZeroCallbackArg())
2944f7df9beSJordan Rose     return true;
2954f7df9beSJordan Rose 
2964f7df9beSJordan Rose   const FunctionDecl *D = getDecl();
2974f7df9beSJordan Rose   if (!D)
2984f7df9beSJordan Rose     return true;
2994f7df9beSJordan Rose 
3004f7df9beSJordan Rose   const IdentifierInfo *II = D->getIdentifier();
3014f7df9beSJordan Rose   if (!II)
3024f7df9beSJordan Rose     return true;
3034f7df9beSJordan Rose 
3044f7df9beSJordan Rose   // This set of "escaping" APIs is
3054f7df9beSJordan Rose 
3064f7df9beSJordan Rose   // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
3074f7df9beSJordan Rose   //   value into thread local storage. The value can later be retrieved with
3084f7df9beSJordan Rose   //   'void *ptheread_getspecific(pthread_key)'. So even thought the
3094f7df9beSJordan Rose   //   parameter is 'const void *', the region escapes through the call.
3104f7df9beSJordan Rose   if (II->isStr("pthread_setspecific"))
3114f7df9beSJordan Rose     return true;
3124f7df9beSJordan Rose 
3134f7df9beSJordan Rose   // - xpc_connection_set_context stores a value which can be retrieved later
3144f7df9beSJordan Rose   //   with xpc_connection_get_context.
3154f7df9beSJordan Rose   if (II->isStr("xpc_connection_set_context"))
3164f7df9beSJordan Rose     return true;
3174f7df9beSJordan Rose 
3184f7df9beSJordan Rose   // - funopen - sets a buffer for future IO calls.
3194f7df9beSJordan Rose   if (II->isStr("funopen"))
3204f7df9beSJordan Rose     return true;
3214f7df9beSJordan Rose 
3224f7df9beSJordan Rose   StringRef FName = II->getName();
3234f7df9beSJordan Rose 
3244f7df9beSJordan Rose   // - CoreFoundation functions that end with "NoCopy" can free a passed-in
3254f7df9beSJordan Rose   //   buffer even if it is const.
3264f7df9beSJordan Rose   if (FName.endswith("NoCopy"))
3274f7df9beSJordan Rose     return true;
3284f7df9beSJordan Rose 
3294f7df9beSJordan Rose   // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
3304f7df9beSJordan Rose   //   be deallocated by NSMapRemove.
3314f7df9beSJordan Rose   if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
3324f7df9beSJordan Rose     return true;
3334f7df9beSJordan Rose 
3344f7df9beSJordan Rose   // - Many CF containers allow objects to escape through custom
3354f7df9beSJordan Rose   //   allocators/deallocators upon container construction. (PR12101)
3364f7df9beSJordan Rose   if (FName.startswith("CF") || FName.startswith("CG")) {
3374f7df9beSJordan Rose     return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
3384f7df9beSJordan Rose            StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
3394f7df9beSJordan Rose            StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
3404f7df9beSJordan Rose            StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
3414f7df9beSJordan Rose            StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
3424f7df9beSJordan Rose            StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
3434f7df9beSJordan Rose   }
3444f7df9beSJordan Rose 
3454f7df9beSJordan Rose   return false;
3464f7df9beSJordan Rose }
3474f7df9beSJordan Rose 
3484f7df9beSJordan Rose 
3494f7df9beSJordan Rose const FunctionDecl *SimpleCall::getDecl() const {
3504f7df9beSJordan Rose   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
3514f7df9beSJordan Rose   if (D)
3524f7df9beSJordan Rose     return D;
3534f7df9beSJordan Rose 
3544f7df9beSJordan Rose   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
3554f7df9beSJordan Rose }
3564f7df9beSJordan Rose 
3574f7df9beSJordan Rose 
3584f7df9beSJordan Rose void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {
3594f7df9beSJordan Rose   if (const MemRegion *R = getCXXThisVal().getAsRegion())
3604f7df9beSJordan Rose     Regions.push_back(R);
3614f7df9beSJordan Rose }
3624f7df9beSJordan Rose 
3634f7df9beSJordan Rose static const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){
3644f7df9beSJordan Rose   const MemRegion *R = ThisVal.getAsRegion();
3654f7df9beSJordan Rose   if (!R)
3664f7df9beSJordan Rose     return 0;
3674f7df9beSJordan Rose 
3684f7df9beSJordan Rose   const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R->StripCasts());
3694f7df9beSJordan Rose   if (!TR)
3704f7df9beSJordan Rose     return 0;
3714f7df9beSJordan Rose 
3724f7df9beSJordan Rose   const CXXRecordDecl *RD = TR->getValueType()->getAsCXXRecordDecl();
3734f7df9beSJordan Rose   if (!RD)
3744f7df9beSJordan Rose     return 0;
3754f7df9beSJordan Rose 
3764f7df9beSJordan Rose   const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD);
3774f7df9beSJordan Rose   const FunctionDecl *Definition;
3784f7df9beSJordan Rose   if (!Result->hasBody(Definition))
3794f7df9beSJordan Rose     return 0;
3804f7df9beSJordan Rose 
3814f7df9beSJordan Rose   return cast<CXXMethodDecl>(Definition);
3824f7df9beSJordan Rose }
3834f7df9beSJordan Rose 
3844f7df9beSJordan Rose 
3854f7df9beSJordan Rose const Decl *CXXInstanceCall::getRuntimeDefinition() const {
3864f7df9beSJordan Rose   const Decl *D = SimpleCall::getRuntimeDefinition();
3874f7df9beSJordan Rose   if (!D)
3884f7df9beSJordan Rose     return 0;
3894f7df9beSJordan Rose 
3904f7df9beSJordan Rose   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
3914f7df9beSJordan Rose   if (!MD->isVirtual())
3924f7df9beSJordan Rose     return MD;
3934f7df9beSJordan Rose 
3944f7df9beSJordan Rose   // If the method is virtual, see if we can find the actual implementation
3954f7df9beSJordan Rose   // based on context-sensitivity.
396*1f8c0b45SJordan Rose   // FIXME: Virtual method calls behave differently when an object is being
397*1f8c0b45SJordan Rose   // constructed or destructed. It's not as simple as "no devirtualization"
398*1f8c0b45SJordan Rose   // because a /partially/ constructed object can be referred to through a
399*1f8c0b45SJordan Rose   // base pointer. We'll eventually want to use DynamicTypeInfo here.
4004f7df9beSJordan Rose   if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
4014f7df9beSJordan Rose     return Devirtualized;
4024f7df9beSJordan Rose 
4034f7df9beSJordan Rose   return 0;
4044f7df9beSJordan Rose }
4054f7df9beSJordan Rose 
40642e8d649SJordan Rose void CXXInstanceCall::getInitialStackFrameContents(
40742e8d649SJordan Rose                                             const StackFrameContext *CalleeCtx,
40842e8d649SJordan Rose                                             BindingsTy &Bindings) const {
40942e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
41042e8d649SJordan Rose 
41142e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
41242e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
41342e8d649SJordan Rose     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
41442e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
41542e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
41642e8d649SJordan Rose     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
41742e8d649SJordan Rose   }
41842e8d649SJordan Rose }
41942e8d649SJordan Rose 
42042e8d649SJordan Rose 
4214f7df9beSJordan Rose 
4224f7df9beSJordan Rose SVal CXXMemberCall::getCXXThisVal() const {
4234f7df9beSJordan Rose   const Expr *Base = getOriginExpr()->getImplicitObjectArgument();
4244f7df9beSJordan Rose 
4254f7df9beSJordan Rose   // FIXME: Will eventually need to cope with member pointers.  This is
4264f7df9beSJordan Rose   // a limitation in getImplicitObjectArgument().
4274f7df9beSJordan Rose   if (!Base)
4284f7df9beSJordan Rose     return UnknownVal();
4294f7df9beSJordan Rose 
4304f7df9beSJordan Rose   return getSVal(Base);
4314f7df9beSJordan Rose }
4324f7df9beSJordan Rose 
4334f7df9beSJordan Rose 
4344f7df9beSJordan Rose SVal CXXMemberOperatorCall::getCXXThisVal() const {
4354f7df9beSJordan Rose   const Expr *Base = getOriginExpr()->getArg(0);
4364f7df9beSJordan Rose   return getSVal(Base);
4374f7df9beSJordan Rose }
4384f7df9beSJordan Rose 
4394f7df9beSJordan Rose 
4404f7df9beSJordan Rose const BlockDataRegion *BlockCall::getBlockRegion() const {
4414f7df9beSJordan Rose   const Expr *Callee = getOriginExpr()->getCallee();
4424f7df9beSJordan Rose   const MemRegion *DataReg = getSVal(Callee).getAsRegion();
4434f7df9beSJordan Rose 
4444f7df9beSJordan Rose   return dyn_cast_or_null<BlockDataRegion>(DataReg);
4454f7df9beSJordan Rose }
4464f7df9beSJordan Rose 
44742e8d649SJordan Rose CallEvent::param_iterator BlockCall::param_begin() const {
4484f7df9beSJordan Rose   const BlockDecl *D = getBlockDecl();
4494f7df9beSJordan Rose   if (!D)
4504f7df9beSJordan Rose     return 0;
4514f7df9beSJordan Rose   return D->param_begin();
4524f7df9beSJordan Rose }
4534f7df9beSJordan Rose 
45442e8d649SJordan Rose CallEvent::param_iterator BlockCall::param_end() const {
4554f7df9beSJordan Rose   const BlockDecl *D = getBlockDecl();
4564f7df9beSJordan Rose   if (!D)
4574f7df9beSJordan Rose     return 0;
4584f7df9beSJordan Rose   return D->param_end();
4594f7df9beSJordan Rose }
4604f7df9beSJordan Rose 
4614f7df9beSJordan Rose void BlockCall::getExtraInvalidatedRegions(RegionList &Regions) const {
4624f7df9beSJordan Rose   // FIXME: This also needs to invalidate captured globals.
4634f7df9beSJordan Rose   if (const MemRegion *R = getBlockRegion())
4644f7df9beSJordan Rose     Regions.push_back(R);
4654f7df9beSJordan Rose }
4664f7df9beSJordan Rose 
46742e8d649SJordan Rose void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
46842e8d649SJordan Rose                                              BindingsTy &Bindings) const {
46942e8d649SJordan Rose   const BlockDecl *D = cast<BlockDecl>(CalleeCtx->getDecl());
47042e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
47142e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
47242e8d649SJordan Rose                                D->param_begin(), D->param_end());
47342e8d649SJordan Rose }
47442e8d649SJordan Rose 
47542e8d649SJordan Rose 
4764f7df9beSJordan Rose QualType BlockCall::getDeclaredResultType() const {
4774f7df9beSJordan Rose   const BlockDataRegion *BR = getBlockRegion();
4784f7df9beSJordan Rose   if (!BR)
4794f7df9beSJordan Rose     return QualType();
4804f7df9beSJordan Rose   QualType BlockTy = BR->getCodeRegion()->getLocationType();
4814f7df9beSJordan Rose   return cast<FunctionType>(BlockTy->getPointeeType())->getResultType();
4824f7df9beSJordan Rose }
4834f7df9beSJordan Rose 
4844f7df9beSJordan Rose 
4854f7df9beSJordan Rose SVal CXXConstructorCall::getCXXThisVal() const {
4864f7df9beSJordan Rose   if (Data)
4874f7df9beSJordan Rose     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
4884f7df9beSJordan Rose   return UnknownVal();
4894f7df9beSJordan Rose }
4904f7df9beSJordan Rose 
4914f7df9beSJordan Rose void CXXConstructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
4924f7df9beSJordan Rose   if (Data)
4934f7df9beSJordan Rose     Regions.push_back(static_cast<const MemRegion *>(Data));
4944f7df9beSJordan Rose }
4954f7df9beSJordan Rose 
49642e8d649SJordan Rose void CXXConstructorCall::getInitialStackFrameContents(
49742e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
49842e8d649SJordan Rose                                              BindingsTy &Bindings) const {
49942e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
50042e8d649SJordan Rose 
50142e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
50242e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
50342e8d649SJordan Rose     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
50442e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
50542e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
50642e8d649SJordan Rose     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
50742e8d649SJordan Rose   }
50842e8d649SJordan Rose }
50942e8d649SJordan Rose 
51042e8d649SJordan Rose 
5114f7df9beSJordan Rose 
5124f7df9beSJordan Rose SVal CXXDestructorCall::getCXXThisVal() const {
5134f7df9beSJordan Rose   if (Data)
5144f7df9beSJordan Rose     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
5154f7df9beSJordan Rose   return UnknownVal();
5164f7df9beSJordan Rose }
5174f7df9beSJordan Rose 
5184f7df9beSJordan Rose void CXXDestructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
5194f7df9beSJordan Rose   if (Data)
5204f7df9beSJordan Rose     Regions.push_back(static_cast<const MemRegion *>(Data));
5214f7df9beSJordan Rose }
5224f7df9beSJordan Rose 
5234f7df9beSJordan Rose const Decl *CXXDestructorCall::getRuntimeDefinition() const {
5244f7df9beSJordan Rose   const Decl *D = AnyFunctionCall::getRuntimeDefinition();
5254f7df9beSJordan Rose   if (!D)
5264f7df9beSJordan Rose     return 0;
5274f7df9beSJordan Rose 
5284f7df9beSJordan Rose   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
5294f7df9beSJordan Rose   if (!MD->isVirtual())
5304f7df9beSJordan Rose     return MD;
5314f7df9beSJordan Rose 
5324f7df9beSJordan Rose   // If the method is virtual, see if we can find the actual implementation
5334f7df9beSJordan Rose   // based on context-sensitivity.
534*1f8c0b45SJordan Rose   // FIXME: Virtual method calls behave differently when an object is being
535*1f8c0b45SJordan Rose   // constructed or destructed. It's not as simple as "no devirtualization"
536*1f8c0b45SJordan Rose   // because a /partially/ constructed object can be referred to through a
537*1f8c0b45SJordan Rose   // base pointer. We'll eventually want to use DynamicTypeInfo here.
5384f7df9beSJordan Rose   if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
5394f7df9beSJordan Rose     return Devirtualized;
5404f7df9beSJordan Rose 
5414f7df9beSJordan Rose   return 0;
5424f7df9beSJordan Rose }
5434f7df9beSJordan Rose 
54442e8d649SJordan Rose void CXXDestructorCall::getInitialStackFrameContents(
54542e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
54642e8d649SJordan Rose                                              BindingsTy &Bindings) const {
54742e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
5484f7df9beSJordan Rose 
54942e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
55042e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
55142e8d649SJordan Rose     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
55242e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
55342e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
55442e8d649SJordan Rose     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
55542e8d649SJordan Rose   }
5564f7df9beSJordan Rose }
5574f7df9beSJordan Rose 
55842e8d649SJordan Rose 
55942e8d649SJordan Rose CallEvent::param_iterator ObjCMethodCall::param_begin() const {
56042e8d649SJordan Rose   const ObjCMethodDecl *D = getDecl();
5614f7df9beSJordan Rose   if (!D)
5624f7df9beSJordan Rose     return 0;
5634f7df9beSJordan Rose 
56442e8d649SJordan Rose   return D->param_begin();
56542e8d649SJordan Rose }
56642e8d649SJordan Rose 
56742e8d649SJordan Rose CallEvent::param_iterator ObjCMethodCall::param_end() const {
56842e8d649SJordan Rose   const ObjCMethodDecl *D = getDecl();
56942e8d649SJordan Rose   if (!D)
57042e8d649SJordan Rose     return 0;
57142e8d649SJordan Rose 
57242e8d649SJordan Rose   return D->param_end();
5734f7df9beSJordan Rose }
5744f7df9beSJordan Rose 
5754f7df9beSJordan Rose void
5764f7df9beSJordan Rose ObjCMethodCall::getExtraInvalidatedRegions(RegionList &Regions) const {
5774f7df9beSJordan Rose   if (const MemRegion *R = getReceiverSVal().getAsRegion())
5784f7df9beSJordan Rose     Regions.push_back(R);
5794f7df9beSJordan Rose }
5804f7df9beSJordan Rose 
5814f7df9beSJordan Rose QualType ObjCMethodCall::getDeclaredResultType() const {
5824f7df9beSJordan Rose   const ObjCMethodDecl *D = getDecl();
5834f7df9beSJordan Rose   if (!D)
5844f7df9beSJordan Rose     return QualType();
5854f7df9beSJordan Rose 
5864f7df9beSJordan Rose   return D->getResultType();
5874f7df9beSJordan Rose }
5884f7df9beSJordan Rose 
5894f7df9beSJordan Rose SVal ObjCMethodCall::getReceiverSVal() const {
5904f7df9beSJordan Rose   // FIXME: Is this the best way to handle class receivers?
5914f7df9beSJordan Rose   if (!isInstanceMessage())
5924f7df9beSJordan Rose     return UnknownVal();
5934f7df9beSJordan Rose 
5944f7df9beSJordan Rose   if (const Expr *Base = getOriginExpr()->getInstanceReceiver())
5954f7df9beSJordan Rose     return getSVal(Base);
5964f7df9beSJordan Rose 
5974f7df9beSJordan Rose   // An instance message with no expression means we are sending to super.
5984f7df9beSJordan Rose   // In this case the object reference is the same as 'self'.
5994f7df9beSJordan Rose   const LocationContext *LCtx = getLocationContext();
6004f7df9beSJordan Rose   const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
6014f7df9beSJordan Rose   assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
6024f7df9beSJordan Rose   return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
6034f7df9beSJordan Rose }
6044f7df9beSJordan Rose 
6054f7df9beSJordan Rose SourceRange ObjCMethodCall::getSourceRange() const {
6064f7df9beSJordan Rose   switch (getMessageKind()) {
6074f7df9beSJordan Rose   case OCM_Message:
6084f7df9beSJordan Rose     return getOriginExpr()->getSourceRange();
6094f7df9beSJordan Rose   case OCM_PropertyAccess:
6104f7df9beSJordan Rose   case OCM_Subscript:
6114f7df9beSJordan Rose     return getContainingPseudoObjectExpr()->getSourceRange();
6124f7df9beSJordan Rose   }
6134f7df9beSJordan Rose   llvm_unreachable("unknown message kind");
6144f7df9beSJordan Rose }
6154f7df9beSJordan Rose 
6164f7df9beSJordan Rose typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
6174f7df9beSJordan Rose 
6184f7df9beSJordan Rose const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
6194f7df9beSJordan Rose   assert(Data != 0 && "Lazy lookup not yet performed.");
6204f7df9beSJordan Rose   assert(getMessageKind() != OCM_Message && "Explicit message send.");
6214f7df9beSJordan Rose   return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
6224f7df9beSJordan Rose }
6234f7df9beSJordan Rose 
6244f7df9beSJordan Rose ObjCMessageKind ObjCMethodCall::getMessageKind() const {
6254f7df9beSJordan Rose   if (Data == 0) {
6264f7df9beSJordan Rose     ParentMap &PM = getLocationContext()->getParentMap();
6274f7df9beSJordan Rose     const Stmt *S = PM.getParent(getOriginExpr());
6284f7df9beSJordan Rose     if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
6294f7df9beSJordan Rose       const Expr *Syntactic = POE->getSyntacticForm();
6304f7df9beSJordan Rose 
6314f7df9beSJordan Rose       // This handles the funny case of assigning to the result of a getter.
6324f7df9beSJordan Rose       // This can happen if the getter returns a non-const reference.
6334f7df9beSJordan Rose       if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
6344f7df9beSJordan Rose         Syntactic = BO->getLHS();
6354f7df9beSJordan Rose 
6364f7df9beSJordan Rose       ObjCMessageKind K;
6374f7df9beSJordan Rose       switch (Syntactic->getStmtClass()) {
6384f7df9beSJordan Rose       case Stmt::ObjCPropertyRefExprClass:
6394f7df9beSJordan Rose         K = OCM_PropertyAccess;
6404f7df9beSJordan Rose         break;
6414f7df9beSJordan Rose       case Stmt::ObjCSubscriptRefExprClass:
6424f7df9beSJordan Rose         K = OCM_Subscript;
6434f7df9beSJordan Rose         break;
6444f7df9beSJordan Rose       default:
6454f7df9beSJordan Rose         // FIXME: Can this ever happen?
6464f7df9beSJordan Rose         K = OCM_Message;
6474f7df9beSJordan Rose         break;
6484f7df9beSJordan Rose       }
6494f7df9beSJordan Rose 
6504f7df9beSJordan Rose       if (K != OCM_Message) {
6514f7df9beSJordan Rose         const_cast<ObjCMethodCall *>(this)->Data
6524f7df9beSJordan Rose           = ObjCMessageDataTy(POE, K).getOpaqueValue();
6534f7df9beSJordan Rose         assert(getMessageKind() == K);
6544f7df9beSJordan Rose         return K;
6554f7df9beSJordan Rose       }
6564f7df9beSJordan Rose     }
6574f7df9beSJordan Rose 
6584f7df9beSJordan Rose     const_cast<ObjCMethodCall *>(this)->Data
6594f7df9beSJordan Rose       = ObjCMessageDataTy(0, 1).getOpaqueValue();
6604f7df9beSJordan Rose     assert(getMessageKind() == OCM_Message);
6614f7df9beSJordan Rose     return OCM_Message;
6624f7df9beSJordan Rose   }
6634f7df9beSJordan Rose 
6644f7df9beSJordan Rose   ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
6654f7df9beSJordan Rose   if (!Info.getPointer())
6664f7df9beSJordan Rose     return OCM_Message;
6674f7df9beSJordan Rose   return static_cast<ObjCMessageKind>(Info.getInt());
6684f7df9beSJordan Rose }
6694f7df9beSJordan Rose 
67063282aefSAnna Zaks const Decl *ObjCMethodCall::getRuntimeDefinition() const {
67163282aefSAnna Zaks   const ObjCMessageExpr *E = getOriginExpr();
67263282aefSAnna Zaks   assert(E);
6735808eb80SAnna Zaks   Selector Sel = E->getSelector();
6744f7df9beSJordan Rose 
67563282aefSAnna Zaks   if (E->isInstanceMessage()) {
6765808eb80SAnna Zaks 
6775808eb80SAnna Zaks     // Find the the receiver type.
6785808eb80SAnna Zaks     const ObjCObjectPointerType *ReceiverT = 0;
6795808eb80SAnna Zaks     QualType SupersType = E->getSuperType();
6805808eb80SAnna Zaks     if (!SupersType.isNull()) {
6815808eb80SAnna Zaks       ReceiverT = cast<ObjCObjectPointerType>(SupersType.getTypePtr());
6825808eb80SAnna Zaks     } else {
68363282aefSAnna Zaks       const MemRegion *Receiver = getReceiverSVal().getAsRegion();
68463282aefSAnna Zaks       DynamicTypeInfo TI = getState()->getDynamicTypeInfo(Receiver);
6855808eb80SAnna Zaks       ReceiverT = dyn_cast<ObjCObjectPointerType>(TI.getType().getTypePtr());
6864f7df9beSJordan Rose     }
6874f7df9beSJordan Rose 
6885808eb80SAnna Zaks     // Lookup the method implementation.
6895808eb80SAnna Zaks     if (ReceiverT)
6905808eb80SAnna Zaks       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
6915808eb80SAnna Zaks         return IDecl->lookupPrivateMethod(Sel);
6925808eb80SAnna Zaks 
69363282aefSAnna Zaks   } else {
69463282aefSAnna Zaks     // This is a class method.
69563282aefSAnna Zaks     // If we have type info for the receiver class, we are calling via
69663282aefSAnna Zaks     // class name.
69763282aefSAnna Zaks     if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
69863282aefSAnna Zaks       // Find/Return the method implementation.
69963282aefSAnna Zaks       return IDecl->lookupPrivateClassMethod(Sel);
7004f7df9beSJordan Rose     }
70163282aefSAnna Zaks   }
70263282aefSAnna Zaks 
70363282aefSAnna Zaks   return 0;
7044f7df9beSJordan Rose }
7054f7df9beSJordan Rose 
70642e8d649SJordan Rose void ObjCMethodCall::getInitialStackFrameContents(
70742e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
70842e8d649SJordan Rose                                              BindingsTy &Bindings) const {
70942e8d649SJordan Rose   const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
71042e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
71142e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
71242e8d649SJordan Rose                                D->param_begin(), D->param_end());
71342e8d649SJordan Rose 
71442e8d649SJordan Rose   SVal SelfVal = getReceiverSVal();
71542e8d649SJordan Rose   if (!SelfVal.isUnknown()) {
71642e8d649SJordan Rose     const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
71742e8d649SJordan Rose     MemRegionManager &MRMgr = SVB.getRegionManager();
71842e8d649SJordan Rose     Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
71942e8d649SJordan Rose     Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
72042e8d649SJordan Rose   }
72142e8d649SJordan Rose }
72242e8d649SJordan Rose 
723fcd016e5SJordan Rose 
724fcd016e5SJordan Rose CallEventRef<SimpleCall>
725fcd016e5SJordan Rose CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
726fcd016e5SJordan Rose                                 const LocationContext *LCtx) {
727fcd016e5SJordan Rose   if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE))
728fcd016e5SJordan Rose     return create<CXXMemberCall>(MCE, State, LCtx);
729fcd016e5SJordan Rose 
730fcd016e5SJordan Rose   if (const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
731fcd016e5SJordan Rose     const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
732fcd016e5SJordan Rose     if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
733fcd016e5SJordan Rose       if (MD->isInstance())
734fcd016e5SJordan Rose         return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
735fcd016e5SJordan Rose 
736fcd016e5SJordan Rose   } else if (CE->getCallee()->getType()->isBlockPointerType()) {
737fcd016e5SJordan Rose     return create<BlockCall>(CE, State, LCtx);
738fcd016e5SJordan Rose   }
739fcd016e5SJordan Rose 
740fcd016e5SJordan Rose   // Otherwise, it's a normal function call, static member function call, or
741fcd016e5SJordan Rose   // something we can't reason about.
742fcd016e5SJordan Rose   return create<FunctionCall>(CE, State, LCtx);
743fcd016e5SJordan Rose }
744c2d249ceSJordan Rose 
745c2d249ceSJordan Rose 
746c2d249ceSJordan Rose CallEventRef<>
747c2d249ceSJordan Rose CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
748c2d249ceSJordan Rose                             ProgramStateRef State) {
749c2d249ceSJordan Rose   const LocationContext *ParentCtx = CalleeCtx->getParent();
750c2d249ceSJordan Rose   const LocationContext *CallerCtx = ParentCtx->getCurrentStackFrame();
751c2d249ceSJordan Rose   assert(CallerCtx && "This should not be used for top-level stack frames");
752c2d249ceSJordan Rose 
753c2d249ceSJordan Rose   const Stmt *CallSite = CalleeCtx->getCallSite();
754c2d249ceSJordan Rose 
755c2d249ceSJordan Rose   if (CallSite) {
756c2d249ceSJordan Rose     if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite))
757c2d249ceSJordan Rose       return getSimpleCall(CE, State, CallerCtx);
758c2d249ceSJordan Rose 
759c2d249ceSJordan Rose     switch (CallSite->getStmtClass()) {
760c2d249ceSJordan Rose     case Stmt::CXXConstructExprClass: {
761c2d249ceSJordan Rose       SValBuilder &SVB = State->getStateManager().getSValBuilder();
762c2d249ceSJordan Rose       const CXXMethodDecl *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
763c2d249ceSJordan Rose       Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
764c2d249ceSJordan Rose       SVal ThisVal = State->getSVal(ThisPtr);
765c2d249ceSJordan Rose 
766c2d249ceSJordan Rose       return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
767c2d249ceSJordan Rose                                    ThisVal.getAsRegion(), State, CallerCtx);
768c2d249ceSJordan Rose     }
769c2d249ceSJordan Rose     case Stmt::CXXNewExprClass:
770c2d249ceSJordan Rose       return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx);
771c2d249ceSJordan Rose     case Stmt::ObjCMessageExprClass:
772c2d249ceSJordan Rose       return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite),
773c2d249ceSJordan Rose                                State, CallerCtx);
774c2d249ceSJordan Rose     default:
775c2d249ceSJordan Rose       llvm_unreachable("This is not an inlineable statement.");
776c2d249ceSJordan Rose     }
777c2d249ceSJordan Rose   }
778c2d249ceSJordan Rose 
779c2d249ceSJordan Rose   // Fall back to the CFG. The only thing we haven't handled yet is
780c2d249ceSJordan Rose   // destructors, though this could change in the future.
781c2d249ceSJordan Rose   const CFGBlock *B = CalleeCtx->getCallSiteBlock();
782c2d249ceSJordan Rose   CFGElement E = (*B)[CalleeCtx->getIndex()];
783c2d249ceSJordan Rose   assert(isa<CFGImplicitDtor>(E) && "All other CFG elements should have exprs");
784c2d249ceSJordan Rose   assert(!isa<CFGTemporaryDtor>(E) && "We don't handle temporaries yet");
785c2d249ceSJordan Rose 
786c2d249ceSJordan Rose   SValBuilder &SVB = State->getStateManager().getSValBuilder();
787c2d249ceSJordan Rose   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
788c2d249ceSJordan Rose   Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
789c2d249ceSJordan Rose   SVal ThisVal = State->getSVal(ThisPtr);
790c2d249ceSJordan Rose 
791c2d249ceSJordan Rose   const Stmt *Trigger;
792c2d249ceSJordan Rose   if (const CFGAutomaticObjDtor *AutoDtor = dyn_cast<CFGAutomaticObjDtor>(&E))
793c2d249ceSJordan Rose     Trigger = AutoDtor->getTriggerStmt();
794c2d249ceSJordan Rose   else
795c2d249ceSJordan Rose     Trigger = Dtor->getBody();
796c2d249ceSJordan Rose 
797c2d249ceSJordan Rose   return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
798c2d249ceSJordan Rose                               State, CallerCtx);
799c2d249ceSJordan Rose }
800c2d249ceSJordan Rose 
801