本文整理汇总了C++中ExpressionPtr类的典型用法代码示例。如果您正苦于以下问题:C++ ExpressionPtr类的具体用法?C++ ExpressionPtr怎么用?C++ ExpressionPtr使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ExpressionPtr类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ExpressionPtr
ExpressionPtr SimpleFunctionCall::preOptimize(AnalysisResultPtr ar) {
if (m_class) ar->preOptimize(m_class);
ar->preOptimize(m_nameExp);
ar->preOptimize(m_params);
if (ar->getPhase() != AnalysisResult::SecondPreOptimize) {
return ExpressionPtr();
}
// optimize away various "exists" functions, this may trigger
// dead code elimination and improve type-inference.
if (!m_class && 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();
// system constant
if (constants->isPresent(symbol)) {
return CONSTANT("true");
}
// user constant
BlockScopePtr block = ar->findConstantDeclarer(symbol);
// not found (i.e., undefined)
if (!block) {
if (symbol.find("::") == std::string::npos) {
return CONSTANT("false");
} else {
// e.g., defined("self::ZERO")
return ExpressionPtr();
}
}
constants = block->getConstants();
// already set to be dynamic
if (constants->isDynamic(symbol)) return ExpressionPtr();
ConstructPtr decl = constants->getValue(symbol);
ExpressionPtr constValue = dynamic_pointer_cast<Expression>(decl);
if (constValue->isScalar()) {
return CONSTANT("true");
} else {
return ExpressionPtr();
}
break;
}
case FunctionExistsFunction: {
const std::string &lname = Util::toLower(symbol);
if (Option::DynamicInvokeFunctions.find(lname) ==
Option::DynamicInvokeFunctions.end()) {
FunctionScopePtr func = ar->findFunction(lname);
if (!func) {
return CONSTANT("false");
} else if (!func->isVolatile()) {
return CONSTANT("true");
}
}
break;
}
case InterfaceExistsFunction: {
ClassScopePtr cls = ar->findClass(Util::toLower(symbol));
if (!cls || !cls->isInterface()) {
return CONSTANT("false");
} else if (!cls->isVolatile()) {
return CONSTANT("true");
}
break;
}
case ClassExistsFunction: {
ClassScopePtr cls = ar->findClass(Util::toLower(symbol));
if (!cls || cls->isInterface()) {
return CONSTANT("false");
} else if (!cls->isVolatile()) {
return CONSTANT("true");
}
break;
}
default:
ASSERT(false);
}
}
}
}
return ExpressionPtr();
}
示例2: getKidCount
void Construct::dumpNode(int spc, AnalysisResultConstPtr ar) {
int nkid = getKidCount();
const char *name = 0;
int type = 0;
std::string scontext = "";
std::string value = "";
std::string type_info = "";
unsigned id = 0;
ExpressionPtr idPtr = ExpressionPtr();
int ef = 0;
if (Statement *s = dynamic_cast<Statement*>(this)) {
Statement::KindOf stype = s->getKindOf();
name = Statement::Names[stype];
value = s->getName();
type = (int)stype;
} else if (Expression *e = dynamic_cast<Expression*>(this)) {
id = e->getCanonID();
idPtr = e->getCanonLVal();
ef = e->getLocalEffects();
Expression::KindOf etype = e->getKindOf();
name = Expression::Names[etype];
switch (etype) {
case Expression::KindOfSimpleFunctionCall:
value = static_cast<SimpleFunctionCall*>(e)->getName();
break;
case Expression::KindOfSimpleVariable:
value = static_cast<SimpleVariable*>(e)->getName();
break;
case Expression::KindOfConstantExpression:
value = e->getText();
break;
case Expression::KindOfScalarExpression:
value = e->getText();
break;
default: break;
}
int c = e->getContext();
if ((c & Expression::Declaration) == Expression::Declaration) {
scontext += "|Declaration";
} else if (c & Expression::LValue) {
scontext += "|LValue";
}
if (c & Expression::NoLValueWrapper) {
scontext += "|NoLValueWrapper";
}
if (c & Expression::RefValue) {
scontext += "|RefValue";
}
if (c & Expression::RefParameter) {
scontext += "|RefParameter";
}
if (c & Expression::DeepReference) {
scontext += "|DeepReference";
}
if (c & Expression::NoRefWrapper) {
scontext += "|NoRefWrapper";
}
if (c & Expression::ObjectContext) {
scontext += "|ObjectContext";
}
if (c & Expression::InParameterExpression) {
scontext += "|InParameterExpression";
}
if (c & Expression::ExistContext) {
scontext += "|ExistContext";
}
if (c & Expression::UnsetContext) {
scontext += "|UnsetContext";
}
if (c & Expression::AssignmentLHS) {
scontext += "|AssignmentLHS";
}
if (c & Expression::RefAssignmentLHS) {
scontext += "|RefAssignmentLHS";
}
if (c & Expression::DeepAssignmentLHS) {
scontext += "|DeepAssignmentLHS";
}
if (c & Expression::InvokeArgument) {
scontext += "|InvokeArgument";
}
if (c & Expression::OprLValue) {
scontext += "|OprLValue";
}
if (c & Expression::DeepOprLValue) {
scontext += "|DeepOprLValue";
}
if (c & Expression::AccessContext) {
scontext += "|AccessContext";
}
if (scontext != "") {
scontext = " (" + scontext.substr(1) + ")";
}
type = (int)etype;
//.........这里部分代码省略.........
示例3: while
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 &&
//.........这里部分代码省略.........
示例4: optimize
ExpressionPtr AssignmentExpression::preOptimize(AnalysisResultConstPtr ar) {
if (Option::EliminateDeadCode &&
ar->getPhase() >= AnalysisResult::FirstPreOptimize) {
// otherwise used & needed flags may not be up to date yet
ExpressionPtr rep = optimize(ar);
if (rep) return rep;
}
if (m_variable->getContainedEffects() & ~(CreateEffect|AccessorEffect)) {
return ExpressionPtr();
}
ExpressionPtr val = m_value;
while (val) {
if (val->is(KindOfExpressionList)) {
ExpressionListPtr el(static_pointer_cast<ExpressionList>(val));
val = el->listValue();
continue;
}
if (val->is(KindOfAssignmentExpression)) {
val = static_pointer_cast<AssignmentExpression>(val)->m_value;
continue;
}
break;
}
if (val && val->isScalar()) {
if (val != m_value) {
ExpressionListPtr rep(new ExpressionList(
getScope(), getLocation(),
ExpressionList::ListKindWrapped));
rep->addElement(m_value);
m_value = val->clone();
rep->addElement(static_pointer_cast<Expression>(shared_from_this()));
return replaceValue(rep);
}
if (!m_ref && m_variable->is(KindOfArrayElementExpression)) {
ArrayElementExpressionPtr ae(
static_pointer_cast<ArrayElementExpression>(m_variable));
ExpressionPtr avar(ae->getVariable());
ExpressionPtr aoff(ae->getOffset());
if (!aoff || aoff->isScalar()) {
avar = avar->getCanonLVal();
while (avar) {
if (avar->isScalar()) {
Variant v,o,r;
if (!avar->getScalarValue(v)) break;
if (!val->getScalarValue(r)) break;
try {
g_context->setThrowAllErrors(true);
if (aoff) {
if (!aoff->getScalarValue(o)) break;
if (v.isString()) {
if (!o.isInteger() ||
o.toInt64Val() < 0 ||
o.toInt64Val() >= v.toCStrRef().size()) {
// warnings should be raised...
break;
}
}
v.set(o, r);
} else {
v.append(r);
}
g_context->setThrowAllErrors(false);
} catch (...) {
break;
}
ExpressionPtr rep(
new AssignmentExpression(
getScope(), getLocation(),
m_variable->replaceValue(Clone(ae->getVariable())),
makeScalarExpression(ar, v), false));
if (!isUnused()) {
ExpressionListPtr el(
new ExpressionList(
getScope(), getLocation(),
ExpressionList::ListKindWrapped));
el->addElement(rep);
el->addElement(val);
rep = el;
}
return replaceValue(rep);
}
avar = avar->getCanonPtr();
}
g_context->setThrowAllErrors(false);
}
}
}
return ExpressionPtr();
}
示例5: switch
// foldConst() is callable from the parse phase as well as the analysis phase.
// We take advantage of this during the parse phase to reduce very simple
// expressions down to a single scalar and keep the parse tree smaller,
// especially in cases of long chains of binary operators. However, we limit
// the effectivness of this during parse to ensure that we eliminate only
// very simple scalars that don't require analysis in later phases. For now,
// that's just simply scalar values.
ExpressionPtr BinaryOpExpression::foldConst(AnalysisResultConstPtr ar) {
ExpressionPtr optExp;
Variant v1;
Variant v2;
if (!m_exp2->getScalarValue(v2)) {
if ((ar->getPhase() != AnalysisResult::ParseAllFiles) &&
m_exp1->isScalar() && m_exp1->getScalarValue(v1)) {
switch (m_op) {
case T_IS_IDENTICAL:
case T_IS_NOT_IDENTICAL:
if (v1.isNull()) {
return makeIsNull(ar, getLocation(), m_exp2,
m_op == T_IS_NOT_IDENTICAL);
}
break;
case T_LOGICAL_AND:
case T_BOOLEAN_AND:
case T_LOGICAL_OR:
case T_BOOLEAN_OR: {
ExpressionPtr rep =
v1.toBoolean() == (m_op == T_LOGICAL_AND ||
m_op == T_BOOLEAN_AND) ? m_exp2 : m_exp1;
rep = ExpressionPtr(
new UnaryOpExpression(
getScope(), getLocation(),
rep, T_BOOL_CAST, true));
rep->setActualType(Type::Boolean);
return replaceValue(rep);
}
case '+':
case '.':
case '*':
case '&':
case '|':
case '^':
if (m_exp2->is(KindOfBinaryOpExpression)) {
BinaryOpExpressionPtr binOpExp =
dynamic_pointer_cast<BinaryOpExpression>(m_exp2);
if (binOpExp->m_op == m_op && binOpExp->m_exp1->isScalar()) {
ExpressionPtr aExp = m_exp1;
ExpressionPtr bExp = binOpExp->m_exp1;
ExpressionPtr cExp = binOpExp->m_exp2;
m_exp1 = binOpExp = Clone(binOpExp);
m_exp2 = cExp;
binOpExp->m_exp1 = aExp;
binOpExp->m_exp2 = bExp;
if (ExpressionPtr optExp = binOpExp->foldConst(ar)) {
m_exp1 = optExp;
}
return static_pointer_cast<Expression>(shared_from_this());
}
}
break;
default:
break;
}
}
return ExpressionPtr();
}
if (m_exp1->isScalar()) {
if (!m_exp1->getScalarValue(v1)) return ExpressionPtr();
try {
ScalarExpressionPtr scalar1 =
dynamic_pointer_cast<ScalarExpression>(m_exp1);
ScalarExpressionPtr scalar2 =
dynamic_pointer_cast<ScalarExpression>(m_exp2);
// Some data, like the values of __CLASS__ and friends, are not available
// while we're still in the initial parse phase.
if (ar->getPhase() == AnalysisResult::ParseAllFiles) {
if ((scalar1 && scalar1->needsTranslation()) ||
(scalar2 && scalar2->needsTranslation())) {
return ExpressionPtr();
}
}
if (!Option::WholeProgram || !Option::ParseTimeOpts) {
// In the VM, don't optimize __CLASS__ if within a trait, since
// __CLASS__ is not resolved yet.
ClassScopeRawPtr clsScope = getOriginalClass();
if (clsScope && clsScope->isTrait()) {
if ((scalar1 && scalar1->getType() == T_CLASS_C) ||
(scalar2 && scalar2->getType() == T_CLASS_C)) {
return ExpressionPtr();
}
}
}
Variant result;
switch (m_op) {
case T_LOGICAL_XOR:
result = static_cast<bool>(v1.toBoolean() ^ v2.toBoolean());
break;
//.........这里部分代码省略.........
示例6: isUserFunction
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
}
//.........这里部分代码省略.........
示例7: always_assert
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;
//.........这里部分代码省略.........
示例8: hasEffect
bool ExpressionList::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
int state) {
if (m_kind == ListKindParam && !m_arrayElements) {
return Expression::preOutputCPP(cg, ar, state|StashKidVars);
}
unsigned n = m_exps.size();
bool inExpression = cg.inExpression();
if (!inExpression && (state & FixOrder)) {
return true;
}
cg.setInExpression(false);
bool ret = false;
if (m_arrayElements) {
/*
* would like to do:
* ret = Expression::preOutputCPP(cg, ar, state);
* but icc has problems with the generated code.
*/
ret = hasEffect();
} else if (n > 1 && m_kind == ListKindLeft) {
ret = true;
} else {
for (unsigned int i = 0; i < n; i++) {
if (m_exps[i]->preOutputCPP(cg, ar, 0)) {
ret = true;
break;
}
}
}
if (!inExpression) return ret;
cg.setInExpression(true);
if (!ret) {
if (state & FixOrder) {
preOutputStash(cg, ar, state);
return true;
}
return false;
}
cg.wrapExpressionBegin();
if (m_arrayElements) {
setCPPTemp(genCPPTemp(cg, ar));
outputCPPInternal(cg, ar, true, true);
} else {
unsigned ix = m_kind == ListKindLeft ? 0 : n - 1;
for (unsigned int i = 0; i < n; i++) {
ExpressionPtr e = m_exps[i];
e->preOutputCPP(cg, ar, 0);
if (i != ix) {
if (e->outputCPPUnneeded(cg, ar)) {
cg_printf(";\n");
}
e->setCPPTemp("/**/");
} else if (e->hasCPPTemp() && Type::SameType(e->getType(), getType())) {
setCPPTemp(e->cppTemp());
} else if (!i && n > 1) {
e->Expression::preOutputStash(cg, ar, state | FixOrder);
if (!(state & FixOrder)) {
cg_printf("id(%s);\n", e->cppTemp().c_str());
}
setCPPTemp(e->cppTemp());
}
}
}
return true;
}
示例9:
ExpressionPtr DepthFirstVisitor<Pre, OptVisitor>::visit(ExpressionPtr e) {
return e->preOptimize(this->m_data.m_ar);
}
示例10: inferTypesImpl
TypePtr AssignmentExpression::
inferTypesImpl(AnalysisResultPtr ar, TypePtr type, bool coerce,
ExpressionPtr variable,
ExpressionPtr value /* = ExpressionPtr() */) {
TypePtr ret = type;
if (value) {
if (coerce) {
ret = value->inferAndCheck(ar, type, coerce);
} else {
ret = value->inferAndCheck(ar, NEW_TYPE(Some), coerce);
}
}
BlockScopePtr scope = ar->getScope();
if (variable->is(Expression::KindOfConstantExpression)) {
// ...as in ClassConstant statement
ConstantExpressionPtr exp =
dynamic_pointer_cast<ConstantExpression>(variable);
bool p;
scope->getConstants()->check(exp->getName(), ret, true, ar, variable, p);
} else if (variable->is(Expression::KindOfDynamicVariable)) {
// simptodo: not too sure about this
ar->getFileScope()->setAttribute(FileScope::ContainsLDynamicVariable);
} else if (variable->is(Expression::KindOfSimpleVariable)) {
SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable);
if (var->getName() == "this" && ar->getClassScope()) {
if (ar->isFirstPass()) {
ar->getCodeError()->record(variable, CodeError::ReassignThis,
variable);
}
}
if (ar->getPhase() == AnalysisResult::LastInference && value) {
if (!value->getExpectedType()) {
value->setExpectedType(variable->getActualType());
}
}
}
// if the value may involve object, consider the variable as "referenced"
// so that objects are not destructed prematurely.
bool referenced = true;
if (value && value->isScalar()) referenced = false;
if (ret && ret->isNoObjectInvolved()) referenced = false;
if (referenced && variable->is(Expression::KindOfSimpleVariable)) {
SimpleVariablePtr var =
dynamic_pointer_cast<SimpleVariable>(variable);
const std::string &name = var->getName();
VariableTablePtr variables = ar->getScope()->getVariables();
variables->addReferenced(name);
}
TypePtr vt = variable->inferAndCheck(ar, ret, true);
if (!coerce && type->is(Type::KindOfAny)) {
ret = vt;
}
return ret;
}
示例11: test
void test(ExpressionPtr expr)
{
std::cout << "Before DNF: " << expr->toString() << std::endl;
std::cout << "After DNF : " << expr->getDNF()->toString() << std::endl << std::endl;
}
示例12: outputLineMap
void SimpleFunctionCall::outputCPPImpl(CodeGenerator &cg,
AnalysisResultPtr ar) {
bool linemap = outputLineMap(cg, ar, true);
if (!m_lambda.empty()) {
cg.printf("\"%s\"", m_lambda.c_str());
if (linemap) cg.printf(")");
return;
}
if (!m_class && m_className.empty()) {
if (m_type == DefineFunction && m_params && m_params->getCount() >= 2) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>((*m_params)[0]);
string varName;
if (name) {
varName = name->getIdentifier();
ExpressionPtr value = (*m_params)[1];
if (varName.empty()) {
cg.printf("throw_fatal(\"bad define\")");
} else if (m_dynamicConstant) {
cg.printf("g->declareConstant(\"%s\", g->%s%s, ",
varName.c_str(), Option::ConstantPrefix,
varName.c_str());
value->outputCPP(cg, ar);
cg.printf(")");
} else {
bool needAssignment = true;
bool isSystem = ar->getConstants()->isSystem(varName);
if (isSystem ||
((!ar->isConstantRedeclared(varName)) && value->isScalar())) {
needAssignment = false;
}
if (needAssignment) {
cg.printf("%s%s = ", Option::ConstantPrefix, varName.c_str());
value->outputCPP(cg, ar);
}
}
} else {
cg.printf("throw_fatal(\"bad define\")");
}
if (linemap) cg.printf(")");
return;
}
if (m_name == "func_num_args") {
cg.printf("num_args");
if (linemap) cg.printf(")");
return;
}
switch (m_type) {
case VariableArgumentFunction:
{
FunctionScopePtr func =
dynamic_pointer_cast<FunctionScope>(ar->getScope());
if (func) {
cg.printf("%s(", m_name.c_str());
func->outputCPPParamsCall(cg, ar, true);
if (m_params) {
cg.printf(",");
m_params->outputCPP(cg, ar);
}
cg.printf(")");
if (linemap) cg.printf(")");
return;
}
}
break;
case FunctionExistsFunction:
case ClassExistsFunction:
case InterfaceExistsFunction:
{
bool literalString = false;
string symbol;
if (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()) {
literalString = true;
symbol = name->getLiteralString();
}
}
}
if (literalString) {
switch (m_type) {
case FunctionExistsFunction:
{
const std::string &lname = Util::toLower(symbol);
bool dynInvoke = Option::DynamicInvokeFunctions.find(lname) !=
Option::DynamicInvokeFunctions.end();
if (!dynInvoke) {
FunctionScopePtr func = ar->findFunction(lname);
if (func) {
if (!func->isDynamic()) {
if (func->isRedeclaring()) {
const char *name = func->getName().c_str();
cg.printf("(%s->%s%s != invoke_failed_%s)",
cg.getGlobals(ar), Option::InvokePrefix,
//.........这里部分代码省略.........
示例13: reset
TypePtr SimpleFunctionCall::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
bool coerce) {
reset();
ConstructPtr self = shared_from_this();
// handling define("CONSTANT", ...);
if (!m_class && m_className.empty()) {
if (m_type == DefineFunction && m_params && m_params->getCount() >= 2) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>((*m_params)[0]);
string varName;
if (name) {
varName = name->getIdentifier();
if (!varName.empty()) {
ExpressionPtr value = (*m_params)[1];
TypePtr varType = value->inferAndCheck(ar, NEW_TYPE(Some), false);
ar->getDependencyGraph()->
addParent(DependencyGraph::KindOfConstant,
ar->getName(), varName, self);
ConstantTablePtr constants =
ar->findConstantDeclarer(varName)->getConstants();
if (constants != ar->getConstants()) {
if (value && !value->isScalar()) {
constants->setDynamic(ar, varName);
varType = Type::Variant;
}
if (constants->isDynamic(varName)) {
m_dynamicConstant = true;
ar->getScope()->getVariables()->
setAttribute(VariableTable::NeedGlobalPointer);
} else {
constants->setType(ar, varName, varType, true);
}
// in case the old 'value' has been optimized
constants->setValue(ar, varName, value);
}
return checkTypesImpl(ar, type, Type::Boolean, coerce);
}
}
if (varName.empty() && ar->isFirstPass()) {
ar->getCodeError()->record(self, CodeError::BadDefine, self);
}
} else if (m_type == ExtractFunction) {
ar->getScope()->getVariables()->forceVariants(ar);
}
}
FunctionScopePtr func;
// avoid raising both MissingObjectContext and UnknownFunction
bool errorFlagged = false;
if (!m_class && m_className.empty()) {
func = ar->findFunction(m_name);
} else {
ClassScopePtr cls = ar->resolveClass(m_className);
if (cls && cls->isVolatile()) {
ar->getScope()->getVariables()
->setAttribute(VariableTable::NeedGlobalPointer);
}
if (!cls || cls->isRedeclaring()) {
if (cls) {
m_redeclaredClass = true;
}
if (!cls && ar->isFirstPass()) {
ar->getCodeError()->record(self, CodeError::UnknownClass, self);
}
if (m_params) {
m_params->inferAndCheck(ar, NEW_TYPE(Some), false);
}
return checkTypesImpl(ar, type, Type::Variant, coerce);
}
m_derivedFromRedeclaring = cls->derivesFromRedeclaring();
m_validClass = true;
if (m_name == "__construct") {
// if the class is known, php will try to identify class-name ctor
func = cls->findConstructor(ar, true);
}
else {
func = cls->findFunction(ar, m_name, true, true);
}
if (func && !func->isStatic()) {
ClassScopePtr clsThis = ar->getClassScope();
FunctionScopePtr funcThis = ar->getFunctionScope();
if (!clsThis ||
(clsThis->getName() != m_className &&
!clsThis->derivesFrom(ar, m_className)) ||
funcThis->isStatic()) {
// set the method static to avoid "unknown method" runtime exception
if (Option::StaticMethodAutoFix && !func->containsThis()) {
func->setStaticMethodAutoFixed();
}
if (ar->isFirstPass()) {
ar->getCodeError()->record(self, CodeError::MissingObjectContext,
self);
errorFlagged = true;
}
//.........这里部分代码省略.........
示例14: Dump
void Type::Dump(ExpressionPtr exp) {
Dump(exp->getExpectedType(), "Expected: %s\t");
Dump(exp->getActualType(), "Actual: %s\n");
}
示例15: getKidCount
void Construct::dumpNode(int spc, AnalysisResultPtr ar) {
int nkid = getKidCount();
std::string name;
int type = 0;
std::string scontext = "";
std::string value = "";
std::string type_info = "";
unsigned id = 0;
ExpressionPtr idPtr = ExpressionPtr();
int ef = 0;
if (Statement *s = dynamic_cast<Statement*>(this)) {
Statement::KindOf stype = s->getKindOf();
switch (stype) {
case Statement::KindOfFunctionStatement:
name="FunctionStatement";
break;
case Statement::KindOfClassStatement:
name="ClassStatement";
break;
case Statement::KindOfInterfaceStatement:
name="InterfaceStatement";
break;
case Statement::KindOfClassVariable:
name="ClassVariable";
break;
case Statement::KindOfClassConstant:
name="ClassConstant";
break;
case Statement::KindOfMethodStatement:
name="MethodStatement";
break;
case Statement::KindOfStatementList:
name="StatementList";
break;
case Statement::KindOfBlockStatement:
name="BlockStatement";
break;
case Statement::KindOfIfBranchStatement:
name="IfBranchStatement";
break;
case Statement::KindOfIfStatement:
name="IfStatement";
break;
case Statement::KindOfWhileStatement:
name="WhileStatement";
break;
case Statement::KindOfDoStatement:
name="DoStatement";
break;
case Statement::KindOfForStatement:
name="ForStatement";
break;
case Statement::KindOfSwitchStatement:
name="SwitchStatement";
break;
case Statement::KindOfCaseStatement:
name="CaseStatement";
break;
case Statement::KindOfBreakStatement:
name="BreakStatement";
break;
case Statement::KindOfContinueStatement:
name="ContinueStatement";
break;
case Statement::KindOfReturnStatement:
name="ReturnStatement";
break;
case Statement::KindOfGlobalStatement:
name="GlobalStatement";
break;
case Statement::KindOfStaticStatement:
name="StaticStatement";
break;
case Statement::KindOfEchoStatement:
name="EchoStatement";
break;
case Statement::KindOfUnsetStatement:
name="UnsetStatement";
break;
case Statement::KindOfExpStatement:
name="ExpStatement";
break;
case Statement::KindOfForEachStatement:
name="ForEachStatement";
break;
case Statement::KindOfCatchStatement:
name="CatchStatement";
break;
case Statement::KindOfTryStatement:
name="TryStatement";
break;
case Statement::KindOfThrowStatement:
name="ThrowStatement";
break;
}
type = (int)stype;
} else if (Expression *e = dynamic_cast<Expression*>(this)) {
id = e->getCanonID();
idPtr = e->getCanonLVal();
//.........这里部分代码省略.........