summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Core/ObjCMessage.cpp
blob: 2e370d62e44063d88cdf6affd8feb84a1fca1ff9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//===- ObjCMessage.cpp - Wrapper for ObjC messages and dot syntax -*- C++ -*--//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines ObjCMessage which serves as a common wrapper for ObjC
// message expressions or implicit messages for loading/storing ObjC properties.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"

using namespace clang;
using namespace ento;

QualType ObjCMessage::getType(ASTContext &ctx) const {
  assert(isValid() && "This ObjCMessage is uninitialized!");
  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
    return msgE->getType();
  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
  if (isPropertySetter())
    return ctx.VoidTy;
  return propE->getType();
}

Selector ObjCMessage::getSelector() const {
  assert(isValid() && "This ObjCMessage is uninitialized!");
  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
    return msgE->getSelector();
  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
  if (isPropertySetter())
    return propE->getSetterSelector();
  return propE->getGetterSelector();
}

const ObjCMethodDecl *ObjCMessage::getMethodDecl() const {
  assert(isValid() && "This ObjCMessage is uninitialized!");
  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
    return msgE->getMethodDecl();
  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
  if (propE->isImplicitProperty())
    return isPropertySetter() ? propE->getImplicitPropertySetter()
                              : propE->getImplicitPropertyGetter();
  return 0;
}

const ObjCInterfaceDecl *ObjCMessage::getReceiverInterface() const {
  assert(isValid() && "This ObjCMessage is uninitialized!");
  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
    return msgE->getReceiverInterface();
  const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
  if (propE->isClassReceiver())
    return propE->getClassReceiver();
  QualType recT;
  if (const Expr *recE = getInstanceReceiver())
    recT = recE->getType();
  else {
    assert(propE->isSuperReceiver());
    recT = propE->getSuperReceiverType();
  }
  if (const ObjCObjectPointerType *Ptr = recT->getAs<ObjCObjectPointerType>())
    return Ptr->getInterfaceDecl();
  return 0;
}

const Expr *ObjCMessage::getArgExpr(unsigned i) const {
  assert(isValid() && "This ObjCMessage is uninitialized!");
  assert(i < getNumArgs() && "Invalid index for argument");
  if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
    return msgE->getArg(i);
  assert(isPropertySetter());
  if (const BinaryOperator *bop = dyn_cast<BinaryOperator>(OriginE))
    if (bop->isAssignmentOp())
      return bop->getRHS();
  return 0;
}

QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const {
  if (CallE) {
    const Expr *Callee = CallE->getCallee();
    if (const FunctionDecl *FD = State->getSVal(Callee).getAsFunctionDecl())
      return FD->getResultType();
    return CallE->getType();
  }
  return Msg.getResultType(ctx);
}

SVal CallOrObjCMessage::getArgSValAsScalarOrLoc(unsigned i) const {
  assert(i < getNumArgs());
  if (CallE) return State->getSValAsScalarOrLoc(CallE->getArg(i));
  QualType argT = Msg.getArgType(i);
  if (Loc::isLocType(argT) || argT->isIntegerType())
    return Msg.getArgSVal(i, State);
  return UnknownVal();
}
OpenPOWER on IntegriCloud