1 //===- ObjCMessage.cpp - Wrapper for ObjC messages and dot syntax -*- C++ -*--//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines ObjCMessage which serves as a common wrapper for ObjC
11 // message expressions or implicit messages for loading/storing ObjC properties.
13 //===----------------------------------------------------------------------===//
15 #include "clang/StaticAnalyzer/PathSensitive/ObjCMessage.h"
17 using namespace clang
;
20 QualType
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())
27 return propE
->getType();
30 Selector
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();
40 const 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();
51 const 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();
59 if (const Expr
*recE
= getInstanceReceiver())
60 recT
= recE
->getType();
62 assert(propE
->isSuperReceiver());
63 recT
= propE
->getSuperReceiverType();
65 if (const ObjCObjectPointerType
*Ptr
= recT
->getAs
<ObjCObjectPointerType
>())
66 return Ptr
->getInterfaceDecl();
70 const 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())
82 QualType
CallOrObjCMessage::getResultType(ASTContext
&ctx
) const {
84 const Expr
*Callee
= CallE
->getCallee();
85 if (const FunctionDecl
*FD
= State
->getSVal(Callee
).getAsFunctionDecl())
86 return FD
->getResultType();
87 return CallE
->getType();
89 return Msg
.getResultType(ctx
);
92 SVal
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
);