summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Core/ObjCMessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/ObjCMessage.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ObjCMessage.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/ObjCMessage.cpp b/lib/StaticAnalyzer/Core/ObjCMessage.cpp
new file mode 100644
index 0000000..2e370d6
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/ObjCMessage.cpp
@@ -0,0 +1,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