2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2015 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_CODE_GENERATOR_H_
18 #define incl_HPHP_CODE_GENERATOR_H_
27 #include "hphp/util/deprecated/declare-boost-types.h"
29 #include "hphp/compiler/hphp.h"
32 ///////////////////////////////////////////////////////////////////////////////
34 DECLARE_BOOST_TYPES(AnalysisResult
);
35 DECLARE_BOOST_TYPES(Statement
);
36 DECLARE_BOOST_TYPES(StatementList
);
37 DECLARE_BOOST_TYPES(Construct
);
38 DECLARE_BOOST_TYPES(BlockScope
);
39 DECLARE_EXTENDED_BOOST_TYPES(ClassScope
);
40 DECLARE_BOOST_TYPES(FunctionScope
);
41 DECLARE_BOOST_TYPES(FileScope
);
42 DECLARE_BOOST_TYPES(LoopStatement
);
43 DECLARE_BOOST_TYPES(Expression
);
44 DECLARE_BOOST_TYPES(ExpressionList
);
51 PickledPHP
, // stripped comments, etc. but 1 to 1 file to file
52 InlinedPHP
, // all includes are inlined
53 TrimmedPHP
, // unreferenced functions and classes are removed
54 MonoCPP
, // All in one file. Left in for test. Not fully correct.
55 FileCPP
, // 1 to 1 from php to cpp file
56 ClusterCPP
, // each directory up to a certain depth to a cpp file
57 SystemCPP
, // special mode for generating builtin classes
58 TextHHBC
, // HHBC dump in human-readable format
59 BinaryHHBC
, // serialized HHBC
60 CodeModel
, // serialized Code Model classes
64 NullStream
= -1, // suppress output
65 PrimaryStream
, // main output
66 ImplFile
, // C++ implementation file
67 FatFile
= ImplFile
, // trimmed functions and classes
68 MapFile
, // lineno mapping between trimmed and original
76 CppForwardDeclaration
,
77 CppDeclaration
, // functions and classes
78 CppImplementation
, // other statements than declarations
79 CppPseudoMain
, // pseudo mains
80 CppConstructor
, // we are generating class constructor
81 CppInitializer
, // we are generating class initializer
82 CppClassConstantsDecl
,
83 CppClassConstantsImpl
,
84 CppConstantsDecl
, // we are generating constant declarations
85 CppFunctionWrapperImpl
, // Only used to force parameters to use C*Ref
86 CppFunctionWrapperDecl
,
87 CppParameterDefaultValueDecl
,
88 CppParameterDefaultValueImpl
,
89 CppTypedParamsWrapperImpl
,
90 CppTypedParamsWrapperDecl
,
95 JavaFFIInterface
, // for translating interfaces
96 JavaFFICppDecl
, // javah is too slow, generate .h ourselves
106 InsideSwitch
= 0x80000000,
107 StaticCases
= 0x40000000,
108 BreakScopeBitMask
= InsideSwitch
| StaticCases
112 CodeGenerator() {} // only for creating a dummy code generator
113 explicit CodeGenerator(std::ostream
*primary
, Output output
= PickledPHP
,
114 const std::string
*filename
= nullptr);
117 * ...if it was passed in from constructor.
119 const std::string
& getFileName() const { return m_filename
;}
122 * What kind of program are we generating?
124 Output
getOutput() const { return m_output
;}
125 void setOutput(Output output
) { m_output
= output
;}
130 void useStream(Stream stream
);
131 bool usingStream(Stream stream
);
132 std::ostream
*getStream() const { return m_out
;}
133 std::ostream
*getStream(Stream stream
) const;
134 void setStream(Stream stream
, std::ostream
*out
);
139 void printf(const char *fmt
, ...) ATTRIBUTE_PRINTF(2,3);
140 void indentBegin(const char *fmt
, ...) ATTRIBUTE_PRINTF(2,3);
142 void indentEnd(const char *fmt
, ...) ATTRIBUTE_PRINTF(2,3);
144 void printRaw(const char *msg
) { print(msg
, false);}
146 * Pre-formatted outputs.
148 void printSection(const char *name
, bool newline
= true);
149 void printSeparator();
150 void namespaceBegin();
152 bool ensureInNamespace();
153 bool ensureOutOfNamespace();
154 void ifdefBegin(bool ifdef
, const char *fmt
, ...) ATTRIBUTE_PRINTF(3,4);
155 void ifdefEnd(const char *fmt
, ...) ATTRIBUTE_PRINTF(2,3);
156 void printDocComment(const std::string comment
);
157 const char *getGlobals(AnalysisResultPtr ar
);
158 static std::string
EscapeLabel(const std::string
&name
, bool *binary
= nullptr);
161 * Make sure PHP variables, functions and typenames are unique and
162 * different from C's built-in keywords and HPHP's.
164 void resetIdCount(const std::string
&key
);
165 int createNewId(const std::string
&key
);
166 int createNewId(ConstructPtr ar
);
167 int createNewLocalId(ConstructPtr ar
);
168 static std::string
GetNewLambda(); // for create_function()
171 * Contexts allow one construct generates more than one kind of source.
172 * For example, a ClassStatement generates different source code, depending
173 * on whether we are generating a header file or an implementation file.
175 void setContext(Context context
) { m_context
= context
;}
176 Context
getContext() const { return m_context
;}
179 * Remember comment nested level to avoid double comments.
181 bool inComments() const;
182 void startComments();
186 * Helpers for break/continue scopes.
188 void pushBreakScope(int labelId
, bool loopCounter
= true);
189 void popBreakScope();
190 const std::vector
<int> &getBreakScopes() const { return m_breakScopes
;}
191 void addLabelId(const char *name
, int labelId
);
192 bool findLabelId(const char *name
, int labelId
);
195 * Get current line number of primary stream.
197 int getLineNo(Stream stream
) const;
199 int getPHPLineNo() { return m_phpLineNo
; }
200 void setPHPLineNo(int ln
) { m_phpLineNo
= ln
; }
202 bool translatePredefined() { return m_translatePredefined
; }
203 void translatePredefined(bool flag
) { m_translatePredefined
= flag
; }
205 int checkLiteralString(const std::string
&str
, int &index
,
206 AnalysisResultPtr ar
, BlockScopePtr bs
,
207 bool scalarVariant
= false);
208 std::string
printNamedString(const std::string
&str
,
209 const std::string
&escaped
,
210 AnalysisResultPtr ar
, BlockScopeRawPtr bs
,
212 std::string
printString(const std::string
&str
, AnalysisResultPtr ar
,
213 BlockScopeRawPtr check
, bool stringWrapper
= true);
214 std::string
printString(const std::string
&str
, AnalysisResultPtr ar
,
215 ConstructPtr check
, bool stringWrapper
= true);
216 int getCurrentIndentation() const { return m_indentation
[m_curStream
];}
218 bool inExpression() { return m_inExpression
[m_curStream
]; }
219 void setInExpression(bool in
) { m_inExpression
[m_curStream
] = in
; }
221 void pushCallInfo(int cit
);
225 LoopStatementPtr
getLoopStatement() const { return m_loopStatement
; }
226 void setLoopStatement(LoopStatementPtr loop
) {
227 m_loopStatement
= loop
;
230 void setFileOrClassHeader(bool value
) { m_inFileOrClassHeader
= value
; }
231 bool isFileOrClassHeader() { return m_inFileOrClassHeader
; }
233 void setInitListFirstElem() { m_initListFirstElem
= true; }
234 bool hasInitListFirstElem() { return m_initListFirstElem
; }
235 void clearInitListFirstElem() { m_initListFirstElem
= false; }
237 bool insertDeclaredClosure(const FunctionScope
*f
) {
238 return m_declaredClosures
.insert(f
).second
;
240 void setLiteralScope(FileScopeRawPtr fs
) {
243 FileScopeRawPtr
getLiteralScope() const {
244 return m_literalScope
;
248 * Support for printing AST nodes in PHP serialize() format.
250 void printObjectHeader(const std::string
& className
, int numProperties
);
251 void printPropertyHeader(const std::string
& propertyName
);
252 void printObjectFooter();
254 void printBool(bool value
);
255 void printValue(double value
);
256 void printValue(int32_t value
);
257 void printValue(int64_t value
);
258 void printValue(const std::string
& value
);
259 void printModifierVector(const std::string
& value
);
260 void printTypeExpression(const std::string
& value
);
261 void printTypeExpression(ExpressionPtr expression
);
262 void printExpression(ExpressionPtr expression
, bool isRef
);
263 void printExpressionVector(ExpressionListPtr el
);
264 void printTypeExpressionVector(ExpressionListPtr el
);
265 void printExpressionVector(ExpressionPtr e
);
266 void printAsBlock(StatementPtr s
, bool isEnclosed
= false);
267 void printAsEnclosedBlock(StatementPtr s
) { printAsBlock(s
, true); }
268 void printStatementVector(StatementListPtr sl
);
269 void printStatementVector(StatementPtr s
);
270 void printLocation(ConstructPtr what
) { printLocation(what
.get()); }
271 void printLocation(const Construct
* what
);
272 void setAstClassPrefix(const std::string
&prefix
) { m_astPrefix
= prefix
; }
274 std::string m_filename
;
276 std::ostream
*m_streams
[StreamCount
];
279 std::string m_astPrefix
;
280 std::vector
<std::string
> m_astClassNames
;
283 int m_indentation
[StreamCount
];
284 bool m_indentPending
[StreamCount
];
285 int m_lineNo
[StreamCount
];
286 int m_inComments
[StreamCount
];
287 bool m_wrappedExpression
[StreamCount
];
288 std::string m_referenceTemps
[StreamCount
];
289 bool m_referenceTempsUsed
[StreamCount
];
290 bool m_inExpression
[StreamCount
];
291 bool m_inFileOrClassHeader
;
293 int m_localId
[StreamCount
];
295 static int s_idLambda
;
296 std::map
<std::string
, int> m_idCounters
;
298 std::vector
<int> m_breakScopes
;
299 std::set
<int> m_breakLabelIds
; // break labels referenced
300 std::set
<int> m_contLabelIds
; // continue labels referenced
301 std::deque
<int> m_callInfos
;
302 LoopStatementPtr m_loopStatement
;
303 StringToClassScopePtrVecMap m_classes
;
304 std::set
<const FunctionScope
*> m_declaredClosures
;
305 FileScopeRawPtr m_literalScope
;
311 bool m_translatePredefined
; // translate predefined constants in PHP output
312 bool m_scalarVariant
;
313 bool m_initListFirstElem
;
315 public: void print(const char *msg
, bool indent
= true);
318 void print(const char *fmt
, va_list ap
) ATTRIBUTE_PRINTF(2,0);
319 void printSubstring(const char *start
, int length
);
321 std::string
getFormattedName(const std::string
&file
);
324 #define cg_printf cg.printf
325 #define m_cg_printf m_cg.printf
326 #define cg_print cg.print
327 #define m_cg_print m_cg.print
328 #define cg_indentBegin cg.indentBegin
329 #define m_cg_indentBegin m_cg.indentBegin
330 #define cg_indentEnd cg.indentEnd
331 #define m_cg_indentEnd cg.indentEnd
332 #define cg_printInclude cg.printInclude
333 #define cg_printString cg.printString
335 ///////////////////////////////////////////////////////////////////////////////
337 #endif // incl_HPHP_CODE_GENERATOR_H_