make #includes consistent
[hiphop-php.git] / hphp / compiler / analysis / variable_table.h
blob26e36be45c03ca3ac011c37fa231b2ab47accac6
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_VARIABLE_TABLE_H_
18 #define incl_HPHP_VARIABLE_TABLE_H_
20 #include "hphp/compiler/analysis/symbol_table.h"
21 #include "hphp/compiler/statement/statement.h"
22 #include "hphp/compiler/analysis/class_scope.h"
24 namespace HPHP {
25 ///////////////////////////////////////////////////////////////////////////////
27 DECLARE_BOOST_TYPES(ModifierExpression);
28 DECLARE_BOOST_TYPES(CodeError);
29 DECLARE_BOOST_TYPES(VariableTable);
30 DECLARE_BOOST_TYPES(Expression);
31 DECLARE_BOOST_TYPES(ClassScope);
32 DECLARE_BOOST_TYPES(FunctionScope);
34 /**
35 * These are the only places that a new variable can be declared:
37 * variable = expr|variable|new obj(...)
38 * static_var_list: T_STATIC T_VARIABLE = static_scalar,...
39 * class_variable_declaration: class { T_VARIABLE = static_scalar,...}
40 * T_LIST (variable, T_LIST(...), ...) = ...
41 * try {...} catch (T obj) {...}
42 * extract(name_value_pair)
44 class VariableTable : public SymbolTable {
45 friend class AssignmentExpression;
46 public:
47 enum Attribute {
48 ContainsDynamicVariable = 1,
49 ContainsLDynamicVariable = ContainsDynamicVariable | 2,
50 ContainsExtract = 4,
51 ContainsCompact = 8,
52 InsideStaticStatement = 16,
53 InsideGlobalStatement = 32,
54 ForceGlobal = 64,
55 ContainsUnset = 128,
56 NeedGlobalPointer = 256,
57 ContainsDynamicStatic = 512,
58 ContainsGetDefinedVars = 1024,
59 ContainsDynamicFunctionCall = 2048,
62 enum JumpTableType {
63 JumpReturn,
64 JumpSet,
65 JumpInitialized,
66 JumpInitializedString,
67 JumpIndex,
68 JumpReturnString
71 enum JumpTableName {
72 JumpTableGlobalGetImpl,
73 JumpTableGlobalExists,
74 JumpTableGlobalGetIndex,
76 JumpTableLocalGetImpl,
77 JumpTableLocalExists,
80 enum AlteredVarClass {
81 NonPrivateNonStaticVars = 1,
82 NonPrivateStaticVars = 2,
83 PrivateNonStaticVars = 4,
84 PrivateStaticVars = 8,
86 AnyNonStaticVars = NonPrivateNonStaticVars | PrivateNonStaticVars,
87 AnyStaticVars = NonPrivateStaticVars | PrivateStaticVars,
88 AnyNonPrivateVars = NonPrivateNonStaticVars | NonPrivateStaticVars,
89 AnyPrivateVars = PrivateNonStaticVars | PrivateStaticVars,
91 AnyVars = AnyStaticVars | AnyNonStaticVars
94 static int GetVarClassMask(bool privates, bool statics) {
95 return (statics ? 2 : 1) << (privates ? 2 : 0);
98 static int GetVarClassMaskForSym(const Symbol *sym) {
99 return GetVarClassMask(sym->isPrivate(), sym->isStatic());
102 public:
103 explicit VariableTable(BlockScope &blockScope);
106 * Get/set attributes.
108 void setAttribute(Attribute attr) { m_attribute |= attr;}
109 void clearAttribute(Attribute attr) { m_attribute &= ~attr;}
110 bool getAttribute(Attribute attr) const {
111 return (m_attribute & attr) == attr;
114 bool isParameter(const std::string &name) const;
115 bool isPublic(const std::string &name) const;
116 bool isProtected(const std::string &name) const;
117 bool isPrivate(const std::string &name) const;
118 bool isStatic(const std::string &name) const;
119 bool isGlobal(const std::string &name) const;
120 bool isSuperGlobal(const std::string &name) const;
121 bool isLocal(const std::string &name) const;
122 bool isLocal(const Symbol *sym) const;
123 bool isRedeclared(const std::string &name) const;
124 bool isLocalGlobal(const std::string &name) const;
125 bool isNestedStatic(const std::string &name) const;
126 bool isLvalParam(const std::string &name) const;
127 bool isUsed(const std::string &name) const;
128 bool isNeeded(const std::string &name) const;
130 bool needLocalCopy(const Symbol *sym) const;
131 bool needLocalCopy(const std::string &name) const;
132 bool needGlobalPointer() const;
133 bool isPseudoMainTable() const;
134 bool hasPrivate() const;
135 bool hasNonStaticPrivate() const;
136 bool hasStatic() const { return m_hasStatic; }
138 virtual bool isInherited(const std::string &name) const;
140 void getLocalVariableNames(std::vector<std::string> &syms) const;
143 * Get all variable's names.
145 void getNames(std::set<std::string> &names,
146 bool collectPrivate = true) const;
148 Symbol *addSymbol(const std::string &name) {
149 return genSymbol(name, false);
152 Symbol *addDeclaredSymbol(const std::string &name, ConstructPtr construct) {
153 return genSymbol(name, false, construct);
157 * Add a function's parameter to this table.
159 TypePtr addParam(const std::string &name, TypePtr type,
160 AnalysisResultConstPtr ar, ConstructPtr construct);
162 TypePtr addParamLike(const std::string &name, TypePtr type,
163 AnalysisResultPtr ar, ConstructPtr construct,
164 bool firstPass);
167 * Called when a variable is declared or being assigned (l-value).
169 TypePtr add(const std::string &name, TypePtr type, bool implicit,
170 AnalysisResultConstPtr ar, ConstructPtr construct,
171 ModifierExpressionPtr modifiers);
172 TypePtr add(Symbol *sym, TypePtr type, bool implicit,
173 AnalysisResultConstPtr ar, ConstructPtr construct,
174 ModifierExpressionPtr modifiers);
177 * Called to note whether a class variable overrides
178 * a definition in a base class. Returns whether or not there
179 * was an error in marking as override.
181 bool markOverride(AnalysisResultPtr ar, const std::string &name);
184 * Called when a variable is used or being evaluated (r-value).
186 TypePtr checkVariable(const std::string &name, TypePtr type, bool coerce,
187 AnalysisResultConstPtr ar, ConstructPtr construct);
188 TypePtr checkVariable(Symbol *sym, TypePtr type, bool coerce,
189 AnalysisResultConstPtr ar, ConstructPtr construct);
191 * Find the class which contains the property, and return
192 * its Symbol
194 Symbol *findProperty(ClassScopePtr &cls,
195 const std::string &name,
196 AnalysisResultConstPtr ar);
199 * Caller is responsible for grabbing a lock on this class scope,
200 * This function will be responsible for grabbing (and releasing)
201 * a lock on the parent scope if necessary.
203 TypePtr checkProperty(BlockScopeRawPtr context,
204 Symbol *sym, TypePtr type,
205 bool coerce, AnalysisResultConstPtr ar);
208 * Walk up to find first parent that has the specified symbol.
210 ClassScopePtr findParent(AnalysisResultConstPtr ar,
211 const std::string &name,
212 const Symbol *&sym) const;
214 ClassScopePtr findParent(AnalysisResultConstPtr ar,
215 const std::string &name,
216 Symbol *&sym) {
217 const Symbol *ss;
218 ClassScopePtr p = findParent(ar, name, ss); // const version
219 sym = const_cast<Symbol*>(ss);
220 return p;
224 * Called when analyze global and static statement.
226 bool checkRedeclared(const std::string &name, Statement::KindOf kindOf);
227 void addLocalGlobal(const std::string &name);
228 void addNestedStatic(const std::string &name);
231 * Helper for static variable default value
233 ConstructPtr getStaticInitVal(std::string varName);
234 bool setStaticInitVal(std::string varName, ConstructPtr value);
237 * Helper for class variable default value
239 ConstructPtr getClassInitVal(std::string varName);
240 bool setClassInitVal(std::string varName, ConstructPtr value);
243 * Called when analyze simple variable
245 void addLvalParam(const std::string &name);
246 void addUsed(const std::string &name);
247 bool checkUnused(Symbol *sym);
248 void addNeeded(const std::string &name);
249 void clearUsed();
250 void addStaticVariable(Symbol *sym, AnalysisResultConstPtr ar,
251 bool member = false);
252 void addStaticVariable(Symbol *sym, AnalysisResultPtr ar,
253 bool member = false);
254 void cleanupForError(AnalysisResultConstPtr ar);
257 * Set all matching variables to variants, since l-dynamic value was used.
259 void forceVariants(AnalysisResultConstPtr ar, int varClass,
260 bool recur = true);
263 * Set one matching variable to be Type::Variant.
265 void forceVariant(AnalysisResultConstPtr ar, const std::string &name,
266 int varClass);
269 * Keep track of $GLOBALS['var'].
271 void addSuperGlobal(const std::string &name);
272 bool isConvertibleSuperGlobal(const std::string &name) const;
275 * Canonicalize symbol order of static globals.
277 void canonicalizeStaticGlobals();
280 * Generate all variable declarations for this symbol table.
282 void outputPHP(CodeGenerator &cg, AnalysisResultPtr ar);
284 * Whether or not the specified jump table is empty.
286 bool hasAllJumpTables() const {
287 return m_emptyJumpTables.empty();
289 bool hasJumpTable(JumpTableName name) const {
290 return m_emptyJumpTables.find(name) == m_emptyJumpTables.end();
294 * These are static variables collected from different local scopes,
295 * as they have to be turned into global variables defined in
296 * GlobalVariables class to make ThreadLocal<GlobalVaribles> work.
297 * This data structure is only needed by global scope.
299 DECLARE_BOOST_TYPES(StaticGlobalInfo);
300 struct StaticGlobalInfo {
301 Symbol *sym;
302 VariableTable *variables; // where this variable was from
303 ClassScopeRawPtr cls; // these need to be raw to avoid reference cycles
304 FunctionScopeRawPtr func;
306 // get unique identifier for this variable
307 static std::string GetId(ClassScopePtr cls,
308 FunctionScopePtr func, const std::string &name);
311 bool hasStaticLocals() const { return !m_staticLocalsVec.empty(); }
313 private:
314 enum StaticSelection {
315 NonStatic = 1,
316 Static = 2,
317 EitherStatic = 3
320 enum PrivateSelection {
321 NonPrivate = 1,
322 Private = 2,
323 EitherPrivate = 3
326 int m_attribute;
327 int m_nextParam;
328 unsigned m_hasGlobal : 1;
329 unsigned m_hasStatic : 1;
330 unsigned m_hasPrivate : 1;
331 unsigned m_hasNonStaticPrivate : 1;
332 unsigned m_forcedVariants : 4;
334 std::set<JumpTableName> m_emptyJumpTables;
336 StaticGlobalInfoPtrVec m_staticGlobalsVec;
337 StringToStaticGlobalInfoPtrMap m_staticGlobals;
339 /** static symbols local to this variable table (ie for closures) */
340 SymbolVec m_staticLocalsVec;
342 bool isGlobalTable(AnalysisResultConstPtr ar) const;
344 virtual TypePtr setType(AnalysisResultConstPtr ar, const std::string &name,
345 TypePtr type, bool coerce);
346 virtual TypePtr setType(AnalysisResultConstPtr ar, Symbol *sym,
347 TypePtr type, bool coerce);
348 virtual void dumpStats(std::map<std::string, int> &typeCounts);
350 void checkSystemGVOrder(SymbolSet &variants, unsigned int max);
353 ///////////////////////////////////////////////////////////////////////////////
356 #endif // incl_HPHP_VARIABLE_TABLE_H_