下面主要分析的是优化阶段和推导阶段的分析,前优化和后优化类似,所以就不具体再分析后优化;
1.将可以进行计算和拼接的简单的一元、二元表达式进行计算和拼接返回成为一个ScalarExpression(但变量和变量之间的是不能在preOptimize中进行合并的,这样的需要进行类型推导后才可以进行优化)
???????? 如:
???? $a=1+2*3+4 优化后$a=11
???????? $a=“123”+3 优化后$a =126
??? $b=2;$a=$b+3 ; 优化后$a=5;
???? $a=“a”.”b”.”c” 优化后 $a=“abc”
2.多个连接语句进行字符串拼接
???????? 如:
??? $a.=“aa”;
??? $b=“bb”;
??? $a.=$b.“dd”;
??? 优化后 $a=“aa”.”bb”.”dd”;数组优化同理
3.优化后的表达式,封装到上一级的表达式或者语句中,将语法树进行简化
?

?
?
例:$a=1+2*3+4
语法树:
?
?
?
(1)优化2*3 返回结果ScalarExpression(6),封装到上一级的BinaryOpExpression上

?
?
(2)优化1+6返回结果ScalarExpression(7),封装到上一级的BinaryOpExpression上

?
?
(3)优化1+6返回结果ScalarExpression(11),封装到上一级的AssignmentExpression上,最终把一颗大树优化为了一个赋值表达式

