void SwitchStatement::analyzeProgram(AnalysisResultConstRawPtr ar) { if (ar->getPhase() == AnalysisResult::AnalyzeAll && m_exp->is(Expression::KindOfSimpleVariable)) { auto exp = dynamic_pointer_cast<SimpleVariable>(m_exp); if (exp && exp->getSymbol() && exp->getSymbol()->isClassName()) { // Mark some classes as volatile since the name is used in switch for (int i = 0; i < m_cases->getCount(); i++) { auto stmt = dynamic_pointer_cast<CaseStatement>((*m_cases)[i]); assert(stmt); ExpressionPtr caseCond = stmt->getCondition(); if (caseCond && caseCond->isScalar()) { auto name = dynamic_pointer_cast<ScalarExpression>(caseCond); if (name && name->isLiteralString()) { string className = name->getLiteralString(); ClassScopePtr cls = ar->findClass(toLower(className)); if (cls && cls->isUserClass()) { cls->setVolatile(); } } } } // Also note this down as code error ConstructPtr self = shared_from_this(); Compiler::Error(Compiler::ConditionalClassLoading, self); } } }
bool InterfaceStatement::checkVolatileBases(AnalysisResultConstRawPtr ar) { ClassScopeRawPtr classScope = getClassScope(); assert(!classScope->isVolatile()); auto const& bases = classScope->getBases(); for (auto it = bases.begin(); it != bases.end(); ++it) { ClassScopePtr base = ar->findClass(*it); if (base && base->isVolatile()) return true; } return false; }
void InterfaceStatement::analyzeProgram(AnalysisResultConstRawPtr ar) { if (ar->getPhase() != AnalysisResult::AnalyzeAll) return; std::vector<std::string> bases; if (m_base) m_base->getStrings(bases); for (unsigned int i = 0; i < bases.size(); i++) { ClassScopePtr cls = ar->findClass(bases[i]); if (cls) { if (!cls->isInterface()) { Compiler::Error( Compiler::InvalidDerivation, shared_from_this(), cls->getOriginalName() + " must be an interface"); } } } }