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/Core/PathSensitive/ObjCMessage.h"
16 #include "clang/AST/DeclCXX.h"
18 using namespace clang;
21 QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const {
25 if (isObjCMessage()) {
26 resultTy = Msg.getResultType(ctx);
27 } else if (const CXXConstructExpr *Ctor =
28 CallE.dyn_cast<const CXXConstructExpr *>()) {
29 resultTy = Ctor->getType();
31 const CallExpr *FunctionCall = CallE.get<const CallExpr *>();
33 isLVal = FunctionCall->isLValue();
34 const Expr *Callee = FunctionCall->getCallee();
35 if (const FunctionDecl *FD = State->getSVal(Callee, LCtx).getAsFunctionDecl())
36 resultTy = FD->getResultType();
38 resultTy = FunctionCall->getType();
42 resultTy = ctx.getPointerType(resultTy);
47 SVal CallOrObjCMessage::getFunctionCallee() const {
48 assert(isFunctionCall());
50 const Expr *Fun = CallE.get<const CallExpr *>()->getCallee()->IgnoreParens();
51 return State->getSVal(Fun, LCtx);
54 SVal CallOrObjCMessage::getCXXCallee() const {
56 const CallExpr *ActualCall = CallE.get<const CallExpr *>();
58 cast<CXXMemberCallExpr>(ActualCall)->getImplicitObjectArgument();
60 // FIXME: Will eventually need to cope with member pointers. This is
61 // a limitation in getImplicitObjectArgument().
65 return State->getSVal(callee, LCtx);
69 CallOrObjCMessage::getInstanceMessageReceiver(const LocationContext *LC) const {
70 assert(isObjCMessage());
71 return Msg.getInstanceReceiverSVal(State, LC);
74 const Decl *CallOrObjCMessage::getDecl() const {
76 const CXXMemberCallExpr *CE =
77 cast<CXXMemberCallExpr>(CallE.dyn_cast<const CallExpr *>());
79 return CE->getMethodDecl();
80 } else if (isObjCMessage()) {
81 return Msg.getMethodDecl();
82 } else if (isFunctionCall()) {
83 // In case of a C style call, use the path sensitive information to find
84 // the function declaration.
85 SVal CalleeVal = getFunctionCallee();
86 return CalleeVal.getAsFunctionDecl();