?
?
?
这里抽取一个一元表达式的作为例子进行分析(unary_op_expression.cpp):
class="cpp">/*
         解析一元表达式,并进行计算,计算出结果(reslut),然后返回
         一个scalarExpr(result),表达式;
         如果m_exp是一元或者二元表达式则返回原表达式;
*/
ExpressionPtr UnaryOpExpression::preOptimize(AnalysisResultConstPtr ar) {
  Variant value;
  Variant result;
 
  if (m_exp && ar->getPhase() >= AnalysisResult::FirstPreOptimize) {
       //T_UNSET : unset
    if (m_op == T_UNSET) {
      if (m_exp->isScalar() ||
          (m_exp->is(KindOfExpressionList) &&
           static_pointer_cast<ExpressionList>(m_exp)->getCount() == 0)) {
        recomputeEffects();
                   //返回一个null
        return CONSTANT("null");
      }
      return ExpressionPtr();
    }
  }
  //T_ISSET :isset
  if (m_op == T_ISSET && m_exp->is(KindOfExpressionList) &&
      static_pointer_cast<ExpressionList>(m_exp)->getListKind() ==
      ExpressionList::ListKindParam) {
    ExpressionListPtr el(static_pointer_cast<ExpressionList>(m_exp));
    result = true;
    int i = 0, n = el->getCount();
    for (; i < n; i++) {
                   //根据下标获取el列表下的expr
      ExpressionPtr e((*el)[i]);
           //如果e为空或e类型不是scalar 则break;
      if (!e || !e->isScalar() || !e->getScalarValue(value)) break;
      if (!isset(value)) {
        result = false;
      }
    }
         //遍历完最后一个expr时,然后返回一个result值,并且将作用域和类型保持与当前表达式一致
    if (i == n) {
      return replaceValue(makeScalarExpression(ar, result));
    }
  } else if (m_op != T_ARRAY &&
             m_exp &&
             m_exp->isScalar() &&
             m_exp->getScalarValue(value) &&
             preCompute(value, result)) {
    //非array ,并且m_exp不为空,m_exp是scalar类型, 调用preCompute返回计算后的result值
    //返回result的scalar表达式,并且修改作用域和类型与当前表达式一致
    return replaceValue(makeScalarExpression(ar, result));
  } else if (m_op == T_BOOL_CAST) {
    switch (m_exp->getKindOf()) {
      default: break;
           //表达式类型为KindOfBinaryOpExpression
      case KindOfBinaryOpExpression: {
                //获取caozuofu.html" target="_blank">操作符
        int op = static_pointer_cast<BinaryOpExpression>(m_exp)->getOp();
        switch (op) {
                     //OR
          case T_LOGICAL_OR:
                     //||
          case T_BOOLEAN_OR:
                     //AND
          case T_LOGICAL_AND:
                     //&&
          case T_BOOLEAN_AND:
                     //XOR
          case T_LOGICAL_XOR:
                     //instanceof
          case T_INSTANCEOF:
          case '<':
                     //<=
          case T_IS_SMALLER_OR_EQUAL:
          case '>':
                     //>=
          case T_IS_GREATER_OR_EQUAL:
                     //===
          case T_IS_IDENTICAL:
                     //!==
          case T_IS_NOT_IDENTICAL:
                     //==
          case T_IS_EQUAL:
                     //!= <>
          case T_IS_NOT_EQUAL:
                          //返回这个二元表达式
            return m_exp;
        }
        break;
      }
           //m_exp是个一元表达式
      case KindOfUnaryOpExpression: {
        int op = static_pointer_cast<UnaryOpExpression>(m_exp)->getOp();
        switch (op) {
                     //bool|boolean
          case T_BOOL_CAST:
          case '!':
                     //isset
          case T_ISSET:
                     //empty
          case T_EMPTY:
                     //print
          case T_PRINT:
                          //返回当前一元表达式
            return m_exp;
        }
        break;
      }
    }
  }
  return ExpressionPtr();
}
?
Infertype的主要作用是在pre-optimize的基础之上进行类型推衍,对表达式的类型、变量的类型进行推衍。并判断类型是否和上下文所期望的一致。形如$a = $b + $c ;这种形式,类型推衍将$b和$c的类型推衍成同一类型的然后再进行操作(post-optimize)。
Infertype的最基本操作包括BinaryOpExpression、AssignmentExpression、UnaryOpExpression。
1)根据functionscope对文件进行划分
2)获取functionscope下的statementlist,对statementlist进行遍历获取到每条statement。
3)对statement中的expression进行类型推衍,通过调用inferTypes(ar, type, coerce);方法分析出当前的expression是哪一种( AssignmentExpression 、scalarexpression等),在通过inferAndCheck()方法对表达式进行推衍和检查,最终得到表达式的类型。
4)将分析出的最小表达式的类型返回到上一级再次进行分析,直到分析出expression或者statement的类型。
?
下面有3个expression中的infertype的3个关键函数的实现分析:
inferAndCheck,checkTypesImpl,setTypes;
这3个函数的关系为:inferAndCheck=> checkTypesImpl=> setTypes
inferAndCheck 推导和检查类型(检查类型实现是checkTypesImpl,设置最终类型是setTypes);
以下是3个函数的实现具体的代码分析,在expression.cpp中:
?
/*
coerce是否强制转换
*/
TypePtr Expression::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
                                  bool coerce) {
  IMPLEMENT_INFER_AND_CHECK_ASSERT(getScope());
  ASSERT(type);
  resetTypes();
  //获取实际类型
  TypePtr actualType = inferTypes(ar, type, coerce);
  //通过传入的type判断是执行如下语句还是执行checkTypesImpl
  if (type->is(Type::KindOfSome) || type->is(Type::KindOfAny)) {
    m_actualType = actualType;
    m_expectedType.reset();
    return actualType;
  }
  //返回期望值
  return checkTypesImpl(ar, type, actualType, coerce);
}
??
TypePtr Expression::checkTypesImpl(AnalysisResultConstPtr ar,
                                   TypePtr expectedType,
                                   TypePtr actualType, bool coerce) {
  TypePtr ret;
  //返回实际类型
  actualType = propagateTypes(ar, actualType);
  ASSERT(actualType);
  //是否强转
  if (coerce) {
    ret = Type::Coerce(ar, expectedType, actualType);
         //设置实际和期望类型
    setTypes(ar, actualType, expectedType);
  } else {
    //返回期望类型,返回交集
    ret = Type::Intersection(ar, actualType, expectedType);
    setTypes(ar, actualType, ret);
  }
  ASSERT(ret);
  return ret;
}
??
//设置当前表达式的类型
//设置m_actualType 和m_expectedType
void Expression::setTypes(AnalysisResultConstPtr ar, TypePtr actualType,
                          TypePtr expectedType) {
  ASSERT(actualType);
  ASSERT(expectedType);
 
  m_actualType = actualType;
  //如果expectedType非any和some类型,那么将expectedType设置为期望类型,否则清空m_expectedType
  if (!expectedType->is(Type::KindOfAny) &&
      !expectedType->is(Type::KindOfSome)) {
    // store the expected type if it is not Any nor Some,
    // regardless of the actual type
    m_expectedType = expectedType;
  } else {
    m_expectedType.reset();
  }
 
  // This is a special case where Type::KindOfObject means any object.
  //m_expectedType是一个对象类型,并不是一个特殊对象时(如m_name=a,也就是class A,这是一个特殊对象)
  //并且实际类型是一个特殊对象
  if (m_expectedType && m_expectedType->is(Type::KindOfObject) &&
      !m_expectedType->isSpecificObject() &&
      m_actualType->isSpecificObject()) {
    m_expectedType.reset();
  }
  //如果m_actualType 是一个特殊对象,那么将它添加到文件作用域的依赖中
  if (m_actualType->isSpecificObject()) {
    boost::const_pointer_cast<AnalysisResult>(ar)->
      addClassDependency(getFileScope(), m_actualType->getName());
  }
}
?
强转Type::Coerce
秉持的思想是向大的类型转,存在以下几种类型:
①当有一种类型为KindOfVariant 那么返回Type::Variant。
②当type1为KindOfVoid ,type2为KindOfString、 KindOfArray、 KindOfObject返回type2的类型
③当type1为某一具体类型,type2为KindOfSome、 KindOfAny返回type1的类型
④当type1为KindOfString, type2为KindOfArray返回Type:: Sequence。
⑤当type1唯一确定为KindOfInteger,如果type2唯一确定为KindOfInteger,返回type2,否则如果type2唯一确定为KindOfDouble,返回Type::Numeric。
⑥当type为objcet返回父类。
?
如下都是类型推导的具体的代码分析:
Coerce是强转类型,实际类型和期望类型之间进行转换;
Intersection 取交集类型;
IsLegalCast判断2种类型是否一致;
isStandardObject 判断是否Object类型;
isSpecificObject 是否是特定的类型,如自定义类class A这样的类型;
isNonConvertibleType 是否是Object或者Array 的类型;
isNoObjectInvolved 判断是否是非对象类型(如果是Object或者Array,则返回false)
InferredObject 推导多态的返回类型;
Inferred 推导类型;
combinedArithmeticType 数字类型推导;
php转换cpp的输出内容;
强转的函数在type.cpp中,Type::Coerce,代码如下:
?
//强制转换 type1是期望类型 type2 是实际类型
TypePtr Type::Coerce(AnalysisResultConstPtr ar, TypePtr type1, TypePtr type2) {
  //type1和type2相同返回type1
  if (SameType(type1, type2)) return type1;
  //type1或type2是variant返回variant
  if (type1->m_kindOf == KindOfVariant ||
      type2->m_kindOf == KindOfVariant) return Type::Variant;
  //如果type1 包含了type2 则将type1 和type2 互换,保证type1是子集
  if (type1->m_kindOf > type2->m_kindOf) {
    TypePtr tmp = type1;
    type1 = type2;
    type2 = tmp;
  }
  //type1是void ,type2是string array object,那么返回type2
  if (type1->m_kindOf == KindOfVoid &&
      (type2->m_kindOf == KindOfString ||
       type2->m_kindOf == KindOfArray ||
       type2->m_kindOf == KindOfObject)) {
    return type2;
  }
  //type2是some any返回type1
  if (type2->m_kindOf == KindOfSome ||
      type2->m_kindOf == KindOfAny) return type1;
  //
  if (type2->m_kindOf & KindOfAuto) {
       //type1 必须是type2不包含auto类型
    if (type1->mustBe(type2->m_kindOf & ~KindOfAuto)) {
                   //type1不是string ,返回type1
      if (!(type1->m_kindOf & Type::KindOfString)) {
        return type1;
      }
      if (type2->m_kindOf == KindOfAutoSequence) {
        return Type::Sequence;
      }
           //获取type2类型,清除auto
      return GetType((KindOf)(type2->m_kindOf & ~KindOfAuto));
    }
    return Type::Variant;
  }
  // type1 type2都是integer,返回type2
  //type1 是integer,type2是double 返回Numeric
  if (type1->mustBe(KindOfInteger)) {
    if (type2->mustBe(KindOfInteger)) {
      return type2;
    } else if (type2->mustBe(KindOfDouble)) {
      return Type::Numeric;
    }
  }
  //type1 和type2必须是object
  if (type1->mustBe(Type::KindOfObject) &&
      type2->mustBe(Type::KindOfObject)) {
    //type1和type2名字为空返回本身
    if (type1->m_name.empty()) return type1;
    if (type2->m_name.empty()) return type2;
         //根据名字查找类并返回type
    ClassScopePtr cls1 = ar->findClass(type1->m_name);
         //cls1不重复,并且type2是他的父类,返回type2
    if (cls1 && !cls1->isRedeclaring() &&
        cls1->derivesFrom(ar, type2->m_name, true, false)) {
      return type2;
    }
         //cls2不重复,并且type1是他的父类,返回type1
    ClassScopePtr cls2 = ar->findClass(type2->m_name);
    if (cls2 && !cls2->isRedeclaring() &&
        cls2->derivesFrom(ar, type1->m_name, true, false)) {
      return type1;
    }
         //cls1 和cls2存在并且都不重复查找cls1或cls2的父类,并且返回
    if (cls1 && cls2 &&
        !cls1->isRedeclaring() && !cls2->isRedeclaring()) {
       //返回父类
      ClassScopePtr parent =
        ClassScope::FindCommonParent(ar, type1->m_name,
                                         type2->m_name);
      if (parent) {
                //创建父类的类型对象
        return Type::CreateObjectType(parent->getName());
      }
    }
    return Type::Object;
  }
 
  if (type1->mustBe(type2->m_kindOf)) {
    return type2;
  }
 
  CT_ASSERT(Type::KindOfString < Type::KindOfArray);
  if (type1->m_kindOf == Type::KindOfString &&
      type2->m_kindOf == Type::KindOfArray) {
    return Type::Sequence;
  }
 
  return Type::Variant;
}
??
TypePtr Type::Intersection(AnalysisResultConstPtr ar,
                           TypePtr from, TypePtr to) {
  // Special case: if we're casting to Some or Any, return the "from" type;
  // if we're casting to Variant, return Variant.
  //to 一般为期望值from一般为实际类型
  //to为some或any时,返回from
  if (to->m_kindOf == KindOfSome || to->m_kindOf == KindOfAny) {
    return from;
  } else if (to->m_kindOf == KindOfVariant) {
    return Variant;
  }
  //获取to和from的类型交际
  int resultKind = to->m_kindOf & from->m_kindOf;
  std::string resultName = "";
  //交集为object
  if (resultKind & KindOfObject) {
    // if they're the same, or we don't know one's name, then use
    // the other
    //to 和from的类型名字一致或者from 名字为空,resultName为to的名字
    if (to->m_name == from->m_name || from->m_name.empty()) {
      resultName = to->m_name;
    } else if (to->m_name.empty()) {
    //to 的名字为空,resultName为from的名字
      resultName = from->m_name;
    } else {
      // make sure there's a subclass relation
      //查找from的类
      ClassScopePtr cls = ar->findClass(from->m_name);
      if (cls) {
                 //判断to是否是from 的父类,如果是resultName设置为to的名字
        if (cls->derivesFrom(ar, to->m_name, true, false)) {
          resultName = to->m_name;
        } else {
          //不是则清空resultKind的KindOfObject类型
          resultKind &= ~KindOfObject;
        }
      }
    }
  }
 
  TypePtr res;
 
  // If there is overlap (for instance, they were the same, or we've narrowed
  // down something like Sequenece to be more specific), then return the
  // intersection of the types.
  if (resultKind) {
       //根据类型名称返回类型
    res = GetType(resultKind, resultName);
  } else if (from->mustBe(KindOfObject) && to->m_kindOf == KindOfPrimitive) {
     //from必须为对象类型,并且to的类型必须是string 或KindOfNumeric(不存在交集)
    // Special case Object -> Primitive: can we tostring it?
    //from名字不为空
    if (!from->m_name.empty()) {
                   //查找from的类,查找__tostring方法如果存在则返回ret为string
      ClassScopePtr cls = ar->findClass(from->m_name);
      if (cls && cls->findFunction(ar, "__tostring", true)) {
        res = Type::String;
      }
    }
 
    // Otherwise, return Int32
    res = Int32;
  } else if (from->m_kindOf == KindOfBoolean
             && to->mustBe(KindOfNumeric | KindOfArray | KindOfString)
             && !IsExactType(to->m_kindOf)) {
    res = Int32;
  } else {
    res = to;
  }
  //from 是boolean ,to是string 和KindOfNumeric 返回int32
  if (from->mustBe(KindOfBoolean) && to->m_kindOf == KindOfPrimitive) {
    res = Int32;
  }
 
  return res;
}
?
/* This new IsLegalCast returns true in a few cases where the old version * (which was basically a hardcoded truth table) returned false; it seems * like "true" is in fact the right thing to return. The cases that appear * when compiling www are: * Sequence -> Array * PlusOperand -> Array * String -> PlusOperand * Boolean -> PlusOperand */ //对比to和from类型是否相同 bool Type::IsLegalCast(AnalysisResultConstPtr ar, TypePtr from, TypePtr to) { if (!from->m_kindOf) return true; // since both 'from' and 'to' represent sets of types, we do // this by computing the set of types that we could possibly cast 'from' // to, and then determining whether that overlaps with 'to'. //给canCastTo加上boolean类型 int canCastTo = KindOfBoolean | from->m_kindOf; //判断from类型中是否有void,如果存在则canCastTo加上void if (from->m_kindOf & KindOfVoid) canCastTo |= KindOfVoid; // Boolean, Numeric, and String can all be cast among each other //判断from中是否有boolean ,数字型和字符串,如果存在给canCastTo加上数字型和字符串 if (from->m_kindOf & (KindOfBoolean | KindOfNumeric | KindOfString)) { canCastTo |= KindOfNumeric | KindOfString; } //判断from是否有对象型 if (from->m_kindOf & KindOfObject) { // Objects can only cast to string if they have __tostring //名字为空,添加上string性 if (from->m_name.empty()) { canCastTo |= KindOfString; // we don't know which class it is } else { //否则是类的对象类型,通过from名字查询cls ClassScopePtr cls = ar->findClass(from->m_name); if (!cls || cls->isRedeclaring() || cls->findFunction(ar, "__tostring", true)) { canCastTo |= KindOfString; } } // can only cast between objects if there's a subclass relation //to 的类型包含object并且类型名字不为空, //并且from类型名字不为空,并且to的m_name不等于from的m_name if ((to->m_kindOf & KindOfObject) && !to->m_name.empty() && !from->m_name.empty() && to->m_name != from->m_name) { //查找类 ClassScopePtr cls = ar->findClass(from->m_name); //类存在,并且类是重复的,将canCastTo的对象类型删除 if (cls && (cls->isRedeclaring() || !cls->derivesFrom(ar, to->m_name, true, true))) { canCastTo &= ~KindOfObject; } } } //判断to 的类型是否在canCastTo中 bool overlap = (to->m_kindOf & canCastTo); return overlap; }
?
//标准的Object,不是特定的class类
bool Type::isStandardObject() const {
  return m_kindOf == KindOfObject && m_name.empty();
}
?
//特殊的对象,kindof类型并且名字不为空,如class A ,这样类的类型就是
bool Type::isSpecificObject() const {
  return m_kindOf == KindOfObject && !m_name.empty();
}
?
???????????????????????????????????
bool Type::isNonConvertibleType() const {
  return m_kindOf == KindOfObject || m_kindOf == KindOfArray;
}
??
//判断不是一个对象,如果为array或object则返回false
bool Type::isNoObjectInvolved() const {
  if (couldBe(KindOfObject)
   || couldBe(KindOfArray))
    return false;
  else
    return true;
}
?
?
//推导2个类的类型中返回类型
TypePtr Type::InferredObject(AnalysisResultConstPtr ar,
                             TypePtr type1,
                             TypePtr type2) {
  ASSERT(type1->m_kindOf == KindOfObject);
  ASSERT(type2->m_kindOf == KindOfObject);
 
  TypePtr resultType = Type::Object;
  // if they're the same, or we don't know one's name, then use
  // the other
  //type1和type2的类型名字相等或者type1的名字为空
  if (type1->m_name == type2->m_name || type1->m_name.empty()) {
       //赋值resultType的类型为type2
    resultType = type2;
  } else if (type2->m_name.empty()) {
    //type2类型名为空,将resultType的类型设置为type1
    resultType = type1;
  } else {
    // take the subclass
    //获取2个类型的类
    ClassScopePtr cls1 = ar->findClass(type1->m_name);
    ClassScopePtr cls2 = ar->findClass(type2->m_name);
    bool c1ok = cls1 && !cls1->isRedeclaring();
    bool c2ok = cls2 && !cls2->isRedeclaring();
 
    if (c1ok && cls1->derivesFrom(ar, type2->m_name, true, false)) {
      resultType = type1;
    } else if (c2ok && cls2->derivesFrom(ar, type1->m_name, true, false)) {
      resultType = type2;
    } else if (c1ok && c2ok && cls1->derivedByDynamic() &&
               cls2->derivesFromRedeclaring()) {
      resultType = type2;
    } else {
      resultType = type1;
    }
  }
  return resultType;
}
??
/* We have inferred type1 and type2 as the actual types for the same
   expression.
   Check that the types are compatible (it cant be both a string and
   an integer, for example), and return the combined type. If they
   are not compatible, return a null pointer.
 */
 //判断2个类型是否一致
