From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp (limited to 'clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp') diff --git a/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp b/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp new file mode 100644 index 0000000..65cdcd9 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp @@ -0,0 +1,90 @@ +//===- 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" +#include "clang/AST/DeclCXX.h" + +using namespace clang; +using namespace ento; + +QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const { + QualType resultTy; + bool isLVal = false; + + if (isObjCMessage()) { + resultTy = Msg.getResultType(ctx); + } else if (const CXXConstructExpr *Ctor = + CallE.dyn_cast()) { + resultTy = Ctor->getType(); + } else { + const CallExpr *FunctionCall = CallE.get(); + + isLVal = FunctionCall->isLValue(); + const Expr *Callee = FunctionCall->getCallee(); + if (const FunctionDecl *FD = State->getSVal(Callee, LCtx).getAsFunctionDecl()) + resultTy = FD->getResultType(); + else + resultTy = FunctionCall->getType(); + } + + if (isLVal) + resultTy = ctx.getPointerType(resultTy); + + return resultTy; +} + +SVal CallOrObjCMessage::getFunctionCallee() const { + assert(isFunctionCall()); + assert(!isCXXCall()); + const Expr *Fun = CallE.get()->getCallee()->IgnoreParens(); + return State->getSVal(Fun, LCtx); +} + +SVal CallOrObjCMessage::getCXXCallee() const { + assert(isCXXCall()); + const CallExpr *ActualCall = CallE.get(); + const Expr *callee = + cast(ActualCall)->getImplicitObjectArgument(); + + // FIXME: Will eventually need to cope with member pointers. This is + // a limitation in getImplicitObjectArgument(). + if (!callee) + return UnknownVal(); + + return State->getSVal(callee, LCtx); +} + +SVal +CallOrObjCMessage::getInstanceMessageReceiver(const LocationContext *LC) const { + assert(isObjCMessage()); + return Msg.getInstanceReceiverSVal(State, LC); +} + +const Decl *CallOrObjCMessage::getDecl() const { + if (isCXXCall()) { + const CXXMemberCallExpr *CE = + cast(CallE.dyn_cast()); + assert(CE); + return CE->getMethodDecl(); + } else if (isObjCMessage()) { + return Msg.getMethodDecl(); + } else if (isFunctionCall()) { + // In case of a C style call, use the path sensitive information to find + // the function declaration. + SVal CalleeVal = getFunctionCallee(); + return CalleeVal.getAsFunctionDecl(); + } + return 0; +} + -- cgit v1.2.3