Update the MSVC compiler options
[hiphop-php.git] / hphp / compiler / code_generator.h
blob847d9317648ea460ade15971b96765bea851a66f
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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_
20 #include <deque>
21 #include <map>
22 #include <ostream>
23 #include <set>
24 #include <utility>
25 #include <vector>
27 #include "hphp/util/deprecated/declare-boost-types.h"
29 #include "hphp/compiler/hphp.h"
31 namespace HPHP {
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);
46 class CodeGenerator {
47 public:
48 enum Output {
49 InvalidOutput,
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
63 enum Stream {
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
70 StreamCount
73 enum Context {
74 NoContext,
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,
91 CppFFIDecl,
92 CppFFIImpl,
93 HsFFI,
94 JavaFFI,
95 JavaFFIInterface, // for translating interfaces
96 JavaFFICppDecl, // javah is too slow, generate .h ourselves
97 JavaFFICppImpl,
98 SwigFFIDecl,
99 SwigFFIImpl,
101 PhpDeclaration,
102 PhpImplementation,
105 enum BreakScopeBit {
106 InsideSwitch = 0x80000000,
107 StaticCases = 0x40000000,
108 BreakScopeBitMask = InsideSwitch | StaticCases
111 public:
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;}
128 * Stream functions.
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);
137 * Output strings.
139 void printf(const char *fmt, ...) ATTRIBUTE_PRINTF(2,3);
140 void indentBegin(const char *fmt, ...) ATTRIBUTE_PRINTF(2,3);
141 void indentBegin();
142 void indentEnd(const char *fmt, ...) ATTRIBUTE_PRINTF(2,3);
143 void indentEnd();
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();
151 void namespaceEnd();
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();
183 void endComments();
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,
211 bool print);
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);
222 void popCallInfo();
223 int callInfoTop();
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) {
241 m_literalScope = 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();
253 void printNull();
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; }
273 private:
274 std::string m_filename;
275 Stream m_curStream;
276 std::ostream *m_streams[StreamCount];
277 std::ostream *m_out;
278 Output m_output;
279 std::string m_astPrefix;
280 std::vector<std::string> m_astClassNames;
281 bool m_verbose;
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;
292 bool m_inNamespace;
293 int m_localId[StreamCount];
295 static int s_idLambda;
296 std::map<std::string, int> m_idCounters;
297 Context m_context;
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;
307 int m_itemIndex;
309 int m_phpLineNo;
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);
317 private:
318 void print(const char *fmt, va_list ap) ATTRIBUTE_PRINTF(2,0);
319 void printSubstring(const char *start, int length);
320 void printIndent();
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_