TypePtr Type::Inferred(AnalysisResultConstPtr ar,
                       TypePtr type1, TypePtr type2) {
  //判断type1或type2如果其中一个为空,返回另一个类型                     
  if (!type1) return type2;
  if (!type2) return type1;
  KindOf k1 = type1->m_kindOf;
  KindOf k2 = type2->m_kindOf;
 
  if (k1 == k2) {
       //k1 是object类型则返回推导类
    return k1 == KindOfObject ?
      Type:::InferredObject(ar, type1, type2) : type1;
  }
 
  // If one set is a subset of the other, return the subset.
  /*判断k1和k2谁是另一个类型的子集返回
         例k1 1111 k2 1011 ,那么k2是子集,k1包含k2,返回k2
    */
  if ((k1 & k2) == k1) return type1;
  if ((k1 & k2) == k2) return type2;
 
  // If one type must be numeric and the other might be, then assume numeric
  //type1 或type2中必须有一个是KindOfNumeric类型,并且另一个包含KindOfNumeric类型则返回某个type
  if (type1->mustBe(KindOfNumeric) && type2->couldBe(KindOfNumeric)) {
    return type1;
  }
  if (type2->mustBe(KindOfNumeric) && type1->couldBe(KindOfNumeric)) {
    return type2;
  }
 
  // Otherwise, take the intersection
  //如果是对象的返回对象类型
  int resultKind = type1->m_kindOf & type2->m_kindOf;
  if (resultKind == KindOfObject) {
    return Type::InferredObject(ar, type1, type2);
  }
  return resultKind ? GetType(resultKind) : TypePtr();
}
?
//数字运算的类型
/*
         t1 是Primitive,如果t2也是,如果t2>t1 返回t2否则t1;
         t1如果是double返回double否则是Numeric
         t2如果是double返回double否则是Numeric
         t1 或t2是Numeric 返回Numeric
         如果kind小于KindOfInt64 ,返回KindOfInt64
         否则都不符合返回空
*/
TypePtr Type::combinedArithmeticType(TypePtr t1, TypePtr t2) {
  KindOf kind = KindOfAny;
  //判断是否是array类型,是则返回空
  if (t1 && t1->is(Type::KindOfArray) ||
      t2 && t2->is(Type::KindOfArray)) {
    return TypePtr();
  }
  //Primitive是Numeric 和String的集合;
  //Numeric 是Double 和Integer的集合;
  //type1 是Primitive
  if (t1 && t1->isPrimitive()) {
       //t2也是Primitive
    if (t2 && t2->isPrimitive()) {
           //t2大于t1,返回t2 否则t1
           /*
                   例: t2:variant t1:int32  ,那么返回Variant
           */
      if (t2->getKindOf() > t1->getKindOf()) {
        kind = t2->getKindOf();
      } else {
        kind = t1->getKindOf();
      }
    } else if (t1->is(KindOfDouble)) {//t1是double返回double
      kind = KindOfDouble;
    } else {//否则返回Numeric
      kind = KindOfNumeric;
    }
  } else if (t2 && t2->isPrimitive()) {
    if (t2->is(KindOfDouble)) {
      kind = KindOfDouble;
    } else {
      kind = KindOfNumeric;
    }
  } else if ((t1 && t1->mustBe(KindOfNumeric)) ||
             (t2 && t2->mustBe(KindOfNumeric))) {
    kind = KindOfNumeric;
  }
 
  if (kind < KindOfInt64) {
    kind = KindOfInt64;
  }
 
  if (kind != KindOfAny) {
    return GetType(kind);
  }
 
  return TypePtr();
}
?
/* 获取c++ 的输出类型*/
string Type::getCPPDecl(AnalysisResultConstPtr ar,
                        BlockScopeRawPtr scope,
                        CodeGenerator *cg /* = 0 */) {
  switch (m_kindOf) {
    case KindOfBoolean:     return "bool";
    case KindOfInt32:       return "int";
    case KindOfInt64:       return "int64";
    case KindOfDouble:      return "double";
    case KindOfString:      return "String";
    case KindOfArray:       return "Array";
    case KindOfObject:{
      ClassScopePtr cls(getClass(ar, scope));
      if (!cls) return "Object";
      if (cg && cg->isFileOrClassHeader() && scope) {
        if (scope->getContainingClass()) {
          scope->getContainingClass()->addUsedClassHeader(cls);
        } else if (scope->getContainingFile()) {
          scope->getContainingFile()->addUsedClassHeader(cls);
        }
      }
           //Option::SmartPtrPrefix=> p_      返回值为p_类名
      return Option::SmartPtrPrefix + cls->getId();
    }
    case KindOfNumeric:     return "Numeric";
    case KindOfPrimitive:   return "Primitive";
    case KindOfPlusOperand: return "PlusOperand";
    case KindOfSequence:    return "Sequence";
    default:
      return "Variant";
  }
}
??
获取数据类型的函数
DataType Type::getDataType() const {
  switch (m_kindOf) {
    case KindOfBoolean:     return HPHP::KindOfBoolean;
    case KindOfInt32:
    case KindOfInt64:       return HPHP::KindOfInt64;
    case KindOfDouble:      return HPHP::KindOfDouble;
    case KindOfString:      return HPHP::KindOfString;
    case KindOfArray:       return HPHP::KindOfArray;
    case KindOfObject:      return HPHP::KindOfObject;
    case KindOfNumeric:
    case KindOfPrimitive:
    case KindOfPlusOperand:
    case KindOfSequence:
    default:                return HPHP::KindOfUnknown;
  }
}
??
//cpp输出声明类型
void Type::outputCPPDecl(CodeGenerator &cg, AnalysisResultConstPtr ar,
                         BlockScopeRawPtr scope) {
  cg_printf(getCPPDecl(ar, scope, &cg).c_str());
}
??
/*
         Php对象输出cpp类对象 p_类名
*/
void Type::outputCPPFastObjectCast(CodeGenerator &cg,
    AnalysisResultConstPtr ar,
    BlockScopeRawPtr scope,
    bool isConst) {
  ASSERT(isSpecificObject());
  ClassScopePtr cls(getClass(ar, scope));
  ASSERT(cls);
  const string &cppClsName = cls->getId();
  /*
  Option::SmartPtrPrefix        const p_类名
  */
  cg_printf("(%s%s%s&)",
            isConst ? "const " : "",
            Option::SmartPtrPrefix,
            cppClsName.c_str());
}
 
