2 +----------------------------------------------------------------------+
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"
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
);
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
;
48 ContainsDynamicVariable
= 1,
49 ContainsLDynamicVariable
= ContainsDynamicVariable
| 2,
52 InsideStaticStatement
= 16,
53 InsideGlobalStatement
= 32,
56 NeedGlobalPointer
= 256,
57 ContainsDynamicStatic
= 512,
58 ContainsGetDefinedVars
= 1024,
59 ContainsDynamicFunctionCall
= 2048,
66 JumpInitializedString
,
72 JumpTableGlobalGetImpl
,
73 JumpTableGlobalExists
,
74 JumpTableGlobalGetIndex
,
76 JumpTableLocalGetImpl
,
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());
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
,
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
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
,
218 ClassScopePtr p
= findParent(ar
, name
, ss
); // const version
219 sym
= const_cast<Symbol
*>(ss
);
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
);
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
,
263 * Set one matching variable to be Type::Variant.
265 void forceVariant(AnalysisResultConstPtr ar
, const std::string
&name
,
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
{
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(); }
314 enum StaticSelection
{
320 enum PrivateSelection
{
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_