More fixing lint: various conversion constructors in compiler/
[hiphop-php.git] / hphp / compiler / analysis / type.h
blob5f6dcbfbfd7201b4c57e35d3431c3ec4f09872a2
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_TYPE_H_
18 #define incl_HPHP_TYPE_H_
20 #include <compiler/hphp.h>
21 #include <util/json.h>
22 #include <util/case_insensitive.h>
23 #include <runtime/base/types.h>
26 class TestCodeRun;
27 class TestCodeError;
28 struct ProgramOptions;
29 int process(const ProgramOptions&);
31 namespace HPHP {
32 ///////////////////////////////////////////////////////////////////////////////
34 class CodeGenerator;
35 DECLARE_BOOST_TYPES(Expression);
36 DECLARE_BOOST_TYPES(AnalysisResult);
37 DECLARE_BOOST_TYPES(Type);
38 DECLARE_BOOST_TYPES(BlockScope);
39 DECLARE_BOOST_TYPES(ClassScope);
41 class Type : public JSON::CodeError::ISerializable,
42 public JSON::DocTarget::ISerializable {
43 friend class ::TestCodeRun;
44 friend class ::TestCodeError;
45 public:
46 typedef int KindOf;
48 static const KindOf KindOfVoid = 0x0001;
49 static const KindOf KindOfBoolean = 0x0002;
50 static const KindOf KindOfInt32 = 0x0010;
51 static const KindOf KindOfInt64 = 0x0020;
52 static const KindOf KindOfDouble = 0x0040;
53 static const KindOf KindOfString = 0x0080;
54 static const KindOf KindOfArray = 0x0100;
55 static const KindOf KindOfObject = 0x0200; // with classname
56 static const KindOf KindOfVariant = 0xFFFF;
58 /* This bit tells coerce that if the other type
59 is already one of the specified types, it wont
60 be modified.
61 eg $a['foo'] = <whatever>
62 If $a is already known to be string or array, it stays that way.
63 If we coerce to Sequence, however, it would become Sequence, and
64 hence Variant
66 static const KindOf KindOfAuto = 0x0400;
68 static const KindOf KindOfInteger = (KindOf)(KindOfInt64 | KindOfInt32);
69 static const KindOf KindOfNumeric = (KindOf)(KindOfDouble | KindOfInteger);
70 static const KindOf KindOfPrimitive = (KindOf)(KindOfNumeric | KindOfString);
71 static const KindOf KindOfPlusOperand = (KindOf)(KindOfNumeric | KindOfArray);
72 static const KindOf KindOfSequence = (KindOf)(KindOfString | KindOfArray);
74 static const KindOf KindOfAutoSequence = (KindOf)(KindOfAuto |
75 KindOfSequence);
76 static const KindOf KindOfAutoObject = (KindOf)(KindOfAuto | KindOfObject);
78 static const KindOf KindOfSome = (KindOf)0x7FFE;
79 static const KindOf KindOfAny = (KindOf)0x7FFF;
80 /**
81 * Inferred types: types that a variable or a constant is sure to be.
83 static TypePtr Null;
84 static TypePtr Boolean;
85 static TypePtr Int32;
86 static TypePtr Int64;
87 static TypePtr Double;
88 static TypePtr String;
89 static TypePtr Array;
90 static TypePtr Object;
91 static TypePtr Variant;
93 static TypePtr Numeric;
94 static TypePtr PlusOperand;
95 static TypePtr Primitive;
96 static TypePtr Sequence;
98 static TypePtr AutoSequence;
99 static TypePtr AutoObject;
101 static TypePtr Any;
102 static TypePtr Some;
104 typedef hphp_string_imap<TypePtr> TypePtrMap;
105 static const TypePtrMap &GetTypeHintTypes();
108 * Uncertain types: types that are ambiguous yet.
110 static TypePtr CreateObjectType(const std::string &classname);
113 * For inferred, return static type objects; for uncertain, create new
114 * ones.
116 static TypePtr GetType(KindOf kindOf,
117 const std::string &clsname = "");
120 * Whether a type can be used as another type.
122 static bool IsLegalCast(AnalysisResultConstPtr ar, TypePtr from, TypePtr to);
125 * Find the intersection between two sets of types.
127 static TypePtr Intersection(AnalysisResultConstPtr ar,
128 TypePtr from, TypePtr to);
131 * Whether or not this type is mapped to type Variant
132 * in the runtime
134 static bool IsMappedToVariant(TypePtr t);
137 * Whether or not a cast is needed during code generation.
139 static bool IsCastNeeded(AnalysisResultConstPtr ar, TypePtr from, TypePtr to);
142 * When a variable's type is t1, and it's used as t2, do we need to
143 * coerce variable's type? Normally, if t2 can be legally casted to t1,
144 * this returns false.
146 static bool IsCoercionNeeded(AnalysisResultConstPtr ar,
147 TypePtr t1, TypePtr t2);
150 * When a variable is assigned with two types, what type a variable
151 * should be?
153 static TypePtr Coerce(AnalysisResultConstPtr ar,
154 TypePtr type1, TypePtr type2);
155 static TypePtr Union(AnalysisResultConstPtr ar, TypePtr type1, TypePtr type2);
158 * When two types have been inferred for an expression, what type
159 * should it be?
161 static TypePtr Inferred(AnalysisResultConstPtr ar,
162 TypePtr type1, TypePtr type2);
165 * When two object types have been inferred for an expression, what type
166 * should it be?
168 static TypePtr InferredObject(AnalysisResultConstPtr ar,
169 TypePtr type1,
170 TypePtr type2);
173 * Whether or not two types are the same.
175 static bool SameType(TypePtr type1, TypePtr type2);
178 * Return true if SameType(type1,type2) or if type1 and type2
179 * are objects and type1 derives from type2.
181 static bool SubType(AnalysisResultConstPtr ar, TypePtr type1, TypePtr type2);
184 * Testing type conversion for constants.
186 static bool IsExactType(KindOf kindOf);
188 static bool HasFastCastMethod(TypePtr t);
191 * Returns the name of the method used to fast cast from
192 * variant to dst
194 static std::string GetFastCastMethod(
195 TypePtr dst, bool allowRef, bool forConst);
197 private:
198 Type(KindOf kindOf, const std::string &name);
200 public:
202 * KindOf testing.
204 explicit Type(KindOf kindOf);
205 bool is(KindOf kindOf) const { return m_kindOf == kindOf;}
206 bool isExactType() const { return IsExactType(m_kindOf); }
207 bool mustBe(KindOf kindOf) const { return !(m_kindOf & ~kindOf); }
208 bool couldBe(KindOf kindOf) const { return m_kindOf & kindOf; }
209 bool isSubsetOf(TypePtr t) const {
210 return m_kindOf != t->m_kindOf && mustBe(t->m_kindOf);
212 KindOf getKindOf() const { return m_kindOf;}
213 bool isInteger() const;
214 bool isStandardObject() const;
215 bool isSpecificObject() const;
216 bool isNonConvertibleType() const; // other types cannot convert to them
217 bool isPrimitive() const {
218 return IsExactType(m_kindOf) && (m_kindOf <= KindOfDouble) &&
219 (m_kindOf != KindOfVoid);
221 bool isNoObjectInvolved() const;
222 const std::string &getName() const { return m_name;}
223 static TypePtr combinedArithmeticType(TypePtr t1, TypePtr t2);
225 ClassScopePtr getClass(AnalysisResultConstPtr ar,
226 BlockScopeRawPtr scope) const;
228 DataType getDataType() const;
229 DataType getHhvmDataType() const;
232 * Type hint names in PHP.
234 std::string getPHPName();
237 * Debug dump.
239 std::string toString() const;
240 static void Dump(TypePtr type, const char *fmt = "%s");
241 static void Dump(ExpressionPtr exp);
244 * Implements JSON::CodeError::ISerializable.
246 virtual void serialize(JSON::CodeError::OutputStream &out) const;
249 * Implements JSON::DocTarget::ISerializable.
251 virtual void serialize(JSON::DocTarget::OutputStream &out) const;
254 * For stats reporting.
256 void count(std::map<std::string, int> &counts);
259 * Must not be invoked concurrently
261 static void InitTypeHintMap();
262 private:
265 * Must not be invoked concurrently
267 static void ResetTypeHintTypes();
269 static TypePtrMap s_TypeHintTypes;
271 const KindOf m_kindOf;
272 const std::string m_name;
275 ///////////////////////////////////////////////////////////////////////////////
277 #endif // incl_HPHP_TYPE_H_