apply clang-tidy modernize-use-override
[hiphop-php.git] / hphp / compiler / analysis / analysis_result.h
blob6e3e38373e30ee0affa2e3e6f0e3292c2e16bc77
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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_ANALYSIS_RESULT_H_
18 #define incl_HPHP_ANALYSIS_RESULT_H_
20 #include "hphp/compiler/code_generator.h"
21 #include "hphp/compiler/analysis/code_error.h"
22 #include "hphp/compiler/option.h"
23 #include "hphp/compiler/analysis/block_scope.h"
24 #include "hphp/compiler/analysis/symbol_table.h"
25 #include "hphp/compiler/analysis/function_container.h"
26 #include "hphp/compiler/package.h"
27 #include "hphp/compiler/hphp.h"
29 #include "hphp/util/string-bag.h"
30 #include "hphp/util/thread-local.h"
32 #include <tbb/concurrent_hash_map.h>
33 #include <atomic>
34 #include <map>
35 #include <set>
36 #include <utility>
37 #include <vector>
38 #include <functional>
40 namespace HPHP {
41 ///////////////////////////////////////////////////////////////////////////////
44 DECLARE_EXTENDED_BOOST_TYPES(ClassScope);
45 DECLARE_EXTENDED_BOOST_TYPES(FileScope);
46 DECLARE_BOOST_TYPES(FunctionScope);
47 DECLARE_BOOST_TYPES(AnalysisResult);
48 DECLARE_BOOST_TYPES(ScalarExpression);
50 struct UnitEmitter;
52 struct AnalysisResult : BlockScope, FunctionContainer {
53 /**
54 * There are multiple passes over our syntax trees. This lists all of them.
56 enum Phase {
57 // parse
58 ParseAllFiles,
60 // analyzeProgram
61 AnalyzeAll,
62 AnalyzeFinal,
64 // pre-optimize
65 FirstPreOptimize,
67 CodeGen,
70 enum GlobalSymbolType {
71 KindOfStaticGlobalVariable,
72 KindOfDynamicGlobalVariable,
73 KindOfMethodStaticVariable,
74 KindOfClassStaticVariable,
75 KindOfDynamicConstant,
76 KindOfPseudoMain,
77 KindOfRedeclaredFunction,
78 KindOfRedeclaredClass,
79 KindOfRedeclaredClassId,
80 KindOfVolatileClass,
81 KindOfLazyStaticInitializer,
83 GlobalSymbolTypeCount
86 struct Locker {
87 explicit Locker(const AnalysisResult *ar) :
88 m_ar(const_cast<AnalysisResult*>(ar)),
89 m_mutex(m_ar->getMutex()) {
90 m_mutex.lock();
92 explicit Locker(AnalysisResultConstPtr ar) :
93 m_ar(const_cast<AnalysisResult*>(ar.get())),
94 m_mutex(m_ar->getMutex()) {
95 m_mutex.lock();
97 Locker(const Locker &l) : m_ar(l.m_ar), m_mutex(l.m_mutex) {
98 const_cast<Locker&>(l).m_ar = 0;
100 ~Locker() {
101 if (m_ar) m_mutex.unlock();
103 AnalysisResultPtr get() const {
104 return m_ar->shared_from_this();
106 AnalysisResult *operator->() const {
107 return m_ar;
109 private:
110 AnalysisResult *m_ar;
111 Mutex &m_mutex;
114 public:
115 AnalysisResult();
116 ~AnalysisResult() override;
117 Locker lock() const { return Locker(this); }
118 void setPackage(Package *package) { m_package = package;}
119 void setParseOnDemand(bool v) { m_parseOnDemand = v;}
120 bool isParseOnDemand() const { return m_package && m_parseOnDemand;}
121 void setParseOnDemandDirs(const std::vector<std::string> &dirs) {
122 assert(m_package && !m_parseOnDemand);
123 m_parseOnDemandDirs = dirs;
125 void setFinish(std::function<void(AnalysisResultPtr)>&& fn) {
126 m_finish = std::move(fn);
128 void finish();
131 * create_function() generates extra PHP code that defines the lambda.
132 * Stores the code in a temporary string, so we can parse this as an
133 * extra file appended to parsed code.
135 void appendExtraCode(const std::string &key, const std::string &code);
136 void appendExtraCode(const std::string &key, const std::string &code) const;
137 void parseExtraCode(const std::string &key);
139 Phase getPhase() const { return m_phase;}
140 void setPhase(Phase phase) { m_phase = phase;}
142 int getFunctionCount() const;
143 int getClassCount() const;
145 void addEntryPoint(const std::string &name);
146 void addEntryPoints(const std::vector<std::string> &names);
148 void addNSFallbackFunc(ConstructPtr c, FileScopePtr fs);
150 void addSystemFunction(FunctionScopeRawPtr fs);
151 void addSystemClass(ClassScopeRawPtr cs);
152 void analyzeProgram(bool system = false);
153 void analyzeProgramFinal();
154 void dump();
156 void visitFiles(void (*cb)(AnalysisResultPtr, StatementPtr, void*),
157 void *data);
159 void getScopesSet(BlockScopeRawPtrQueue &v);
161 void preOptimize();
164 * Code generation functions.
166 bool outputAllPHP(CodeGenerator::Output output);
169 * Parser creates a FileScope upon parsing a new file.
171 void parseOnDemand(const std::string &name) const;
172 void parseOnDemandByClass(const std::string &name) const {
173 parseOnDemandBy(name, Option::AutoloadClassMap);
175 void parseOnDemandByFunction(const std::string &name) const {
176 parseOnDemandBy(name, Option::AutoloadFuncMap);
178 void parseOnDemandByConstant(const std::string &name) const {
179 parseOnDemandBy(name, Option::AutoloadConstMap);
181 template <class Map>
182 void parseOnDemandBy(const std::string &name,
183 const Map& amap) const;
184 FileScopePtr findFileScope(const std::string &name) const;
185 const StringToFileScopePtrMap &getAllFiles() { return m_files;}
186 const std::vector<FileScopePtr> &getAllFilesVector() {
187 return m_fileScopes;
190 void addFileScope(FileScopePtr fileScope);
193 * Declarations
195 bool declareFunction(FunctionScopePtr funcScope) const;
196 bool declareClass(ClassScopePtr classScope) const;
197 void declareUnknownClass(const std::string &name);
198 bool declareConst(FileScopePtr fs, const std::string &name);
200 ClassScopePtr findClass(const std::string &className) const;
203 * Find all the redeclared classes by the name, excluding system classes.
204 * Note that system classes cannot be redeclared.
206 const std::vector<ClassScopePtr>& findRedeclaredClasses(
207 const std::string &className) const;
210 * Find all the classes by the name, including system classes.
212 std::vector<ClassScopePtr> findClasses(const std::string &className) const;
213 ClassScopePtr findExactClass(ConstructPtr cs, const std::string &name) const;
214 FunctionScopePtr findFunction(const std::string &funcName) const ;
215 BlockScopeConstPtr findConstantDeclarer(const std::string &constName) const {
216 return const_cast<AnalysisResult*>(this)->findConstantDeclarer(constName);
218 BlockScopePtr findConstantDeclarer(const std::string &constName);
220 bool isConstantDeclared(const std::string &constName) const;
221 bool isConstantRedeclared(const std::string &constName) const;
222 bool isSystemConstant(const std::string &constName) const;
225 * For function declaration parsing.
227 static std::string prepareFile(const char *root, const std::string &fileName,
228 bool chop, bool stripPath = true);
230 void setOutputPath(const std::string &path) {
231 m_outputPath = path;
233 const std::string &getOutputPath() {
234 return m_outputPath;
237 void addHhasFile(std::unique_ptr<UnitEmitter>&& ue);
238 std::vector<std::unique_ptr<UnitEmitter>> getHhasFiles();
239 private:
240 std::function<void(AnalysisResultPtr)> m_finish;
241 Package *m_package;
242 bool m_parseOnDemand;
243 std::vector<std::string> m_parseOnDemandDirs;
244 std::set<std::pair<ConstructPtr, FileScopePtr> > m_nsFallbackFuncs;
245 Phase m_phase;
246 StringToFileScopePtrMap m_files;
247 std::vector<FileScopePtr> m_fileScopes;
248 std::vector<std::unique_ptr<UnitEmitter>> m_hhasFiles;
250 StringBag m_extraCodeFileNames;
251 std::map<std::string, std::string> m_extraCodes;
253 StringToClassScopePtrMap m_systemClasses;
254 StringToFunctionScopePtrMap m_functionDecs;
255 StringToFunctionScopePtrVecMap m_functionReDecs;
256 StringToClassScopePtrVecMap m_classDecs;
257 StringToFileScopePtrMap m_constDecs;
258 std::set<std::string> m_constRedeclared;
260 // Names of type aliases.
261 std::set<std::string> m_typeAliasNames;
263 std::vector<StatementPtr> m_stmts;
264 StatementPtr m_stmt;
266 std::string m_outputPath;
267 public:
268 AnalysisResultPtr shared_from_this() {
269 return static_pointer_cast<AnalysisResult>
270 (BlockScope::shared_from_this());
273 AnalysisResultConstPtr shared_from_this() const {
274 return static_pointer_cast<const AnalysisResult>
275 (BlockScope::shared_from_this());
278 private:
279 std::vector<BlockScopePtr> m_ignoredScopes;
282 * Checks whether the file is in one of the on-demand parsing directories.
284 bool inParseOnDemandDirs(const std::string &filename) const;
287 * Find the names of all functions and classes in the program; mark
288 * functions with duplicate names as redeclaring, but duplicate
289 * classes aren't yet marked. See markRedeclaringClasses.
291 void collectFunctionsAndClasses(FileScopePtr fs);
294 * Making sure symbol orders are not different even with multithreading, so
295 * to make sure generated code are consistent every time.
297 void canonicalizeSymbolOrder();
300 * After all the class names have been collected and symbol order is
301 * canonicalized, this passes through and marks duplicate class
302 * names as redeclaring.
304 void markRedeclaringClasses();
307 * Checks circular class derivations that can cause stack overflows for
308 * subsequent analysis. Also checks to make sure no two redundant parents.
310 void checkClassDerivations();
312 void resolveNSFallbackFuncs();
314 int getFileSize(FileScopePtr fs);
316 public:
317 static DECLARE_THREAD_LOCAL(BlockScopeRawPtr, s_currentScopeThreadLocal);
318 static DECLARE_THREAD_LOCAL(BlockScopeRawPtrFlagsHashMap,
319 s_changedScopesMapThreadLocal);
321 private:
322 void processScopesParallel(const char* id, void* context = nullptr);
325 ///////////////////////////////////////////////////////////////////////////////
327 #endif // incl_HPHP_ANALYSIS_RESULT_H_