本文整理汇总了C++中FunctionScopePtr::getName方法的典型用法代码示例。如果您正苦于以下问题:C++ FunctionScopePtr::getName方法的具体用法?C++ FunctionScopePtr::getName怎么用?C++ FunctionScopePtr::getName使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FunctionScopePtr
的用法示例。
在下文中一共展示了FunctionScopePtr::getName方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ImportExtFunctions
void BuiltinSymbols::ImportExtFunctions(AnalysisResultPtr ar,
StringToFunctionScopePtrMap &map,
ClassInfo *cls) {
const ClassInfo::MethodVec &methods = cls->getMethodsVec();
for (auto it = methods.begin(); it != methods.end(); ++it) {
FunctionScopePtr f = ImportFunctionScopePtr(ar, cls, *it);
assert(!map[f->getName()]);
map[f->getName()] = f;
}
}
示例2: ParseExtFunctions
void BuiltinSymbols::ParseExtFunctions(AnalysisResultPtr ar, const char **p,
bool sep) {
while (*p) {
FunctionScopePtr f = ParseExtFunction(ar, p);
if (sep) {
f->setSepExtension();
}
assert(!s_functions[f->getName()]);
s_functions[f->getName()] = f;
}
}
示例3: outputCPPImpl
void StatementList::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
FunctionScopePtr func = getFunctionScope();
for (unsigned int i = 0; i < m_stmts.size(); i++) {
StatementPtr stmt = m_stmts[i];
stmt->outputCPP(cg, ar);
if (stmt->is(Statement::KindOfMethodStatement)) {
MethodStatementPtr methodStmt =
dynamic_pointer_cast<MethodStatement>(stmt);
std::string methodName = methodStmt->getName();
if (methodName == "offsetget") {
ClassScopePtr cls = getClassScope();
std::string arrayAccess("arrayaccess");
if (cls->derivesFrom(ar, arrayAccess, false, false)) {
FunctionScopePtr funcScope = methodStmt->getFunctionScope();
std::string name = funcScope->getName();
funcScope->setName("__offsetget_lval");
methodStmt->setName("__offsetget_lval");
methodStmt->outputCPP(cg, ar);
funcScope->setName(name);
methodStmt->setName("offsetget");
}
}
}
}
}
示例4: outputCPPImpl
void StatementList::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
FunctionScopePtr func = getFunctionScope();
bool inPseudoMain = func && func->inPseudoMain();
std::vector<bool> isDeclaration;
if (inPseudoMain) {
// We need these declarations to go first, because PHP allows top level
// function and class declarations to appear after usage.
for (unsigned int i = 0; i < m_stmts.size(); i++) {
StatementPtr stmt = m_stmts[i];
bool isDecl = false;
if (stmt->is(Statement::KindOfFunctionStatement)) {
isDecl = true;
} else if (stmt->is(Statement::KindOfClassStatement) ||
stmt->is(Statement::KindOfInterfaceStatement)) {
ClassScopePtr cls =
(dynamic_pointer_cast<InterfaceStatement>(stmt))->getClassScope();
isDecl = cls->isBaseClass() || !cls->isVolatile();
}
if (isDecl) stmt->outputCPP(cg,ar);
isDeclaration.push_back(isDecl);
}
}
for (unsigned int i = 0; i < m_stmts.size(); i++) {
StatementPtr stmt = m_stmts[i];
if (stmt->is(Statement::KindOfClassStatement)) {
if (!inPseudoMain || !isDeclaration[i]) stmt->outputCPP(cg, ar);
} else if (!(stmt->is(Statement::KindOfFunctionStatement) ||
stmt->is(Statement::KindOfInterfaceStatement)) ||
(!inPseudoMain || !isDeclaration[i])) {
stmt->outputCPP(cg, ar);
if (stmt->is(Statement::KindOfMethodStatement)) {
MethodStatementPtr methodStmt =
dynamic_pointer_cast<MethodStatement>(stmt);
std::string methodName = methodStmt->getName();
if (methodName == "offsetget") {
ClassScopePtr cls = getClassScope();
std::string arrayAccess("arrayaccess");
if (cls->derivesFrom(ar, arrayAccess, false, false)) {
FunctionScopePtr funcScope = methodStmt->getFunctionScope();
std::string name = funcScope->getName();
funcScope->setName("__offsetget_lval");
methodStmt->setName("__offsetget_lval");
methodStmt->outputCPP(cg, ar);
funcScope->setName(name);
methodStmt->setName("offsetget");
}
}
}
}
}
}
示例5: addFunction
bool ClassScope::addFunction(AnalysisResultConstPtr ar,
FunctionScopePtr funcScope) {
FunctionScopePtr &func = m_functions[funcScope->getName()];
if (func) {
func->getStmt()->parseTimeFatal(Compiler::DeclaredMethodTwice,
"Redeclared method %s::%s",
getOriginalName().c_str(),
func->getOriginalName().c_str());
}
func = funcScope;
m_functionsVec.push_back(funcScope);
return true;
}
示例6: analyzeProgram
void ParameterExpression::analyzeProgram(AnalysisResultPtr ar) {
if (!m_type.empty()) addUserClass(ar, m_type);
if (m_defaultValue) m_defaultValue->analyzeProgram(ar);
if (ar->isFirstPass()) {
// Have to use non const ref params for magic methods
FunctionScopePtr fs = ar->getFunctionScope();
if (fs->isMagicMethod() || fs->getName() == "offsetget") {
fs->getVariables()->addLvalParam(m_name);
}
}
}
示例7: addFunction
bool FileScope::addFunction(AnalysisResultConstPtr ar,
FunctionScopePtr funcScope) {
if (ar->declareFunction(funcScope)) {
FunctionScopePtr &fs = m_functions[funcScope->getName()];
if (fs) {
if (!m_redeclaredFunctions) {
m_redeclaredFunctions = new StringToFunctionScopePtrVecMap;
}
FunctionScopePtrVec &funcVec =
(*m_redeclaredFunctions)[funcScope->getName()];
if (!funcVec.size()) {
fs->setLocalRedeclaring();
funcVec.push_back(fs);
}
funcScope->setLocalRedeclaring();
funcVec.push_back(funcScope);
} else {
fs = funcScope;
}
return true;
}
return false;
}
示例8: outputCPPTypeCheckWrapper
void MethodStatement::outputCPPTypeCheckWrapper(CodeGenerator &cg,
AnalysisResultPtr ar) {
FunctionScopePtr funcScope = getFunctionScope();
TypePtr type = funcScope->getReturnType();
bool isMethod = getClassScope();
string fname = isMethod ? funcScope->getName() : funcScope->getId(cg);
funcScope->outputCPP(cg, ar);
cg_printf("%s%s%s(", type ? "return " : "",
(isMethod ? (m_modifiers->isStatic() ?
Option::TypedMethodImplPrefix :
Option::TypedMethodPrefix) :
Option::TypedFunctionPrefix),
fname.c_str());
if (getClassScope() && m_modifiers->isStatic()) {
cg_printf("cls, ");
}
if (funcScope->isVariableArgument()) {
cg_printf("num_args, ");
}
assert(m_params);
for (int i = 0; i < m_params->getCount(); i++) {
ParameterExpressionPtr param =
dynamic_pointer_cast<ParameterExpression>((*m_params)[i]);
ASSERT(param);
if (i) cg_printf(", ");
cg_printf("%s%s", Option::VariablePrefix,
param->getName().c_str());
if (TypePtr spec = funcScope->getParamTypeSpec(i)) {
if (Type::SameType(spec, funcScope->getParamType(i))) {
if (spec->is(Type::KindOfArray)) {
cg_printf(".getArrayData()");
} else {
ClassScopePtr cls = ar->findClass(spec->getName());
assert(cls && !cls->isRedeclaring());
cg_printf(".getObjectData()");
}
}
}
}
if (funcScope->isVariableArgument()) {
cg_printf(", args");
}
cg_printf(");\n");
}
示例9: declareFunction
bool AnalysisResult::declareFunction(FunctionScopePtr funcScope) const {
assert(m_phase < AnalyzeAll);
string fname = funcScope->getName();
// System functions override
auto it = m_functions.find(fname);
if (it != m_functions.end()) {
if (!it->second->allowOverride()) {
// we need someone to hold on to a reference to it
// even though we're not going to do anything with it
this->lock()->m_ignoredScopes.push_back(funcScope);
return false;
}
}
return true;
}
示例10: Load
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) {
if (Loaded) return true;
Loaded = true;
// Build function scopes for some of the runtime helper functions
// declared in "runtime/base/builtin_functions.h"
const char **helper = HelperFunctions;
while (*helper) {
FunctionScopePtr f = ParseHelperFunction(ar, helper);
ASSERT(!s_helperFunctions[f->getName()]);
s_helperFunctions[f->getName()] = f;
}
// load extension functions first, so system/classes may call them
ParseExtFunctions(ar, ExtensionFunctions, false);
AnalysisResultPtr ar2;
// parse all PHP files under system/classes
if (!extOnly) {
ar = AnalysisResultPtr(new AnalysisResult());
ar->loadBuiltinFunctions();
for (const char **cls = SystemClasses; *cls; cls++) {
string phpBaseName = "/system/classes/";
phpBaseName += *cls;
phpBaseName += ".php";
string phpFileName = Option::GetSystemRoot() + phpBaseName;
const char *baseName = s_strings.add(phpBaseName.c_str());
const char *fileName = s_strings.add(phpFileName.c_str());
try {
Scanner scanner(fileName, Option::ScannerType);
Compiler::Parser parser(scanner, baseName, ar);
if (!parser.parse()) {
Logger::Error("Unable to parse file %s: %s", fileName,
parser.getMessage().c_str());
ASSERT(false);
}
} catch (FileOpenException &e) {
Logger::Error("%s", e.getMessage().c_str());
}
}
ar->analyzeProgram(true);
ar->inferTypes();
const StringToFileScopePtrMap &files = ar->getAllFiles();
for (StringToFileScopePtrMap::const_iterator iterFile = files.begin();
iterFile != files.end(); iterFile++) {
const StringToClassScopePtrVecMap &classes =
iterFile->second->getClasses();
for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin();
iter != classes.end(); ++iter) {
ASSERT(iter->second.size() == 1);
iter->second[0]->setSystem();
ASSERT(!s_classes[iter->first]);
s_classes[iter->first] = iter->second[0];
}
}
// parse globals/variables.php and globals/constants.php
NoSuperGlobals = true;
s_variables = LoadGlobalSymbols("symbols.php")->getVariables();
ar2 = LoadGlobalSymbols("constants.php");
const FileScopePtrVec &fileScopes = ar2->getAllFilesVector();
if (!fileScopes.empty()) {
s_constants = fileScopes[0]->getConstants();
} else {
Logger::Error("Couldn't load constants.php");
return false;
}
NoSuperGlobals = false;
} else {
ar2 = AnalysisResultPtr(new AnalysisResult());
s_variables = VariableTablePtr(new VariableTable(*ar2.get()));
s_constants = ConstantTablePtr(new ConstantTable(*ar2.get()));
NoSuperGlobals = true;
}
s_constants->setDynamic(ar, "SID", true);
// load extension constants, classes and dynamics
ParseExtConsts(ar, ExtensionConsts, false);
ParseExtClasses(ar, ExtensionClasses, false);
for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) {
Option::SepExtensionOptions &options = Option::SepExtensions[i];
string soname = options.soname;
if (soname.empty()) {
soname = string("lib") + options.name + ".so";
}
if (!options.lib_path.empty()) {
soname = options.lib_path + "/" + soname;
}
if (!LoadSepExtensionSymbols(ar, options.name, soname)) {
return false;
}
}
return true;
}
示例11: outputCPPFFIStub
void MethodStatement::outputCPPFFIStub(CodeGenerator &cg,
AnalysisResultPtr ar) {
FunctionScopePtr funcScope = m_funcScope.lock();
ClassScopePtr clsScope = getClassScope();
bool varArgs = funcScope->isVariableArgument();
bool ret = funcScope->getReturnType();
string fname = funcScope->getId(cg);
bool inClass = !m_className.empty();
bool isStatic = !inClass || m_modifiers->isStatic();
if (inClass && m_modifiers->isAbstract()) {
return;
}
if (funcScope->getName() == "__offsetget_lval") {
return;
}
if (ret) {
cg_printf("int");
} else {
cg_printf("void");
}
cg_printf(" %s%s%s(", Option::FFIFnPrefix,
(inClass ? (m_className + "_cls_").c_str() : ""), fname.c_str());
if (ret) {
cg_printf("void** res");
}
bool first = !ret;
if (!isStatic) {
// instance methods need one additional parameter for the target
if (first) {
first = false;
}
else {
cg_printf(", ");
}
cg_printf("Variant *target");
}
int ac = funcScope->getMaxParamCount();
for (int i = 0; i < ac; ++i) {
if (first) {
first = false;
} else {
cg_printf(", ");
}
cg_printf("Variant *a%d", i);
}
if (varArgs) {
if (!first) {
cg_printf(", ");
}
cg_printf("Variant *va");
}
cg_printf(")");
if (cg.getContext() == CodeGenerator::CppFFIDecl) {
cg_printf(";\n");
} else {
cg_indentBegin(" {\n");
if (ret) {
cg_printf("return hphp_ffi_exportVariant(");
}
if (!inClass) {
// simple function call
cg_printf("%s%s(", Option::FunctionPrefix, fname.c_str());
} else if (isStatic) {
// static method call
cg_printf("%s%s::%s%s(", Option::ClassPrefix,
clsScope->getId(cg).c_str(),
Option::MethodPrefix, funcScope->getName().c_str());
} else {
// instance method call
cg_printf("dynamic_cast<%s%s *>(target->getObjectData())->",
Option::ClassPrefix, clsScope->getId(cg).c_str());
cg_printf("%s%s(", Option::MethodPrefix, funcScope->getName().c_str());
}
first = true;
if (varArgs) {
cg_printf("%d + (va->isNull() ? 0 : va->getArrayData()->size())", ac);
first = false;
}
for (int i = 0; i < ac; ++i) {
if (first) {
first = false;
} else {
cg_printf(", ");
}
cg_printf("*a%d", i);
}
if (varArgs) {
cg_printf(", va->toArray()");
}
if (ret) {
cg_printf("), res");
//.........这里部分代码省略.........
示例12: outputJavaFFICPPStub
void MethodStatement::outputJavaFFICPPStub(CodeGenerator &cg,
AnalysisResultPtr ar) {
// TODO translate PHP namespace once that is supported
string packageName = Option::JavaFFIRootPackage;
FunctionScopePtr funcScope = m_funcScope.lock();
bool varArgs = funcScope->isVariableArgument();
bool ret = funcScope->getReturnType();
bool inClass = !m_className.empty();
bool isStatic = !inClass || m_modifiers->isStatic();
string fname = funcScope->getId(cg);
int ac = funcScope->getMaxParamCount();
bool exposeNative = !(ac > 0 || varArgs || !isStatic || !ret && inClass);
if (inClass && m_modifiers->isAbstract()) {
// skip all the abstract methods, because hphp doesn't generate code
// for them
return;
}
if (funcScope->getName() == "__offsetget_lval") return;
const char *clsName;
if (inClass) {
// uses capitalized original class name
ClassScopePtr cls = ar->findClass(m_className);
clsName = cls->getOriginalName().c_str();
} else {
clsName = "HphpMain";
}
string mangledName = "Java." + packageName + "." + clsName + "." + fname
+ (exposeNative ? "" : "_native");
// all the existing "_" are replaced as "_1"
Util::replaceAll(mangledName, "_", "_1");
Util::replaceAll(mangledName, ".", "_");
cg_printf("JNIEXPORT %s JNICALL\n", ret ? "jobject" : "void");
cg_printf("%s(JNIEnv *env, %s target", mangledName.c_str(),
(isStatic ? "jclass" : "jobject"));
ostringstream args;
bool first = true;
if (!isStatic) {
// instance method also gets an additional argument, which is a Variant
// pointer to the target, encoded in int64
first = false;
cg_printf(", jlong targetPtr");
args << "(Variant *)targetPtr";
}
for (int i = 0; i < ac; i++) {
cg_printf(", jlong a%d", i);
if (first) first = false;
else args << ", ";
args << "(Variant *)a" << i;
}
if (varArgs) {
cg_printf(", jlong va");
if (!first) args << ", ";
args << "(Variant *)va";
}
if (cg.getContext() == CodeGenerator::JavaFFICppDecl) {
// java_stubs.h
cg_printf(");\n\n");
return;
}
cg_indentBegin(") {\n");
// support static/instance methods
if (ret) {
cg_printf("void *result;\n");
cg_printf("int kind = ");
cg_printf("%s%s%s(&result",
Option::FFIFnPrefix,
(inClass ? (m_className + "_cls_").c_str() : ""), fname.c_str());
if (!isStatic || ac > 0 || varArgs) cg_printf(", ");
} else {
cg_printf("%s%s%s(", Option::FFIFnPrefix,
(inClass ? (m_className + "_cls_").c_str() : ""),
fname.c_str());
}
cg_printf("%s);\n", args.str().c_str());
if (ret) {
if (!inClass) {
// HphpMain extends hphp.Hphp.
cg_printf("jclass hphp = env->GetSuperclass(target);\n");
}
else {
cg_printf("jclass hphp = env->FindClass(\"hphp/Hphp\");\n");
}
cg_printf("return exportVariantToJava(env, hphp, result, kind);\n");
}
cg_indentEnd("}\n");
cg.printImplSplitter();
}
示例13: outputCPPImpl
void SimpleFunctionCall::outputCPPImpl(CodeGenerator &cg,
AnalysisResultPtr ar) {
bool linemap = outputLineMap(cg, ar, true);
if (!m_lambda.empty()) {
cg.printf("\"%s\"", m_lambda.c_str());
if (linemap) cg.printf(")");
return;
}
if (m_className.empty()) {
if (m_type == DefineFunction && m_params && m_params->getCount() >= 2) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>((*m_params)[0]);
string varName;
if (name) {
varName = name->getIdentifier();
ExpressionPtr value = (*m_params)[1];
if (varName.empty()) {
cg.printf("throw_fatal(\"bad define\")");
} else if (m_dynamicConstant) {
cg.printf("g->declareConstant(\"%s\", g->%s%s, ",
varName.c_str(), Option::ConstantPrefix,
varName.c_str());
value->outputCPP(cg, ar);
cg.printf(")");
} else {
bool needAssignment = true;
bool isSystem = ar->getConstants()->isSystem(varName);
if (isSystem ||
((!ar->isConstantRedeclared(varName)) && value->isScalar())) {
needAssignment = false;
}
if (needAssignment) {
cg.printf("%s%s = ", Option::ConstantPrefix, varName.c_str());
value->outputCPP(cg, ar);
}
}
} else {
cg.printf("throw_fatal(\"bad define\")");
}
if (linemap) cg.printf(")");
return;
}
if (m_name == "func_num_args") {
cg.printf("num_args");
if (linemap) cg.printf(")");
return;
}
switch (m_type) {
case VariableArgumentFunction:
{
FunctionScopePtr func =
dynamic_pointer_cast<FunctionScope>(ar->getScope());
if (func) {
cg.printf("%s(", m_name.c_str());
func->outputCPPParamsCall(cg, ar, true);
if (m_params) {
cg.printf(",");
m_params->outputCPP(cg, ar);
}
cg.printf(")");
if (linemap) cg.printf(")");
return;
}
}
break;
case FunctionExistsFunction:
case ClassExistsFunction:
case InterfaceExistsFunction:
{
bool literalString = false;
string symbol;
if (m_params && m_params->getCount() == 1) {
ExpressionPtr value = (*m_params)[0];
if (value->isScalar()) {
ScalarExpressionPtr name =
dynamic_pointer_cast<ScalarExpression>(value);
if (name && name->isLiteralString()) {
literalString = true;
symbol = name->getLiteralString();
}
}
}
if (literalString) {
switch (m_type) {
case FunctionExistsFunction:
{
const std::string &lname = Util::toLower(symbol);
bool dynInvoke = Option::DynamicInvokeFunctions.find(lname) !=
Option::DynamicInvokeFunctions.end();
if (!dynInvoke) {
FunctionScopePtr func = ar->findFunction(lname);
if (func) {
if (!func->isDynamic()) {
if (func->isRedeclaring()) {
const char *name = func->getName().c_str();
cg.printf("(%s->%s%s != invoke_failed_%s)",
cg.getGlobals(ar), Option::InvokePrefix,
//.........这里部分代码省略.........
示例14: outputCPPParamOrderControlled
void SimpleFunctionCall::outputCPPParamOrderControlled(CodeGenerator &cg,
AnalysisResultPtr ar) {
if (m_className.empty()) {
switch (m_type) {
case ExtractFunction:
cg.printf("extract(variables, ");
FunctionScope::outputCPPArguments(m_params, cg, ar, 0, false);
cg.printf(")");
return;
case CompactFunction:
cg.printf("compact(variables, ");
FunctionScope::outputCPPArguments(m_params, cg, ar, -1, true);
cg.printf(")");
return;
default:
break;
}
}
bool volatileCheck = false;
ClassScopePtr cls;
if (!m_className.empty()) {
cls = ar->findClass(m_className);
if (cls && !ar->checkClassPresent(m_origClassName)) {
volatileCheck = true;
cls->outputVolatileCheckBegin(cg, ar, cls->getOriginalName());
}
}
if (m_valid) {
bool tooManyArgs =
(m_params && m_params->outputCPPTooManyArgsPre(cg, ar, m_name));
if (!m_className.empty()) {
cg.printf("%s%s::", Option::ClassPrefix, m_className.c_str());
if (m_name == "__construct" && cls) {
FunctionScopePtr func = cls->findConstructor(ar, true);
cg.printf("%s%s(", Option::MethodPrefix, func->getName().c_str());
} else {
cg.printf("%s%s(", Option::MethodPrefix, m_name.c_str());
}
} else {
int paramCount = m_params ? m_params->getCount() : 0;
if (m_name == "get_class" && ar->getClassScope() && paramCount == 0) {
cg.printf("(\"%s\"", ar->getClassScope()->getOriginalName());
} else if (m_name == "get_parent_class" && ar->getClassScope() &&
paramCount == 0) {
const std::string parentClass = ar->getClassScope()->getParent();
if (!parentClass.empty()) {
cg.printf("(\"%s\"", ar->getClassScope()->getParent().c_str());
} else {
cg.printf("(false");
}
} else {
if (m_noPrefix) {
cg.printf("%s(", m_name.c_str());
}
else {
cg.printf("%s%s(", m_builtinFunction ? Option::BuiltinFunctionPrefix :
Option::FunctionPrefix, m_name.c_str());
}
}
}
FunctionScope::outputCPPArguments(m_params, cg, ar, m_extraArg,
m_variableArgument, m_argArrayId);
cg.printf(")");
if (tooManyArgs) {
m_params->outputCPPTooManyArgsPost(cg, ar, m_voidReturn);
}
} else {
if (m_className.empty()) {
if (m_redeclared && !m_dynamicInvoke) {
if (canInvokeFewArgs()) {
cg.printf("%s->%s%s_few_args(", cg.getGlobals(ar),
Option::InvokePrefix, m_name.c_str());
int left = Option::InvokeFewArgsCount;
if (m_params && m_params->getCount()) {
left -= m_params->getCount();
cg.printf("%d, ", m_params->getCount());
FunctionScope::outputCPPArguments(m_params, cg, ar, 0, false);
} else {
cg.printf("0");
}
for (int i = 0; i < left; i++) {
cg.printf(", null_variant");
}
cg.printf(")");
return;
} else {
cg.printf("%s->%s%s(", cg.getGlobals(ar), Option::InvokePrefix,
m_name.c_str());
}
} else {
cg.printf("invoke(\"%s\", ", m_name.c_str());
}
} else {
bool inObj = m_parentClass && ar->getClassScope() &&
!dynamic_pointer_cast<FunctionScope>(ar->getScope())->isStatic();
if (m_redeclaredClass) {
if (inObj) { // parent is redeclared
cg.printf("parent->%sinvoke(\"%s\",", Option::ObjectPrefix,
m_name.c_str());
} else {
//.........这里部分代码省略.........
示例15: analyzeProgram
void AnalysisResult::analyzeProgram(bool system /* = false */) {
AnalysisResultPtr ar = shared_from_this();
getVariables()->forceVariants(ar, VariableTable::AnyVars);
getVariables()->setAttribute(VariableTable::ContainsLDynamicVariable);
getVariables()->setAttribute(VariableTable::ContainsExtract);
getVariables()->setAttribute(VariableTable::ForceGlobal);
// Analyze Includes
Logger::Verbose("Analyzing Includes");
sort(m_fileScopes.begin(), m_fileScopes.end(), by_filename); // fixed order
unsigned int i = 0;
for (i = 0; i < m_fileScopes.size(); i++) {
collectFunctionsAndClasses(m_fileScopes[i]);
}
// Keep generated code identical without randomness
canonicalizeSymbolOrder();
markRedeclaringClasses();
// Analyze some special cases
for (set<string>::const_iterator it = Option::VolatileClasses.begin();
it != Option::VolatileClasses.end(); ++it) {
ClassScopePtr cls = findClass(toLower(*it));
if (cls && cls->isUserClass()) {
cls->setVolatile();
}
}
checkClassDerivations();
resolveNSFallbackFuncs();
// Analyze All
Logger::Verbose("Analyzing All");
setPhase(AnalysisResult::AnalyzeAll);
for (i = 0; i < m_fileScopes.size(); i++) {
m_fileScopes[i]->analyzeProgram(ar);
}
/*
Note that cls->collectMethods() can add entries to m_classDecs,
which can invalidate iterators. So we have to create an array
and then iterate over that.
The new entries added to m_classDecs are always empty, so it
doesnt matter that we dont include them in the iteration
*/
std::vector<ClassScopePtr> classes;
classes.reserve(m_classDecs.size());
for (StringToClassScopePtrVecMap::const_iterator iter = m_classDecs.begin();
iter != m_classDecs.end(); ++iter) {
for (ClassScopePtr cls: iter->second) {
classes.push_back(cls);
}
}
// Collect methods
for (ClassScopePtr cls: classes) {
if (cls->isRedeclaring()) {
cls->setStaticDynamic(ar);
}
StringToFunctionScopePtrMap methods;
cls->collectMethods(ar, methods, true /* include privates */);
bool needAbstractMethodImpl =
(!cls->isAbstract() && !cls->isInterface() &&
cls->derivesFromRedeclaring() == Derivation::Normal &&
!cls->getAttribute(ClassScope::UsesUnknownTrait));
for (StringToFunctionScopePtrMap::const_iterator iterMethod =
methods.begin(); iterMethod != methods.end(); ++iterMethod) {
FunctionScopePtr func = iterMethod->second;
if (Option::WholeProgram && !func->hasImpl() && needAbstractMethodImpl) {
FunctionScopePtr tmpFunc =
cls->findFunction(ar, func->getName(), true, true);
always_assert(!tmpFunc || !tmpFunc->hasImpl());
Compiler::Error(Compiler::MissingAbstractMethodImpl,
func->getStmt(), cls->getStmt());
}
m_methodToClassDecs[iterMethod->first].push_back(cls);
}
}
ClassScopePtr cls;
string cname;
for (auto& sysclass_cls: m_systemClasses) {
tie(cname, cls) = sysclass_cls;
StringToFunctionScopePtrMap methods;
cls->collectMethods(ar, methods, true /* include privates */);
for (StringToFunctionScopePtrMap::const_iterator iterMethod =
methods.begin(); iterMethod != methods.end(); ++iterMethod) {
m_methodToClassDecs[iterMethod->first].push_back(cls);
}
}
}