blob: 53c71750136bf34c88d1c5ba2d7e3f00eb90b388 [file] [log] [blame]
Argyrios Kyrtzidis432424d2011-01-25 00:03:53 +00001//===- ObjCMessage.cpp - Wrapper for ObjC messages and dot syntax -*- C++ -*--//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines ObjCMessage which serves as a common wrapper for ObjC
11// message expressions or implicit messages for loading/storing ObjC properties.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/StaticAnalyzer/PathSensitive/ObjCMessage.h"
16
17using namespace clang;
18using namespace ento;
19
20QualType ObjCMessage::getType(ASTContext &ctx) const {
21 assert(isValid() && "This ObjCMessage is uninitialized!");
22 if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
23 return msgE->getType();
24 const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
25 if (isPropertySetter())
26 return ctx.VoidTy;
27 return propE->getType();
28}
29
30Selector ObjCMessage::getSelector() const {
31 assert(isValid() && "This ObjCMessage is uninitialized!");
32 if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
33 return msgE->getSelector();
34 const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
35 if (isPropertySetter())
36 return propE->getSetterSelector();
37 return propE->getGetterSelector();
38}
39
40const ObjCMethodDecl *ObjCMessage::getMethodDecl() const {
41 assert(isValid() && "This ObjCMessage is uninitialized!");
42 if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
43 return msgE->getMethodDecl();
44 const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
45 if (propE->isImplicitProperty())
46 return isPropertySetter() ? propE->getImplicitPropertySetter()
47 : propE->getImplicitPropertyGetter();
48 return 0;
49}
50
51const ObjCInterfaceDecl *ObjCMessage::getReceiverInterface() const {
52 assert(isValid() && "This ObjCMessage is uninitialized!");
53 if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
54 return msgE->getReceiverInterface();
55 const ObjCPropertyRefExpr *propE = cast<ObjCPropertyRefExpr>(MsgOrPropE);
56 if (propE->isClassReceiver())
57 return propE->getClassReceiver();
58 QualType recT;
59 if (const Expr *recE = getInstanceReceiver())
60 recT = recE->getType();
61 else {
62 assert(propE->isSuperReceiver());
63 recT = propE->getSuperReceiverType();
64 }
65 if (const ObjCObjectPointerType *Ptr = recT->getAs<ObjCObjectPointerType>())
66 return Ptr->getInterfaceDecl();
67 return 0;
68}
69
70const Expr *ObjCMessage::getArgExpr(unsigned i) const {
71 assert(isValid() && "This ObjCMessage is uninitialized!");
72 assert(i < getNumArgs() && "Invalid index for argument");
73 if (const ObjCMessageExpr *msgE = dyn_cast<ObjCMessageExpr>(MsgOrPropE))
74 return msgE->getArg(i);
75 assert(isPropertySetter());
76 if (const BinaryOperator *bop = dyn_cast<BinaryOperator>(OriginE))
77 if (bop->isAssignmentOp())
78 return bop->getRHS();
79 return 0;
80}
81
82QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const {
83 if (CallE) {
84 const Expr *Callee = CallE->getCallee();
85 if (const FunctionDecl *FD = State->getSVal(Callee).getAsFunctionDecl())
86 return FD->getResultType();
87 return CallE->getType();
88 }
89 return Msg.getResultType(ctx);
90}
91
92SVal CallOrObjCMessage::getArgSValAsScalarOrLoc(unsigned i) const {
93 assert(i < getNumArgs());
94 if (CallE) return State->getSValAsScalarOrLoc(CallE->getArg(i));
95 QualType argT = Msg.getArgType(i);
96 if (Loc::IsLocType(argT) || argT->isIntegerType())
97 return Msg.getArgSVal(i, State);
98 return UnknownVal();
99}