?
/*
         Php对应cpp 输出相应类型
*/
void Type::outputCPPCast(CodeGenerator &cg, AnalysisResultConstPtr ar,
                         BlockScopeRawPtr scope) {
  switch (m_kindOf) {
    case KindOfBoolean:     cg_printf("toBoolean");   break;
    case KindOfInt32:       cg_printf("toInt32");     break;
    case KindOfInt64:       cg_printf("toInt64");     break;
    case KindOfDouble:      cg_printf("toDouble");    break;
    case KindOfString:      cg_printf("toString");    break;
    case KindOfArray:       cg_printf("toArray");     break;
    case KindOfNumeric:     cg_printf("Numeric");     break;
    case KindOfPrimitive:   cg_printf("Primitive");   break;
    case KindOfPlusOperand: cg_printf("PlusOperand"); break;
    case KindOfSequence:    cg_printf("Sequence");    break;
    case KindOfObject: {
      ClassScopePtr cls(getClass(ar, scope));
      if (!cls) {
        cg_printf("toObject");
      } else {
        cg_printf("%s%s", Option::SmartPtrPrefix, cls->getId().c_str());
      }
      break;
    }
    default:
      cg_printf("Variant");
      break;
  }
}
??
//cpp 类型初始化内容
const char *Type::getCPPInitializer() {
  switch (m_kindOf) {
  case KindOfBoolean:     return "false";
  case KindOfInt32:
  case KindOfInt64:       return "0";
  case KindOfNumeric:
  case KindOfPrimitive:
  case KindOfPlusOperand: return "0";
  case KindOfDouble:      return "0.0";
  default:                return NULL;
  }
}
?
类型在type.h中,有如下的类型:
 
