2012-09-29 06:21:39 +08:00
|
|
|
//===--- ScopeInfo.cpp - Information about a semantic context -------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements FunctionScopeInfo and its subclasses, which contain
|
|
|
|
// information about a single function, block, lambda, or method body.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Sema/ScopeInfo.h"
|
|
|
|
#include "clang/AST/Decl.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/ExprCXX.h"
|
|
|
|
#include "clang/AST/ExprObjC.h"
|
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
using namespace sema;
|
|
|
|
|
|
|
|
void FunctionScopeInfo::Clear() {
|
|
|
|
HasBranchProtectedScope = false;
|
|
|
|
HasBranchIntoScope = false;
|
|
|
|
HasIndirectGoto = false;
|
|
|
|
|
|
|
|
SwitchStack.clear();
|
|
|
|
Returns.clear();
|
|
|
|
ErrorTrap.reset();
|
|
|
|
PossiblyUnreachableDiags.clear();
|
|
|
|
WeakObjectUses.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
|
|
|
|
if (PropE->isExplicitProperty())
|
|
|
|
return PropE->getExplicitProperty();
|
|
|
|
|
|
|
|
return PropE->getImplicitPropertyGetter();
|
|
|
|
}
|
|
|
|
|
|
|
|
FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
|
|
|
|
FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
|
|
|
|
E = E->IgnoreParenCasts();
|
|
|
|
|
|
|
|
const NamedDecl *D = 0;
|
|
|
|
bool IsExact = false;
|
|
|
|
|
|
|
|
switch (E->getStmtClass()) {
|
|
|
|
case Stmt::DeclRefExprClass:
|
|
|
|
D = cast<DeclRefExpr>(E)->getDecl();
|
|
|
|
IsExact = isa<VarDecl>(D);
|
|
|
|
break;
|
|
|
|
case Stmt::MemberExprClass: {
|
|
|
|
const MemberExpr *ME = cast<MemberExpr>(E);
|
|
|
|
D = ME->getMemberDecl();
|
|
|
|
IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Stmt::ObjCIvarRefExprClass: {
|
|
|
|
const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
|
|
|
|
D = IE->getDecl();
|
2012-10-02 04:34:04 +08:00
|
|
|
IsExact = IE->getBase()->isObjCSelfExpr();
|
2012-09-29 06:21:39 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Stmt::PseudoObjectExprClass: {
|
|
|
|
const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
|
|
|
|
const ObjCPropertyRefExpr *BaseProp =
|
|
|
|
dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
|
|
|
|
if (BaseProp) {
|
|
|
|
D = getBestPropertyDecl(BaseProp);
|
|
|
|
|
|
|
|
const Expr *DoubleBase = BaseProp->getBase();
|
|
|
|
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
|
|
|
|
DoubleBase = OVE->getSourceExpr();
|
|
|
|
|
2012-10-02 04:34:04 +08:00
|
|
|
IsExact = DoubleBase->isObjCSelfExpr();
|
2012-09-29 06:21:39 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return BaseInfoTy(D, IsExact);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
|
|
|
|
const ObjCPropertyRefExpr *PropE)
|
|
|
|
: Base(0, true), Property(getBestPropertyDecl(PropE)) {
|
|
|
|
|
|
|
|
if (PropE->isObjectReceiver()) {
|
|
|
|
const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
|
|
|
|
const Expr *E = OVE->getSourceExpr();
|
|
|
|
Base = getBaseInfo(E);
|
|
|
|
} else if (PropE->isClassReceiver()) {
|
|
|
|
Base.setPointer(PropE->getClassReceiver());
|
|
|
|
} else {
|
|
|
|
assert(PropE->isSuperReceiver());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
-Warc-repeated-use-of-weak: Check messages to property accessors as well.
Previously, [foo weakProp] was not being treated the same as foo.weakProp.
Now, for every explicit message send, we check if it's a property access,
and if so, if the property is weak. Then for every assignment of a
message, we have to do the same thing again.
This is a potentially expensive increase because determining whether a
method is a property accessor requires searching through the methods it
overrides. However, without it -Warc-repeated-use-of-weak will miss cases
from people who prefer not to use dot syntax. If this turns out to be
too expensive, we can try caching the result somewhere, or even lose
precision by not checking superclass methods. The warning is off-by-default,
though.
<rdar://problem/12407765>
llvm-svn: 165718
2012-10-12 00:06:21 +08:00
|
|
|
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
|
|
|
|
const ObjCPropertyDecl *Prop)
|
|
|
|
: Base(0, true), Property(Prop) {
|
|
|
|
if (BaseE)
|
|
|
|
Base = getBaseInfo(BaseE);
|
|
|
|
// else, this is a message accessing a property on super.
|
|
|
|
}
|
|
|
|
|
2012-09-29 06:21:39 +08:00
|
|
|
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
|
|
|
|
const DeclRefExpr *DRE)
|
|
|
|
: Base(0, true), Property(DRE->getDecl()) {
|
|
|
|
assert(isa<VarDecl>(Property));
|
|
|
|
}
|
|
|
|
|
|
|
|
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
|
|
|
|
const ObjCIvarRefExpr *IvarE)
|
|
|
|
: Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
|
|
|
|
}
|
|
|
|
|
-Warc-repeated-use-of-weak: Check messages to property accessors as well.
Previously, [foo weakProp] was not being treated the same as foo.weakProp.
Now, for every explicit message send, we check if it's a property access,
and if so, if the property is weak. Then for every assignment of a
message, we have to do the same thing again.
This is a potentially expensive increase because determining whether a
method is a property accessor requires searching through the methods it
overrides. However, without it -Warc-repeated-use-of-weak will miss cases
from people who prefer not to use dot syntax. If this turns out to be
too expensive, we can try caching the result somewhere, or even lose
precision by not checking superclass methods. The warning is off-by-default,
though.
<rdar://problem/12407765>
llvm-svn: 165718
2012-10-12 00:06:21 +08:00
|
|
|
void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
|
|
|
|
const ObjCPropertyDecl *Prop) {
|
|
|
|
assert(Msg && Prop);
|
|
|
|
WeakUseVector &Uses =
|
|
|
|
WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
|
|
|
|
Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
|
|
|
|
}
|
|
|
|
|
2012-09-29 06:21:39 +08:00
|
|
|
void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
|
2012-10-11 00:43:06 +08:00
|
|
|
E = E->IgnoreParenCasts();
|
2012-09-29 06:21:39 +08:00
|
|
|
|
|
|
|
if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
|
|
|
|
markSafeWeakUse(POE->getSyntacticForm());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
|
|
|
|
markSafeWeakUse(Cond->getTrueExpr());
|
|
|
|
markSafeWeakUse(Cond->getFalseExpr());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const BinaryConditionalOperator *Cond =
|
|
|
|
dyn_cast<BinaryConditionalOperator>(E)) {
|
|
|
|
markSafeWeakUse(Cond->getCommon());
|
|
|
|
markSafeWeakUse(Cond->getFalseExpr());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Has this weak object been seen before?
|
|
|
|
FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
|
|
|
|
if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
|
-Warc-repeated-use-of-weak: Check messages to property accessors as well.
Previously, [foo weakProp] was not being treated the same as foo.weakProp.
Now, for every explicit message send, we check if it's a property access,
and if so, if the property is weak. Then for every assignment of a
message, we have to do the same thing again.
This is a potentially expensive increase because determining whether a
method is a property accessor requires searching through the methods it
overrides. However, without it -Warc-repeated-use-of-weak will miss cases
from people who prefer not to use dot syntax. If this turns out to be
too expensive, we can try caching the result somewhere, or even lose
precision by not checking superclass methods. The warning is off-by-default,
though.
<rdar://problem/12407765>
llvm-svn: 165718
2012-10-12 00:06:21 +08:00
|
|
|
Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
|
2012-09-29 06:21:39 +08:00
|
|
|
else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
|
-Warc-repeated-use-of-weak: Check messages to property accessors as well.
Previously, [foo weakProp] was not being treated the same as foo.weakProp.
Now, for every explicit message send, we check if it's a property access,
and if so, if the property is weak. Then for every assignment of a
message, we have to do the same thing again.
This is a potentially expensive increase because determining whether a
method is a property accessor requires searching through the methods it
overrides. However, without it -Warc-repeated-use-of-weak will miss cases
from people who prefer not to use dot syntax. If this turns out to be
too expensive, we can try caching the result somewhere, or even lose
precision by not checking superclass methods. The warning is off-by-default,
though.
<rdar://problem/12407765>
llvm-svn: 165718
2012-10-12 00:06:21 +08:00
|
|
|
Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
|
2012-09-29 06:21:39 +08:00
|
|
|
else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
|
-Warc-repeated-use-of-weak: Check messages to property accessors as well.
Previously, [foo weakProp] was not being treated the same as foo.weakProp.
Now, for every explicit message send, we check if it's a property access,
and if so, if the property is weak. Then for every assignment of a
message, we have to do the same thing again.
This is a potentially expensive increase because determining whether a
method is a property accessor requires searching through the methods it
overrides. However, without it -Warc-repeated-use-of-weak will miss cases
from people who prefer not to use dot syntax. If this turns out to be
too expensive, we can try caching the result somewhere, or even lose
precision by not checking superclass methods. The warning is off-by-default,
though.
<rdar://problem/12407765>
llvm-svn: 165718
2012-10-12 00:06:21 +08:00
|
|
|
Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
|
|
|
|
else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(MsgE)) {
|
|
|
|
Uses = WeakObjectUses.end();
|
|
|
|
if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
|
|
|
|
if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
|
|
|
|
Uses =
|
|
|
|
WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
|
|
|
|
Prop));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-09-29 06:21:39 +08:00
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (Uses == WeakObjectUses.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Has there been a read from the object using this Expr?
|
|
|
|
FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
|
|
|
|
std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true));
|
|
|
|
if (ThisUse == Uses->second.rend())
|
|
|
|
return;
|
|
|
|
|
|
|
|
ThisUse->markSafe();
|
|
|
|
}
|
|
|
|
|
|
|
|
FunctionScopeInfo::~FunctionScopeInfo() { }
|
|
|
|
BlockScopeInfo::~BlockScopeInfo() { }
|
|
|
|
LambdaScopeInfo::~LambdaScopeInfo() { }
|