本文整理汇总了C++中ExpressionPtr::getContext方法的典型用法代码示例。如果您正苦于以下问题:C++ ExpressionPtr::getContext方法的具体用法?C++ ExpressionPtr::getContext怎么用?C++ ExpressionPtr::getContext使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ExpressionPtr
的用法示例。
在下文中一共展示了ExpressionPtr::getContext方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: process
void DataFlowWalker::process(ExpressionPtr e, bool doAccessChains) {
if ((e->getContext() & (Expression::AssignmentLHS|Expression::OprLValue)) ||
(!doAccessChains && e->hasContext(Expression::AccessContext))) {
return;
}
switch (e->getKindOf()) {
case Expression::KindOfListAssignment:
processAccessChainLA(static_pointer_cast<ListAssignment>(e));
processAccess(e);
break;
case Expression::KindOfArrayElementExpression:
case Expression::KindOfObjectPropertyExpression:
if (!e->hasContext(Expression::AccessContext)) {
processAccessChain(e);
}
// fall through
case Expression::KindOfObjectMethodExpression:
case Expression::KindOfDynamicFunctionCall:
case Expression::KindOfSimpleFunctionCall:
case Expression::KindOfNewObjectExpression:
case Expression::KindOfIncludeExpression:
case Expression::KindOfSimpleVariable:
case Expression::KindOfDynamicVariable:
case Expression::KindOfStaticMemberExpression:
case Expression::KindOfConstantExpression:
processAccess(e);
break;
case Expression::KindOfAssignmentExpression:
case Expression::KindOfBinaryOpExpression:
case Expression::KindOfUnaryOpExpression: {
ExpressionPtr var = e->getStoreVariable();
if (var && var->getContext() & (Expression::AssignmentLHS|
Expression::OprLValue)) {
processAccessChain(var);
processAccess(var);
}
// fall through
}
default:
processAccess(e);
break;
}
}
示例2: isReadOnlyAccess
static bool isReadOnlyAccess(ExpressionPtr e) {
if (e->getContext() & (Expression::UnsetContext|
Expression::RefValue|
Expression::LValue)) {
return false;
}
switch (e->getKindOf()) {
case Expression::KindOfConstantExpression:
case Expression::KindOfSimpleVariable:
case Expression::KindOfArrayElementExpression:
case Expression::KindOfDynamicVariable:
return true;
default:
return false;
}
}
示例3: cloneForInlineRecur
static ExpressionPtr cloneForInlineRecur(InlineCloneInfo &info,
ExpressionPtr exp,
const std::string &prefix,
AnalysisResultConstPtr ar,
FunctionScopePtr scope) {
exp->getOriginalScope(); // make sure to cache the original scope
exp->setBlockScope(scope);
for (int i = 0, n = exp->getKidCount(); i < n; i++) {
if (ExpressionPtr k = exp->getNthExpr(i)) {
exp->setNthKid(i, cloneForInlineRecur(info, k, prefix, ar, scope));
}
}
StaticClassName *scn = dynamic_cast<StaticClassName*>(exp.get());
if (scn && scn->isStatic() && !info.staticClass.empty()) {
scn->resolveStatic(info.staticClass);
}
switch (exp->getKindOf()) {
case Expression::KindOfSimpleVariable:
{
SimpleVariablePtr sv(dynamic_pointer_cast<SimpleVariable>(exp));
if (sv->isSuperGlobal()) break;
string name;
if (sv->isThis()) {
if (!info.callWithThis) {
if (!sv->hasContext(Expression::ObjectContext)) {
exp = sv->makeConstant(ar, "null");
} else {
// This will produce the wrong error
// we really want a "throw_fatal" ast node.
exp = sv->makeConstant(ar, "null");
}
break;
}
if (info.localThis.empty()) break;
name = info.localThis;
} else {
name = prefix + sv->getName();
}
SimpleVariablePtr rep(new SimpleVariable(
exp->getScope(), exp->getLocation(), name));
rep->copyContext(sv);
rep->updateSymbol(SimpleVariablePtr());
rep->getSymbol()->setHidden();
// Conservatively set flags to prevent
// the alias manager from getting confused.
// On the next pass, it will correct the values,
// and optimize appropriately.
rep->getSymbol()->setUsed();
rep->getSymbol()->setReferenced();
if (exp->getContext() & (Expression::LValue|
Expression::RefValue|
Expression::RefParameter)) {
info.sepm[name] = rep;
}
exp = rep;
}
break;
case Expression::KindOfObjectMethodExpression:
{
FunctionCallPtr call(
static_pointer_cast<FunctionCall>(exp));
if (call->getFuncScope() == info.func) {
call->setNoInline();
}
break;
}
case Expression::KindOfSimpleFunctionCall:
{
SimpleFunctionCallPtr call(static_pointer_cast<SimpleFunctionCall>(exp));
call->addLateDependencies(ar);
call->setLocalThis(info.localThis);
if (call->getFuncScope() == info.func) {
call->setNoInline();
}
}
default:
break;
}
return exp;
}
示例4: updateAccess
/*
The classical use/def isnt quite enough here. There are two unusual
issues:
- the ref/non-ref issue.
An assignment to a var which is referenced doesnt end its
lifetime. In fact it could just be a "use" of the var. But it
also counts as a def.
- the destructor issue.
variables which might need to be destroyed later are technically
alive, but dont interfere with any other variables in the same state.
They /do/ interfere with any truly "live" variables, however.
These are "dying".
So we end up defining, use, kill, def and dying.
use : a read of the variable, an ordinary assignment if it could
be referenced
kill : an unset, a ref assignment, or, for non referenced vars, any assignment
def : ref or normal assignment
dying : a variable whose destructor is (partially/locally) anticipated.
*/
void LiveDict::updateAccess(ExpressionPtr e) {
int cls = e->getExprClass();
if (cls & Expression::Store) {
/*
Handled when we see the lhs
*/
return;
}
int eid = e->getCanonID();
int context = e->getContext();
bool unset = false;
bool store = false;
if (context & Expression::LValue && context & Expression::UnsetContext) {
unset = true;
} else if (context & Expression::AssignmentLHS) {
store = true;
}
if (e->is(Expression::KindOfSimpleVariable)) {
SimpleVariablePtr sv(static_pointer_cast<SimpleVariable>(e));
bool use = false, kill = false, def = false;
Symbol *sym = sv->getSymbol();
bool isReferenced =
e->isReferencedValid() ?
e->isReferenced() :
sym && sym->isReferenced();
bool isNeeded =
e->isNeededValid() ?
e->isNeeded() :
sym && sym->isNeeded();
if (unset) {
kill = true;
} else if (store) {
if (context & Expression::RefAssignmentLHS ||
(!m_am.hasWildRefs() && !isReferenced)) {
kill = true;
}
def = true;
} else if ((context & Expression::Declaration) == Expression::Declaration) {
// a global declaration
def = kill = true;
} else if (context & (Expression::LValue|
Expression::RefValue|
Expression::DeepReference|
Expression::UnsetContext|
Expression::OprLValue)) {
use = def = true;
} else {
use = true;
}
if (kill && (!sym || isNeeded || isReferenced) &&
!BitOps::get_bit(eid, m_altered) &&
!BitOps::get_bit(eid, m_available)) {
BitOps::set_bit(eid, m_dying, true);
}
if (use &&
!BitOps::get_bit(eid, m_altered) &&
!BitOps::get_bit(eid, m_available)) {
BitOps::set_bit(eid, m_anticipated, true);
e->setAnticipated();
}
if (kill) {
BitOps::set_bit(eid, m_altered, true);
BitOps::set_bit(eid, m_available, def);
} else if (def) {
BitOps::set_bit(eid, m_available, true);
}
if (!m_am.couldBeAliased(sv)) {
return;
}
} else if (!e->is(Expression::KindOfDynamicVariable) &&
(unset || (context & Expression::RefAssignmentLHS))) {
// An unset, or a reference assignment to anything other
// than a simple or dynamic variable can never affect a simple
//.........这里部分代码省略.........
示例5: analyzeProgram
//.........这里部分代码省略.........
if (m_name == "__construct") {
func = cls->findConstructor(ar, true);
} else {
func = cls->findFunction(ar, m_name, true, true);
}
}
}
if (func && !func->isRedeclaring()) {
if (m_funcScope != func) {
m_funcScope = func;
Construct::recomputeEffects();
}
}
if (cls && !cls->isRedeclaring())
m_classScope = cls;
}
// check for dynamic constant and volatile function/class
if (m_className.empty() &&
(m_type == DefinedFunction ||
m_type == FunctionExistsFunction ||
m_type == ClassExistsFunction ||
m_type == InterfaceExistsFunction) &&
m_params && m_params->getCount() >= 1) {
ExpressionPtr value = (*m_params)[0];
if (value->isScalar()) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>(value);
if (name && name->isLiteralString()) {
string symbol = name->getLiteralString();
switch (m_type) {
case DefinedFunction: {
ConstantTablePtr constants = ar->getConstants();
if (!constants->isPresent(symbol)) {
// user constant
BlockScopePtr block = ar->findConstantDeclarer(symbol);
if (block) { // found the constant
constants = block->getConstants();
// set to be dynamic
constants->setDynamic(ar, symbol);
}
}
break;
}
case FunctionExistsFunction: {
FunctionScopePtr func = ar->findFunction(Util::toLower(symbol));
if (func && func->isUserFunction()) {
func->setVolatile();
}
break;
}
case InterfaceExistsFunction:
case ClassExistsFunction: {
ClassScopePtr cls = ar->findClass(Util::toLower(symbol));
if (cls && cls->isUserClass()) {
cls->setVolatile();
}
break;
}
default:
ASSERT(false);
}
}
}
}
}
if (m_params) {
if (ar->getPhase() == AnalysisResult::AnalyzeAll) {
if (m_funcScope) {
ExpressionList ¶ms = *m_params;
int mpc = m_funcScope->getMaxParamCount();
for (int i = params.getCount(); i--; ) {
ExpressionPtr p = params[i];
if (i < mpc ? m_funcScope->isRefParam(i) :
m_funcScope->isReferenceVariableArgument()) {
p->setContext(Expression::RefValue);
} else if (!(p->getContext() & Expression::RefParameter)) {
p->clearContext(Expression::RefValue);
}
}
} else {
FunctionScopePtr func = ar->findFunction(m_name);
if (func && func->isRedeclaring()) {
FunctionScope::RefParamInfoPtr info =
FunctionScope::GetRefParamInfo(m_name);
if (info) {
for (int i = m_params->getCount(); i--; ) {
if (info->isRefParam(i)) {
m_params->markParam(i, canInvokeFewArgs());
}
}
}
} else {
m_params->markParams(false);
}
}
}
m_params->analyzeProgram(ar);
}
}
示例6: inferParamTypes
int FunctionScope::inferParamTypes(AnalysisResultPtr ar, ConstructPtr exp,
ExpressionListPtr params, bool &valid) {
if (!params) {
if (m_minParam > 0) {
if (ar->isFirstPass()) {
ar->getCodeError()->record(CodeError::TooFewArgument, exp, m_stmt);
}
valid = false;
setDynamic();
}
return 0;
}
int ret = 0;
if (params->getCount() < m_minParam) {
if (ar->isFirstPass()) {
ar->getCodeError()->record(CodeError::TooFewArgument, exp, m_stmt);
}
valid = false;
setDynamic();
}
if (params->getCount() > m_maxParam) {
if (isVariableArgument()) {
ret = params->getCount() - m_maxParam;
} else {
if (ar->isFirstPass()) {
ar->getCodeError()->record(CodeError::TooManyArgument, exp, m_stmt);
}
valid = false;
setDynamic();
}
}
bool canSetParamType = isUserFunction() && !m_overriding;
for (int i = 0; i < params->getCount(); i++) {
ExpressionPtr param = (*params)[i];
if (valid && param->hasContext(Expression::InvokeArgument)) {
param->clearContext(Expression::InvokeArgument);
param->clearContext(Expression::RefValue);
param->clearContext(Expression::NoRefWrapper);
}
TypePtr expType;
if (!canSetParamType && i < m_maxParam) {
expType = param->inferAndCheck(ar, getParamType(i), false);
} else {
expType = param->inferAndCheck(ar, NEW_TYPE(Some), false);
}
bool isRefVararg = (i >= m_maxParam && isReferenceVariableArgument());
if ((i < m_maxParam && isRefParam(i)) || isRefVararg) {
param->setContext(Expression::LValue);
param->setContext(Expression::RefValue);
param->inferAndCheck(ar, Type::Variant, true);
} else if (!(param->getContext() & Expression::RefParameter)) {
param->clearContext(Expression::LValue);
param->clearContext(Expression::RefValue);
param->clearContext(Expression::InvokeArgument);
param->clearContext(Expression::NoRefWrapper);
}
if (i < m_maxParam) {
if (m_paramTypeSpecs[i] && ar->isFirstPass()) {
if (!Type::Inferred(ar, expType, m_paramTypeSpecs[i])) {
const char *file = m_stmt->getLocation()->file;
Logger::Error("%s: parameter %d of %s requires %s, called with %s",
file, i, m_name.c_str(),
m_paramTypeSpecs[i]->toString().c_str(),
expType->toString().c_str());
ar->getCodeError()->record(CodeError::BadArgumentType, m_stmt);
}
}
TypePtr paramType = getParamType(i);
if (canSetParamType) {
paramType = setParamType(ar, i, expType);
}
if (!Type::IsLegalCast(ar, expType, paramType) &&
paramType->isNonConvertibleType()) {
param->inferAndCheck(ar, paramType, true);
}
param->setExpectedType(paramType);
}
// we do a best-effort check for bad pass-by-reference and do not report
// error for some vararg case (e.g., array_multisort can have either ref
// or value for the same vararg).
if (!isRefVararg || !isMixedVariableArgument()) {
Expression::checkPassByReference(ar, param);
}
}
return ret;
}
示例7: updateAccess
void ExprDict::updateAccess(ExpressionPtr e) {
int cls = e->getExprClass();
int eid = e->getCanonID();
e->clearAnticipated();
e->clearAvailable();
// bail on non-canonical expressions
if (!isCanonicalStructure(eid)) {
// but record we saw a type assertion belonging to this block
m_avlTypeAsserts.push_back(eid);
return;
}
if (m_anticipated &&
(cls & Expression::Update ?
!BitOps::get_bit(eid, m_altered) : !e->getLocalEffects())) {
/*
Anticipated can be computed bottom up as we go. But note that we
only know altered for Load/Store expressions.
*/
int i = e->getKidCount();
while (true) {
if (!i--) {
e->setAnticipated();
if (!e->hasContext(Expression::AssignmentLHS)) {
setStructureOps(eid, m_anticipated, true);
}
break;
}
if (ExpressionPtr k = e->getNthExpr(i)) {
if (!isCanonicalStructure(k->getCanonID())) continue;
if (!k->isAnticipated()) {
break;
}
}
}
}
if (m_available) {
/*
Available has to be computed optimistically, because we dont yet
know what is going to be altered between here and the end of the block
So keep a list of the potentially-available accesses (avlAccess), and
for each id, the last potentially-available expression (avlExpr).
For each modifying expression that we process, we remove expressions
from avlAccess, and at the end, we build up the available expressions
bottom up.
*/
if ((cls & (Expression::Store|Expression::Call)) ||
(cls & Expression::Load &&
e->getContext() & (Expression::LValue|
Expression::RefValue|
Expression::UnsetContext|
Expression::DeepReference))) {
bool isLoad;
int depth = 0, effects = 0;
for (int i = 0, n = m_avlAccess.size(); i < n; ) {
ExpressionRawPtr a = m_avlAccess[i];
if (m_am.checkAnyInterf(e, a, isLoad, depth, effects) !=
AliasManager::DisjointAccess) {
int aid = a->getCanonID();
assert(isCanonicalStructure(aid));
if (eid != aid || cls == Expression::Load) {
BitOps::set_bit(aid, m_altered, true);
}
if (!(cls & Expression::Store) ||
a != e->getStoreVariable()) {
a->clearAvailable();
m_avlAccess[i] = m_avlAccess[--n];
m_avlAccess.resize(n);
continue;
}
}
i++;
}
}
if (cls & Expression::Update ||
!e->getContainedEffects()) {
int i = e->getKidCount();
while (true) {
if (!i--) {
e->setAvailable();
if (cls & Expression::Update) {
m_avlAccess.push_back(e);
}
m_avlExpr[eid] = e;
break;
}
if (ExpressionPtr k = e->getNthExpr(i)) {
if (!isCanonicalStructure(k->getCanonID())) continue;
if (!k->isAvailable()) {
break;
}
}
}
}
}
if ((cls & (Expression::Store|Expression::Call)) ||
(cls & Expression::Load &&
//.........这里部分代码省略.........
示例8: updateAccess
void RefDict::updateAccess(ExpressionPtr e) {
always_assert(!e->getScope()->inPseudoMain());
int eid = e->getCanonID();
int context = e->getContext();
if (first_pass) {
if (!e->is(Expression::KindOfSimpleVariable) &&
!e->is(Expression::KindOfDynamicVariable)) return;
e->clearAvailable();
e->clearReferencedValid();
e->clearReferenced();
SimpleVariablePtr ptr(dynamic_pointer_cast<SimpleVariable>(e));
if (ptr && (ptr->isSuperGlobal() || ptr->isThis())) return;
if (e->is(Expression::KindOfSimpleVariable)) {
if (BitOps::get_bit(eid, m_referenced)) {
e->setReferenced();
} else if (!BitOps::get_bit(eid, m_killed)) {
// use as a temp place holder
e->setAvailable();
}
}
}
// let the first pass information propagate for both passes, since
// we need it in both contexts
if (context & Expression::RefAssignmentLHS ||
context & Expression::RefValue ||
context & Expression::RefParameter ||
((context & Expression::Declaration) == Expression::Declaration)) {
if (e->is(Expression::KindOfSimpleVariable)) {
BitOps::set_bit(eid, m_referenced, true);
BitOps::set_bit(eid, m_killed, false);
} else {
// for dynamic variables, we must assume the worst
BitOps::set(size(), m_referenced, -1);
BitOps::set(size(), m_killed, 0);
}
} else if (e->is(Expression::KindOfSimpleVariable) &&
context & Expression::LValue &&
context & Expression::UnsetContext) {
BitOps::set_bit(eid, m_referenced, false);
BitOps::set_bit(eid, m_killed, true);
}
if (first_pass) return;
// now we're on the second pass
if (context & Expression::AssignmentLHS ||
context & Expression::OprLValue) {
// we dealt with this node as a store expression
return;
}
int cls = e->getExprClass();
bool isRhsNeeded = false;
bool canKill = false;
ExpressionPtr lhs;
ExpressionPtr rhs;
if (cls & Expression::Store) {
// we care about two cases here
switch (e->getKindOf()) {
case Expression::KindOfAssignmentExpression:
// $x = ...
{
AssignmentExpressionPtr assign(
static_pointer_cast<AssignmentExpression>(e));
lhs = assign->getVariable();
rhs = assign->getValue();
isRhsNeeded = Expression::CheckNeededRHS(rhs);
canKill = true;
}
break;
case Expression::KindOfBinaryOpExpression:
// $x += ...
{
BinaryOpExpressionPtr binop(
static_pointer_cast<BinaryOpExpression>(e));
if (binop->getOp() == T_PLUS_EQUAL) {
lhs = binop->getExp1();
rhs = binop->getExp2();
isRhsNeeded = Expression::CheckNeededRHS(rhs);
}
}
break;
default:
break;
}
}
bool isLhsSimpleVar = false;
bool isLhsDynamic = false;
bool isRefd = false;
//.........这里部分代码省略.........
示例9: inferParamTypes
int FunctionScope::inferParamTypes(AnalysisResultPtr ar, ConstructPtr exp,
ExpressionListPtr params, bool &valid) {
if (!params) {
if (m_minParam > 0) {
if (exp->getScope()->isFirstPass()) {
Compiler::Error(Compiler::TooFewArgument, exp, m_stmt);
}
valid = false;
if (!Option::AllDynamic) setDynamic();
}
return 0;
}
int ret = 0;
if (params->getCount() < m_minParam) {
if (exp->getScope()->isFirstPass()) {
Compiler::Error(Compiler::TooFewArgument, exp, m_stmt);
}
valid = false;
if (!Option::AllDynamic) setDynamic();
}
if (params->getCount() > m_maxParam) {
if (isVariableArgument()) {
ret = params->getCount() - m_maxParam;
} else {
if (exp->getScope()->isFirstPass()) {
Compiler::Error(Compiler::TooManyArgument, exp, m_stmt);
}
valid = false;
if (!Option::AllDynamic) setDynamic();
}
}
bool canSetParamType = isUserFunction() && !m_overriding && !m_perfectVirtual;
for (int i = 0; i < params->getCount(); i++) {
ExpressionPtr param = (*params)[i];
if (i < m_maxParam && param->hasContext(Expression::RefParameter)) {
/**
* This should be very un-likely, since call time pass by ref is a
* deprecated, not very widely used (at least in FB codebase) feature.
*/
TRY_LOCK_THIS();
Symbol *sym = getVariables()->addSymbol(m_paramNames[i]);
sym->setLvalParam();
sym->setCallTimeRef();
}
if (valid && param->hasContext(Expression::InvokeArgument)) {
param->clearContext(Expression::InvokeArgument);
param->clearContext(Expression::RefValue);
param->clearContext(Expression::NoRefWrapper);
}
bool isRefVararg = (i >= m_maxParam && isReferenceVariableArgument());
if ((i < m_maxParam && isRefParam(i)) || isRefVararg) {
param->setContext(Expression::LValue);
param->setContext(Expression::RefValue);
param->inferAndCheck(ar, Type::Variant, true);
} else if (!(param->getContext() & Expression::RefParameter)) {
param->clearContext(Expression::LValue);
param->clearContext(Expression::RefValue);
param->clearContext(Expression::InvokeArgument);
param->clearContext(Expression::NoRefWrapper);
}
TypePtr expType;
/**
* Duplicate the logic of getParamType(i), w/o the mutation
*/
TypePtr paramType(i < m_maxParam && !isZendParamMode() ?
m_paramTypes[i] : TypePtr());
if (!paramType) paramType = Type::Some;
if (valid && !canSetParamType && i < m_maxParam &&
(!Option::HardTypeHints || !m_paramTypeSpecs[i])) {
/**
* What is this magic, you might ask?
*
* Here, we take advantage of implicit conversion from every type to
* Variant. Essentially, we don't really care what type comes out of this
* expression since it'll just get converted anyways. Doing it this way
* allows us to generate less temporaries along the way.
*/
TypePtr optParamType(paramType->is(Type::KindOfVariant) ?
Type::Some : paramType);
expType = param->inferAndCheck(ar, optParamType, false);
} else {
expType = param->inferAndCheck(ar, Type::Some, false);
}
if (i < m_maxParam) {
if (!Option::HardTypeHints || !m_paramTypeSpecs[i]) {
if (canSetParamType) {
if (!Type::SameType(paramType, expType) &&
!paramType->is(Type::KindOfVariant)) {
TRY_LOCK_THIS();
paramType = setParamType(ar, i, expType);
} else {
// do nothing - how is this safe? well, if we ever observe
// paramType == expType, then this means at some point in the past,
// somebody called setParamType() with expType. thus, by calling
// setParamType() again with expType, we contribute no "new"
// information. this argument also still applies in the face of
// concurrency
}
//.........这里部分代码省略.........
示例10: collectAliasInfoRecur
void AliasManager::collectAliasInfoRecur(ConstructPtr cs) {
if (!cs) {
return;
}
if (StatementPtr s = dpc(Statement, cs)) {
switch (s->getKindOf()) {
case Statement::KindOfFunctionStatement:
case Statement::KindOfMethodStatement:
case Statement::KindOfClassStatement:
case Statement::KindOfInterfaceStatement:
return;
default:
break;
}
}
int nkid = cs->getKidCount();
for (int i = 0; i < nkid; i++) {
ConstructPtr kid = cs->getNthKid(i);
if (kid) {
collectAliasInfoRecur(kid);
}
}
if (ExpressionPtr e = dpc(Expression, cs)) {
int context = e->getContext();
switch (e->getKindOf()) {
case Expression::KindOfAssignmentExpression:
{
AssignmentExpressionPtr ae = spc(AssignmentExpression, e);
ExpressionPtr var = ae->getVariable();
ExpressionPtr val = ae->getValue();
if (var->is(Expression::KindOfSimpleVariable)) {
const std::string &name = spc(SimpleVariable, var)->getName();
AliasInfo &ai = m_aliasInfo[name];
if (val->getContext() & Expression::RefValue) {
ai.setIsRefTo();
m_variables->addUsed(name);
} else {
Expression::checkUsed(m_arp, var, val);
}
}
}
break;
case Expression::KindOfListAssignment:
{
ListAssignmentPtr la = spc(ListAssignment, e);
ExpressionListPtr vars = la->getVariables();
for (int i = vars->getCount(); i--; ) {
ExpressionPtr v = (*vars)[i];
if (v && v->is(Expression::KindOfSimpleVariable)) {
SimpleVariablePtr sv = spc(SimpleVariable, v);
m_variables->addUsed(sv->getName());
}
}
}
break;
case Expression::KindOfSimpleVariable:
{
const std::string &name = spc(SimpleVariable, e)->getName();
if (context & Expression::RefValue) {
AliasInfo &ai = m_aliasInfo[name];
ai.addRefLevel(0);
}
if (!(context & (Expression::AssignmentLHS |
Expression::UnsetContext))) {
m_variables->addUsed(name);
}
}
break;
case Expression::KindOfDynamicVariable:
if (context & Expression::RefValue) {
m_wildRefs = true;
}
break;
case Expression::KindOfArrayElementExpression:
{
int n = 1;
while (n < 10 &&
e->is(Expression::KindOfArrayElementExpression)) {
e = spc(ArrayElementExpression, e)->getVariable();
}
if (e->is(Expression::KindOfSimpleVariable)) {
const std::string &name = spc(SimpleVariable, e)->getName();
if (context & Expression::RefValue) {
AliasInfo &ai = m_aliasInfo[name];
ai.addRefLevel(n);
}
m_variables->addUsed(name); // need this for UnsetContext
}
}
break;
case Expression::KindOfObjectPropertyExpression:
{
e = spc(ObjectPropertyExpression, e)->getObject();
if (e->is(Expression::KindOfSimpleVariable)) {
const std::string &name = spc(SimpleVariable, e)->getName();
if (context & Expression::RefValue) {
//.........这里部分代码省略.........
示例11: canonicalizeNode
ExpressionPtr AliasManager::canonicalizeNode(ExpressionPtr e) {
e->setCanonPtr(ExpressionPtr());
e->setCanonID(0);
switch (e->getKindOf()) {
case Expression::KindOfObjectMethodExpression:
case Expression::KindOfDynamicFunctionCall:
case Expression::KindOfSimpleFunctionCall:
case Expression::KindOfNewObjectExpression:
add(m_bucketMap[0], e);
break;
case Expression::KindOfListAssignment:
add(m_bucketMap[0], e);
break;
case Expression::KindOfAssignmentExpression: {
AssignmentExpressionPtr ae = spc(AssignmentExpression,e);
if (e->getContext() & Expression::DeadStore) {
Construct::recomputeEffects();
return ae->getValue();
}
ExpressionPtr rep;
int interf = findInterf(ae->getVariable(), false, rep);
if (interf == SameAccess) {
switch (rep->getKindOf()) {
default:
break;
case Expression::KindOfAssignmentExpression:
{
AssignmentExpressionPtr a = spc(AssignmentExpression, rep);
ExpressionPtr value = a->getValue();
if (a->getValue()->getContext() & Expression::RefValue) {
break;
}
}
case Expression::KindOfUnaryOpExpression:
case Expression::KindOfBinaryOpExpression:
rep->setContext(Expression::DeadStore);
break;
}
}
add(m_bucketMap[0], e);
break;
}
case Expression::KindOfConstantExpression:
case Expression::KindOfSimpleVariable:
case Expression::KindOfDynamicVariable:
case Expression::KindOfArrayElementExpression:
case Expression::KindOfObjectPropertyExpression:
case Expression::KindOfStaticMemberExpression:
if (!(e->getContext() & (Expression::AssignmentLHS|
Expression::DeepAssignmentLHS|
Expression::OprLValue))) {
if (!(e->getContext() & (Expression::LValue|
Expression::RefValue|
Expression::RefParameter|
Expression::UnsetContext))) {
ExpressionPtr rep;
int interf = findInterf(e, true, rep);
if (interf == SameAccess) {
if (rep->getKindOf() == e->getKindOf()) {
e->setCanonID(rep->getCanonID());
e->setCanonPtr(rep);
return ExpressionPtr();
}
if (rep->getKindOf() == Expression::KindOfAssignmentExpression) {
ExpressionPtr rhs = spc(AssignmentExpression,rep)->getValue();
if (rhs->is(Expression::KindOfScalarExpression)) {
rhs = rhs->clone();
getCanonical(rhs);
return rhs;
}
e->setCanonPtr(rhs);
}
}
}
add(m_bucketMap[0], e);
} else {
getCanonical(e);
}
break;
case Expression::KindOfBinaryOpExpression: {
BinaryOpExpressionPtr bop = spc(BinaryOpExpression, e);
int rop = getOpForAssignmentOp(bop->getOp());
if (rop) {
ExpressionPtr lhs = bop->getExp1();
ExpressionPtr rep;
if (bop->getContext() & Expression::DeadStore) {
Construct::recomputeEffects();
ExpressionPtr rhs = bop->getExp2()->clone();
lhs = lhs->clone();
lhs->clearContext(Expression::LValue);
lhs->clearContext(Expression::NoLValueWrapper);
lhs->clearContext(Expression::OprLValue);
rep = ExpressionPtr
(new BinaryOpExpression(e->getLocation(),
//.........这里部分代码省略.........