diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-02-08 22:30:36 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-02-08 22:30:36 +0000 |
commit | 811d75ee35b8b061a9b10a4e7b81e0c0eaf739c3 (patch) | |
tree | 76064238268b854e8698c225b3eb44eefedd6559 /lib/StaticAnalyzer/Core/ObjCMessage.cpp | |
parent | a12a51701794a5ce96d47513ed186922e41eadd5 (diff) |
[analyzer] Move the files in lib/StaticAnalyzer to lib/StaticAnalyzer/Core.
Eventually there will also be a lib/StaticAnalyzer/Frontend that will handle initialization and checker registration.
Yet another library to avoid cyclic dependencies between Core and Checkers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125124 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ObjCMessage.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ObjCMessage.cpp | 99 |
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 0000000000..53c7175013 --- /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/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(); +} |