static const KindOf KindOfVoid       = 0x0001;
  static const KindOf KindOfBoolean    = 0x0002;
  static const KindOf KindOfInt32      = 0x0010;
  static const KindOf KindOfInt64      = 0x0020;
  static const KindOf KindOfDouble     = 0x0040;
  static const KindOf KindOfString     = 0x0080;
  static const KindOf KindOfArray      = 0x0100;
  static const KindOf KindOfObject     = 0x0200;   // with classname
  static const KindOf KindOfVariant    = 0xFFFF;
  /* This bit tells coerce that if the other type
     is already one of the specified types, it wont
     be modified.
     eg $a['foo'] = <whatever>
     If $a is already known to be string or array, it stays that way.
     If we coerce to Sequence, however, it would become Sequence, and
     hence Variant
  */
  static const KindOf KindOfAuto       = 0x0400;
  static const KindOf KindOfInteger = (KindOf)(KindOfInt64 | KindOfInt32);
  static const KindOf KindOfNumeric = (KindOf)(KindOfDouble | KindOfInteger);
  static const KindOf KindOfPrimitive = (KindOf)(KindOfNumeric | KindOfString);
  static const KindOf KindOfPlusOperand = (KindOf)(KindOfNumeric | KindOfArray);
  static const KindOf KindOfSequence = (KindOf)(KindOfString | KindOfArray);
  static const KindOf KindOfAutoSequence = (KindOf)(KindOfAuto |KindOfSequence);
  static const KindOf KindOfAutoObject = (KindOf)(KindOfAuto | KindOfObject);
  static const KindOf KindOfSome = (KindOf)0x7FFE;
  static const KindOf KindOfAny = (KindOf)0x7FFF;
  /**
   * Inferred types: types that a variable or a constant is sure to be.
   */
  static TypePtr Null;
  static TypePtr Boolean;
  static TypePtr Int32;
  static TypePtr Int64;
  static TypePtr Double;
  static TypePtr String;
  static TypePtr Array;
  static TypePtr Object;
  static TypePtr Variant;
  static TypePtr Numeric;
  static TypePtr PlusOperand;
  static TypePtr Primitive;
  static TypePtr Sequence;
  static TypePtr AutoSequence;
  static TypePtr AutoObject;
  static TypePtr Any;
  static TypePtr Some;
?