void Symbol::import(BlockScopeRawPtr scope, const Symbol &src_sym) { setName(src_sym.getName()); setSystem(); if (src_sym.declarationSet()) { ConstructPtr sc = src_sym.getDeclaration(); if (sc) sc->resetScope(scope); setDeclaration(sc); } if (src_sym.valueSet()) { ConstructPtr sc = src_sym.getValue(); if (sc) sc->resetScope(scope); setValue(sc); } if (src_sym.isDynamic()) { setDynamic(); } if (src_sym.isConstant()) { setConstant(); } m_coerced = src_sym.m_coerced; }
ASTvariable_declaration::ASTvariable_declaration (OSLCompilerImpl *comp, const TypeSpec &type, ustring name, ASTNode *init, bool isparam, bool ismeta, bool isoutput, bool initlist) : ASTNode (variable_declaration_node, comp, 0, init, NULL /* meta */), m_name(name), m_sym(NULL), m_isparam(isparam), m_isoutput(isoutput), m_ismetadata(ismeta), m_initlist(initlist) { m_typespec = type; Symbol *f = comp->symtab().clash (name); if (f) { std::string e = Strutil::format ("\"%s\" already declared in this scope", name.c_str()); if (f->node()) { boost::filesystem::path p(f->node()->sourcefile().string()); e += Strutil::format ("\n\t\tprevious declaration was at %s:%d", p.filename().c_str(), f->node()->sourceline()); } if (f->scope() == 0 && f->symtype() == SymTypeFunction && isparam) { // special case: only a warning for param to mask global function warning ("%s", e.c_str()); } else { error ("%s", e.c_str()); } } if (name[0] == '_' && name[1] == '_' && name[2] == '_') { error ("\"%s\" : sorry, can't start with three underscores", name.c_str()); } SymType symtype = isparam ? (isoutput ? SymTypeOutputParam : SymTypeParam) : SymTypeLocal; m_sym = new Symbol (name, type, symtype, this); if (! m_ismetadata) oslcompiler->symtab().insert (m_sym); // A struct really makes several subvariables if (type.is_structure() || type.is_structure_array()) { ASSERT (! m_ismetadata); // Add the fields as individual declarations m_compiler->add_struct_fields (type.structspec(), m_sym->name(), symtype, type.arraylength(), this); } }
void SemanticAnalysis::visitNameProxy(NameProxy *proxy) { Symbol *sym = proxy->sym(); VariableSymbol *var = sym->asVariable(); // If we see that a symbol is a function literal, then we bypass the scope // chain operations entirely and hardcode the function literal. if (sym->isFunction()) { assert(sym->scope()->kind() == Scope::Global); hir_ = new (pool_) HFunction(proxy, sym->asFunction()); return; } if (value_context_ == kLValue) { // Egads! We're being asked to construct an l-value instead of an r-value. *outp_ = LValue(var); return; } Scope *in = sym->scope(); switch (in->kind()) { case Scope::Global: hir_ = new (pool_) HGlobal(proxy, var); return; case Scope::Function: { assert(var->storage() == VariableSymbol::Arg); // Since we're in an r-value context, we need to strip the reference type. Type *type = var->type(); if (type->isReference()) type = type->toReference()->contained(); hir_ = new (pool_) HLocal(proxy, type, var); return; } default: assert(in->kind() == Scope::Block); assert(var->storage() == VariableSymbol::Local); hir_ = new (pool_) HLocal(proxy, var->type(), var); return; } }
void execute() { std::sort(m_rootEntries.begin(), m_rootEntries.end(), reCmp); for (int i = 0; i < m_size; i++) { RootEntry &re = m_rootEntries[i]; if (!re.second) break; const AstWalkerState &s = re.first[re.first.size() - 1]; StatementPtr sp(dynamic_pointer_cast<Statement>(s.cp)); assert(sp); StatementListPtr sl; int ix; if (sp->is(Statement::KindOfStatementList)) { sl = static_pointer_cast<StatementList>(sp); ix = (s.index - 1) / 2; } else { assert(sp->is(Statement::KindOfBlockStatement)); sl = static_pointer_cast<BlockStatement>(sp)->getStmts(); if (!sl) continue; ix = 0; } ExpressionPtr e = m_dict.get(re.second); assert(e && e->is(Expression::KindOfSimpleVariable)); SimpleVariablePtr sv(static_pointer_cast<SimpleVariable>(e)); Symbol *sym = sv->getSymbol(); bool inGen = sv->getFunctionScope()->isGenerator(); if (!sym || sym->isGlobal() || sym->isStatic() || sym->isParameter() || sym->isClosureVar() || sv->isThis() || inGen) { continue; } sym->setShrinkWrapped(); e = e->clone(); e->clearContext(); e->recomputeEffects(); e->setContext(Expression::Declaration); StatementPtr sub = (*sl)[ix]; e->setLocation(sub->getLocation()); e->setBlockScope(sub->getScope()); ExpStatementPtr exp( new ExpStatement(sub->getScope(), sub->getLocation(), e)); sl->insertElement(exp, ix); } }
BPatch_variableExpr *BPatch_image::createVarExprByName(BPatch_module *mod, const char *name) { Symbol syminfo; BPatch_type *type; type = mod->getModuleTypes()->globalVarsByName[name]; if (!type) { switch (syminfo.size()) { case 1: type = findType("char"); break; case 2: type = findType("short"); break; case 8: type = findType("integer*8"); break; case 4: default: type = findType("int"); break; } } if (!type) return NULL; if (!proc->llproc->getSymbolInfo(name, syminfo)) { return NULL; } // Error case. if (syminfo.addr() == 0) return NULL; BPatch_variableExpr *var = AddrToVarExpr->hash[syminfo.addr()]; if (!var) { var = new BPatch_variableExpr( const_cast<char *>(name), proc, (void *)syminfo.addr(), type); AddrToVarExpr->hash[syminfo.addr()] = var; } return var; }
void VariableTable::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) { if (Option::GenerateInferredTypes) { for (unsigned int i = 0; i < m_symbolVec.size(); i++) { Symbol *sym = m_symbolVec[i]; if (isInherited(sym->getName())) continue; if (sym->isParameter()) { cg_printf("// @param "); } else if (sym->isGlobal()) { cg_printf("// @global "); } else if (sym->isStatic()) { cg_printf("// @static "); } else { cg_printf("// @local "); } cg_printf("%s\t$%s\n", sym->getFinalType()->toString().c_str(), sym->getName().c_str()); } } if (Option::ConvertSuperGlobals && !getAttribute(ContainsDynamicVariable)) { std::set<string> convertibles; typedef std::pair<const string,Symbol> symPair; BOOST_FOREACH(symPair &sym, m_symbolMap) { if (sym.second.isSuperGlobal() && !sym.second.declarationSet()) { convertibles.insert(sym.second.getName()); } } if (!convertibles.empty()) { cg_printf("/* converted super globals */ global "); for (std::set<string>::const_iterator iter = convertibles.begin(); iter != convertibles.end(); ++iter) { if (iter != convertibles.begin()) cg_printf(","); cg_printf("$%s", iter->c_str()); } cg_printf(";\n"); } }
void ClosureExpression::analyzeProgram(AnalysisResultPtr ar) { m_func->analyzeProgram(ar); if (m_vars) { m_values->analyzeProgram(ar); if (ar->getPhase() == AnalysisResult::AnalyzeAll) { m_func->getFunctionScope()->setClosureVars(m_vars); // closure function's variable table (not containing function's) VariableTablePtr variables = m_func->getFunctionScope()->getVariables(); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); string name = param->getName(); { Symbol *sym = variables->addSymbol(name); sym->setClosureVar(); if (param->isRef()) { sym->setRefClosureVar(); } } } return; } if (ar->getPhase() == AnalysisResult::AnalyzeFinal) { // closure function's variable table (not containing function's) VariableTablePtr variables = m_func->getFunctionScope()->getVariables(); for (int i = 0; i < m_vars->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]); string name = param->getName(); // so we can assign values to them, instead of seeing CVarRef Symbol *sym = variables->getSymbol(name); if (sym && sym->isParameter()) { sym->setLvalParam(); } } } } }
void IdentifierNode::generateILOCCode(Node* context) { if (this->children->size() == 0) { // Variable Symbol* symbol = Scope::getSymbol(this->symbol->getText()); Node* symbolScope = Scope::getScope(this->symbol->getText()); std::string* varAddressRegisterName = ILOC::getRegister(symbol->getText()); std::string registerBaseAddress = (symbolScope->getNodeType() == Common::NT_PROGRAM) ? "bss" : "fp"; std::stringstream symbolOffsetStr; symbolOffsetStr << symbol->getOffset(); ILOC* instruction = new ILOC(Common::ILOC_LOADAI, registerBaseAddress, symbolOffsetStr.str(), *varAddressRegisterName, ""); this->addInstruction(instruction); this->setLastRegister(*varAddressRegisterName); } else { // vector Symbol* symbol = Scope::getSymbol(this->symbol->getText()); Node* symbolScope = Scope::getScope(this->symbol->getText()); std::string* vectorAddressRegisterName = ILOC::getRegister(symbol->getText()); std::string registerBaseAddress = (symbolScope->getNodeType() == Common::NT_PROGRAM) ? "bss" : "fp"; std::stringstream symbolOffsetStr; symbolOffsetStr << symbol->getOffset(); ILOC* instruction = new ILOC(Common::ILOC_ADDI, registerBaseAddress, symbolOffsetStr.str(), *vectorAddressRegisterName, ""); this->addInstruction(instruction); std::string lastBaseRegister = *vectorAddressRegisterName; std::string* indexRegisterName; for (unsigned int i = 0; i < this->children->size(); i++) { ExpressionNode* expression = dynamic_cast<ExpressionNode*>(this->children->at(i)); expression->generateILOCCode(this); std::stringstream indexStream; indexStream << i; std::string* multResultRegisterName = ILOC::getRegister("INST_MULT_VEC_RESULT_" + indexStream.str()); indexRegisterName = ILOC::getRegister("INDEX_REGISTER_NAME_" + indexStream.str()); ILOC* instructionMult = new ILOC(Common::ILOC_MULTI, expression->getLastRegister(), "4", *multResultRegisterName, ""); ILOC* instructionLoadAO = new ILOC(Common::ILOC_LOADA0, lastBaseRegister, *multResultRegisterName, *indexRegisterName, ""); lastBaseRegister = *indexRegisterName; this->addInstruction(instructionMult); this->addInstruction(instructionLoadAO); } this->setLastRegister(*indexRegisterName); } }
void DisassemblerDatabase::saveSymbols() { SQLiteStatement(this->_disassemblerdb, "BEGIN").execute(); SQLiteStatement s(this->_disassemblerdb, "INSERT INTO SymbolTable (Address, Name, Type, Size, ReferenceCount) VALUES (?, ?, ?, ?, ?)"); for(SymbolTable::Iterator it = this->_symboltable->begin(); it != this->_symboltable->end(); it++) { Symbol* symbol = it.value(); const QList<DataValue>& sources = symbol->sources(); sqlite3_int64 address = symbol->startAddress().compatibleValue<sqlite3_int64>(); s.bind(1, address); s.bind(2, symbol->name().toUtf8().constData()); s.bind(3, static_cast<sqlite3_int64>(symbol->type())); s.bind(4, symbol->size().compatibleValue<sqlite3_int64>()); s.bind(5, sources.count()); s.step(); s.reset(); } SQLiteStatement(this->_disassemblerdb, "COMMIT").execute(); }
void ASTfunction_declaration::add_meta (ASTNode *meta) { for ( ; meta; meta = meta->nextptr()) { ASSERT (meta->nodetype() == ASTNode::variable_declaration_node); const ASTvariable_declaration *metavar = static_cast<const ASTvariable_declaration *>(meta); Symbol *metasym = metavar->sym(); if (metasym->name() == "builtin") { m_is_builtin = true; if (func()->typespec().is_closure()) // It is a builtin closure // Force keyword arguments at the end func()->argcodes(ustring(std::string(func()->argcodes().c_str()) + ".")); } else if (metasym->name() == "derivs") func()->takes_derivs (true); else if (metasym->name() == "printf_args") func()->printf_args (true); else if (metasym->name() == "texture_args") func()->texture_args (true); else if (metasym->name() == "rw") func()->readwrite_special_case (true); } }
AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { Symtab *symtab = GetSymtab(); if (symtab) { Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr); if (symbol) { if (symbol->ValueIsAddress()) { const SectionSP section_sp(symbol->GetAddressRef().GetSection()); if (section_sp) { const SectionType section_type = section_sp->GetType(); switch (section_type) { case eSectionTypeInvalid: return eAddressClassUnknown; case eSectionTypeCode: return eAddressClassCode; case eSectionTypeContainer: return eAddressClassUnknown; case eSectionTypeData: case eSectionTypeDataCString: case eSectionTypeDataCStringPointers: case eSectionTypeDataSymbolAddress: case eSectionTypeData4: case eSectionTypeData8: case eSectionTypeData16: case eSectionTypeDataPointers: case eSectionTypeZeroFill: case eSectionTypeDataObjCMessageRefs: case eSectionTypeDataObjCCFStrings: case eSectionTypeGoSymtab: return eAddressClassData; case eSectionTypeDebug: case eSectionTypeDWARFDebugAbbrev: case eSectionTypeDWARFDebugAddr: case eSectionTypeDWARFDebugAranges: case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: case eSectionTypeDWARFDebugLine: case eSectionTypeDWARFDebugLoc: case eSectionTypeDWARFDebugMacInfo: case eSectionTypeDWARFDebugMacro: case eSectionTypeDWARFDebugPubNames: case eSectionTypeDWARFDebugPubTypes: case eSectionTypeDWARFDebugRanges: case eSectionTypeDWARFDebugStr: case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFAppleNames: case eSectionTypeDWARFAppleTypes: case eSectionTypeDWARFAppleNamespaces: case eSectionTypeDWARFAppleObjC: return eAddressClassDebug; case eSectionTypeEHFrame: case eSectionTypeARMexidx: case eSectionTypeARMextab: case eSectionTypeCompactUnwind: return eAddressClassRuntime; case eSectionTypeELFSymbolTable: case eSectionTypeELFDynamicSymbols: case eSectionTypeELFRelocationEntries: case eSectionTypeELFDynamicLinkInfo: case eSectionTypeOther: return eAddressClassUnknown; case eSectionTypeAbsoluteAddress: // In case of absolute sections decide the address class based on // the symbol // type because the section type isn't specify if it is a code or a // data // section. break; } } } const SymbolType symbol_type = symbol->GetType(); switch (symbol_type) { case eSymbolTypeAny: return eAddressClassUnknown; case eSymbolTypeAbsolute: return eAddressClassUnknown; case eSymbolTypeCode: return eAddressClassCode; case eSymbolTypeTrampoline: return eAddressClassCode; case eSymbolTypeResolver: return eAddressClassCode; case eSymbolTypeData: return eAddressClassData; case eSymbolTypeRuntime: return eAddressClassRuntime; case eSymbolTypeException: return eAddressClassRuntime; case eSymbolTypeSourceFile: return eAddressClassDebug; case eSymbolTypeHeaderFile: return eAddressClassDebug; case eSymbolTypeObjectFile: return eAddressClassDebug; case eSymbolTypeCommonBlock: return eAddressClassDebug; case eSymbolTypeBlock: return eAddressClassDebug; case eSymbolTypeLocal: return eAddressClassData; case eSymbolTypeParam: return eAddressClassData; case eSymbolTypeVariable: return eAddressClassData; case eSymbolTypeVariableType: return eAddressClassDebug; case eSymbolTypeLineEntry: return eAddressClassDebug; case eSymbolTypeLineHeader: return eAddressClassDebug; case eSymbolTypeScopeBegin: return eAddressClassDebug; case eSymbolTypeScopeEnd: return eAddressClassDebug; case eSymbolTypeAdditional: return eAddressClassUnknown; case eSymbolTypeCompiler: return eAddressClassDebug; case eSymbolTypeInstrumentation: return eAddressClassDebug; case eSymbolTypeUndefined: return eAddressClassUnknown; case eSymbolTypeObjCClass: return eAddressClassRuntime; case eSymbolTypeObjCMetaClass: return eAddressClassRuntime; case eSymbolTypeObjCIVar: return eAddressClassRuntime; case eSymbolTypeReExported: return eAddressClassRuntime; } } } return eAddressClassUnknown; }
bool OSLCompilerImpl::compile (const std::string &filename, const std::vector<std::string> &options) { if (! boost::filesystem::exists (filename)) { error (ustring(), 0, "Input file \"%s\" not found", filename.c_str()); return false; } std::string stdinclude; #ifdef USE_BOOST_WAVE std::vector<std::string> defines; std::vector<std::string> undefines; std::vector<std::string> includepaths; #else std::string cppoptions; #endif // Determine where the installed shader include directory is, and // look for ../shaders/stdosl.h and force it to include. std::string program = Sysutil::this_program_path (); if (program.size()) { boost::filesystem::path path (program); // our program #if BOOST_VERSION >= 103600 path = path.parent_path (); // now the bin dir of our program path = path.parent_path (); // now the parent dir #else path = path.branch_path (); // now the bin dir of our program path = path.branch_path (); // now the parent dir #endif path = path / "shaders"; bool found = false; if (boost::filesystem::exists (path)) { path = path / "stdosl.h"; if (boost::filesystem::exists (path)) { stdinclude = path.string(); found = true; } } if (! found) warning (ustring(filename), 0, "Unable to find \"%s\"", path.string().c_str()); } m_output_filename.clear (); bool preprocess_only = false; for (size_t i = 0; i < options.size(); ++i) { if (options[i] == "-v") { // verbose mode m_verbose = true; } else if (options[i] == "-q") { // quiet mode m_quiet = true; } else if (options[i] == "-d") { // debug mode m_debug = true; } else if (options[i] == "-E") { preprocess_only = true; } else if (options[i] == "-o" && i < options.size()-1) { ++i; m_output_filename = options[i]; } else if (options[i] == "-O0") { m_optimizelevel = 0; } else if (options[i] == "-O" || options[i] == "-O1") { m_optimizelevel = 1; } else if (options[i] == "-O2") { m_optimizelevel = 2; #ifdef USE_BOOST_WAVE } else if (options[i].c_str()[0] == '-' && options[i].size() > 2) { // options meant for the preprocessor if(options[i].c_str()[1] == 'D') defines.push_back(options[i].substr(2)); else if(options[i].c_str()[1] == 'U') undefines.push_back(options[i].substr(2)); else if(options[i].c_str()[1] == 'I') includepaths.push_back(options[i].substr(2)); #else } else { // something meant for the cpp command cppoptions += "\""; cppoptions += options[i]; cppoptions += "\" "; #endif } } std::string preprocess_result; #ifdef USE_BOOST_WAVE if (! preprocess(filename, stdinclude, defines, undefines, includepaths, preprocess_result)) { #else if (! preprocess(filename, stdinclude, cppoptions, preprocess_result)) { #endif return false; } else if (preprocess_only) { std::cout << preprocess_result; } else { std::istringstream in (preprocess_result); oslcompiler = this; // Create a lexer, parse the file, delete the lexer m_lexer = new oslFlexLexer (&in); oslparse (); bool parseerr = error_encountered(); delete m_lexer; if (! parseerr) { shader()->typecheck (); } // Print the parse tree if there were no errors if (m_debug) { symtab().print (); if (shader()) shader()->print (std::cout); } if (! error_encountered()) { shader()->codegen (); // add_useparam (); track_variable_dependencies (); track_variable_lifetimes (); check_for_illegal_writes (); // if (m_optimizelevel >= 1) // coalesce_temporaries (); } if (! error_encountered()) { if (m_output_filename.size() == 0) m_output_filename = default_output_filename (); write_oso_file (m_output_filename); } oslcompiler = NULL; } return ! error_encountered(); } struct GlobalTable { const char *name; TypeSpec type; }; static GlobalTable globals[] = { { "P", TypeDesc::TypePoint }, { "I", TypeDesc::TypeVector }, { "N", TypeDesc::TypeNormal }, { "Ng", TypeDesc::TypeNormal }, { "u", TypeDesc::TypeFloat }, { "v", TypeDesc::TypeFloat }, { "dPdu", TypeDesc::TypeVector }, { "dPdv", TypeDesc::TypeVector }, #if 0 // Light variables -- we don't seem to be on a route to support this // kind of light shader, so comment these out for now. { "L", TypeDesc::TypeVector }, { "Cl", TypeDesc::TypeColor }, { "Ns", TypeDesc::TypeNormal }, { "Pl", TypeDesc::TypePoint }, { "Nl", TypeDesc::TypeNormal }, #endif { "Ps", TypeDesc::TypePoint }, { "Ci", TypeSpec (TypeDesc::TypeColor, true) }, { "time", TypeDesc::TypeFloat }, { "dtime", TypeDesc::TypeFloat }, { "dPdtime", TypeDesc::TypeVector }, { NULL } }; void OSLCompilerImpl::initialize_globals () { for (int i = 0; globals[i].name; ++i) { Symbol *s = new Symbol (ustring(globals[i].name), globals[i].type, SymTypeGlobal); symtab().insert (s); } } std::string OSLCompilerImpl::default_output_filename () { if (m_shader && shader_decl()) return shader_decl()->shadername().string() + ".oso"; return std::string(); } void OSLCompilerImpl::write_oso_metadata (const ASTNode *metanode) const { ASSERT (metanode->nodetype() == ASTNode::variable_declaration_node); const ASTvariable_declaration *metavar = static_cast<const ASTvariable_declaration *>(metanode); Symbol *metasym = metavar->sym(); ASSERT (metasym); TypeSpec ts = metasym->typespec(); oso ("%%meta{%s,%s,", ts.string().c_str(), metasym->name().c_str()); const ASTNode *init = metavar->init().get(); ASSERT (init); if (ts.is_string() && init->nodetype() == ASTNode::literal_node) oso ("\"%s\"", ((const ASTliteral *)init)->strval()); else if (ts.is_int() && init->nodetype() == ASTNode::literal_node) oso ("%d", ((const ASTliteral *)init)->intval()); else if (ts.is_float() && init->nodetype() == ASTNode::literal_node) oso ("%.8g", ((const ASTliteral *)init)->floatval()); // FIXME -- what about type constructors? else { std::cout << "Error, don't know how to print metadata " << ts.string() << " with node type " << init->nodetypename() << "\n"; ASSERT (0); // FIXME } oso ("} "); }
void BytecodePrinter::print_attributes(int bci, outputStream* st) { // Show attributes of pre-rewritten codes Bytecodes::Code code = Bytecodes::java_code(raw_code()); // If the code doesn't have any fields there's nothing to print. // note this is ==1 because the tableswitch and lookupswitch are // zero size (for some reason) and we want to print stuff out for them. if (Bytecodes::length_for(code) == 1) { st->cr(); return; } switch(code) { // Java specific bytecodes only matter. case Bytecodes::_bipush: st->print_cr(" " INT32_FORMAT, get_byte()); break; case Bytecodes::_sipush: st->print_cr(" " INT32_FORMAT, get_short()); break; case Bytecodes::_ldc: if (Bytecodes::uses_cp_cache(raw_code())) { print_constant(get_index_u1_cpcache(), st); } else { print_constant(get_index_u1(), st); } break; case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: if (Bytecodes::uses_cp_cache(raw_code())) { print_constant(get_index_u2_cpcache(), st); } else { print_constant(get_index_u2(), st); } break; case Bytecodes::_iload: case Bytecodes::_lload: case Bytecodes::_fload: case Bytecodes::_dload: case Bytecodes::_aload: case Bytecodes::_istore: case Bytecodes::_lstore: case Bytecodes::_fstore: case Bytecodes::_dstore: case Bytecodes::_astore: st->print_cr(" #%d", get_index_special()); break; case Bytecodes::_iinc: { int index = get_index_special(); jint offset = is_wide() ? get_short(): get_byte(); st->print_cr(" #%d " INT32_FORMAT, index, offset); } break; case Bytecodes::_newarray: { BasicType atype = (BasicType)get_index_u1(); const char* str = type2name(atype); if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) { assert(false, "Unidentified basic type"); } st->print_cr(" %s", str); } break; case Bytecodes::_anewarray: { int klass_index = get_index_u2(); ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s ", name->as_C_string()); } break; case Bytecodes::_multianewarray: { int klass_index = get_index_u2(); int nof_dims = get_index_u1(); ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s %d", name->as_C_string(), nof_dims); } break; case Bytecodes::_ifeq: case Bytecodes::_ifnull: case Bytecodes::_iflt: case Bytecodes::_ifle: case Bytecodes::_ifne: case Bytecodes::_ifnonnull: case Bytecodes::_ifgt: case Bytecodes::_ifge: case Bytecodes::_if_icmpeq: case Bytecodes::_if_icmpne: case Bytecodes::_if_icmplt: case Bytecodes::_if_icmpgt: case Bytecodes::_if_icmple: case Bytecodes::_if_icmpge: case Bytecodes::_if_acmpeq: case Bytecodes::_if_acmpne: case Bytecodes::_goto: case Bytecodes::_jsr: st->print_cr(" %d", bci + get_short()); break; case Bytecodes::_goto_w: case Bytecodes::_jsr_w: st->print_cr(" %d", bci + get_int()); break; case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break; case Bytecodes::_tableswitch: { align(); int default_dest = bci + get_int(); int lo = get_int(); int hi = get_int(); int len = hi - lo + 1; jint* dest = NEW_RESOURCE_ARRAY(jint, len); for (int i = 0; i < len; i++) { dest[i] = bci + get_int(); } st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ", default_dest, lo, hi); int first = true; for (int ll = lo; ll <= hi; ll++, first = false) { int idx = ll - lo; const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" : ", %d:" INT32_FORMAT " (delta: %d)"; st->print(format, ll, dest[idx], dest[idx]-bci); } st->cr(); } break; case Bytecodes::_lookupswitch: { align(); int default_dest = bci + get_int(); int len = get_int(); jint* key = NEW_RESOURCE_ARRAY(jint, len); jint* dest = NEW_RESOURCE_ARRAY(jint, len); for (int i = 0; i < len; i++) { key [i] = get_int(); dest[i] = bci + get_int(); }; st->print(" %d %d ", default_dest, len); bool first = true; for (int ll = 0; ll < len; ll++, first = false) { const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT : ", " INT32_FORMAT ":" INT32_FORMAT ; st->print(format, key[ll], dest[ll]); } st->cr(); } break; case Bytecodes::_putstatic: case Bytecodes::_getstatic: case Bytecodes::_putfield: case Bytecodes::_getfield: print_field_or_method(get_index_u2_cpcache(), st); break; case Bytecodes::_invokevirtual: case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: print_field_or_method(get_index_u2_cpcache(), st); break; case Bytecodes::_invokeinterface: { int i = get_index_u2_cpcache(); int n = get_index_u1(); get_byte(); // ignore zero byte print_field_or_method(i, st); } break; case Bytecodes::_invokedynamic: print_field_or_method(get_index_u4(), st); break; case Bytecodes::_new: case Bytecodes::_checkcast: case Bytecodes::_instanceof: { int i = get_index_u2(); ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(i); st->print_cr(" %d <%s>", i, name->as_C_string()); } break; case Bytecodes::_wide: // length is zero not one, but printed with no more info. break; default: ShouldNotReachHere(); break; } }
Symbol* Symbol::create(VM& vm) { Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm); symbol->finishCreation(vm); return symbol; }
bool operator==(const std::string &lhs, const Symbol &rhs) { return rhs.GetName() == lhs; }
AddressClass ObjectFile::GetAddressClass (addr_t file_addr) { Symtab *symtab = GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList); if (symtab) { Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr); if (symbol) { if (symbol->ValueIsAddress()) { const SectionSP section_sp (symbol->GetAddress().GetSection()); if (section_sp) { const SectionType section_type = section_sp->GetType(); switch (section_type) { case eSectionTypeInvalid: return eAddressClassUnknown; case eSectionTypeCode: return eAddressClassCode; case eSectionTypeContainer: return eAddressClassUnknown; case eSectionTypeData: case eSectionTypeDataCString: case eSectionTypeDataCStringPointers: case eSectionTypeDataSymbolAddress: case eSectionTypeData4: case eSectionTypeData8: case eSectionTypeData16: case eSectionTypeDataPointers: case eSectionTypeZeroFill: case eSectionTypeDataObjCMessageRefs: case eSectionTypeDataObjCCFStrings: return eAddressClassData; case eSectionTypeDebug: case eSectionTypeDWARFDebugAbbrev: case eSectionTypeDWARFDebugAranges: case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: case eSectionTypeDWARFDebugLine: case eSectionTypeDWARFDebugLoc: case eSectionTypeDWARFDebugMacInfo: case eSectionTypeDWARFDebugPubNames: case eSectionTypeDWARFDebugPubTypes: case eSectionTypeDWARFDebugRanges: case eSectionTypeDWARFDebugStr: case eSectionTypeDWARFAppleNames: case eSectionTypeDWARFAppleTypes: case eSectionTypeDWARFAppleNamespaces: case eSectionTypeDWARFAppleObjC: return eAddressClassDebug; case eSectionTypeEHFrame: return eAddressClassRuntime; case eSectionTypeELFSymbolTable: case eSectionTypeELFDynamicSymbols: case eSectionTypeELFRelocationEntries: case eSectionTypeELFDynamicLinkInfo: case eSectionTypeOther: return eAddressClassUnknown; } } } const SymbolType symbol_type = symbol->GetType(); switch (symbol_type) { case eSymbolTypeAny: return eAddressClassUnknown; case eSymbolTypeAbsolute: return eAddressClassUnknown; case eSymbolTypeCode: return eAddressClassCode; case eSymbolTypeTrampoline: return eAddressClassCode; case eSymbolTypeResolver: return eAddressClassCode; case eSymbolTypeData: return eAddressClassData; case eSymbolTypeRuntime: return eAddressClassRuntime; case eSymbolTypeException: return eAddressClassRuntime; case eSymbolTypeSourceFile: return eAddressClassDebug; case eSymbolTypeHeaderFile: return eAddressClassDebug; case eSymbolTypeObjectFile: return eAddressClassDebug; case eSymbolTypeCommonBlock: return eAddressClassDebug; case eSymbolTypeBlock: return eAddressClassDebug; case eSymbolTypeLocal: return eAddressClassData; case eSymbolTypeParam: return eAddressClassData; case eSymbolTypeVariable: return eAddressClassData; case eSymbolTypeVariableType: return eAddressClassDebug; case eSymbolTypeLineEntry: return eAddressClassDebug; case eSymbolTypeLineHeader: return eAddressClassDebug; case eSymbolTypeScopeBegin: return eAddressClassDebug; case eSymbolTypeScopeEnd: return eAddressClassDebug; case eSymbolTypeAdditional: return eAddressClassUnknown; case eSymbolTypeCompiler: return eAddressClassDebug; case eSymbolTypeInstrumentation:return eAddressClassDebug; case eSymbolTypeUndefined: return eAddressClassUnknown; case eSymbolTypeObjCClass: return eAddressClassRuntime; case eSymbolTypeObjCMetaClass: return eAddressClassRuntime; case eSymbolTypeObjCIVar: return eAddressClassRuntime; } } } return eAddressClassUnknown; }
/** This function initializes the Elf members @internalComponent @released */ void ElfProducer::InitElfContents() { iElfHeader = new Elf32_Ehdr; iSections = new Elf32_Shdr[MAX_SECTIONS+1]; iElfDynSym = new Elf32_Sym[iNSymbols]; iVersionTbl = new Elf32_Half[iNSymbols]; iVersionDef = new Elf32_Verdef[2]; iDSODaux = new Elf32_Verdaux[2]; iProgHeader = new Elf32_Phdr[2]; iCodeSectionData = new PLUINT32[iNSymbols]; iHashTbl = new Elf32_HashTable; //premeditated iHashTbl->nBuckets = (iNSymbols /3) + (iNSymbols % 0x3); iHashTbl->nChains = iNSymbols; iDSOBuckets = new Elf32_Sword[iHashTbl->nBuckets]; iDSOChains = new Elf32_Sword[iHashTbl->nChains]; Elf32_Sword aNullPtr = 0; memset(iDSOBuckets, aNullPtr, sizeof(Elf32_Sword)*iHashTbl->nBuckets); memset(iDSOChains, aNullPtr, sizeof(Elf32_Sword)*iHashTbl->nChains); memset(iCodeSectionData, 0, sizeof(PLUINT32)*iNSymbols); CreateElfHeader(); SymbolList::iterator aItr = iSymbolsList->begin(); SymbolList::iterator aEnd = iSymbolsList->end(); Symbol *aSym; PLUINT32 aIdx = 1; memset( &iElfDynSym[0], 0, sizeof(Elf32_Sym)); iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0); while(aItr != aEnd) { String aSymName(""); aSym = *aItr; aSymName = aSym->SymbolName(); //set symbol info.. iElfDynSym[aIdx].st_name = iDSOSymNameStrTbl.size(); iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), aSymName.begin(), aSymName.end() ); iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0); SetSymolFields( aSym, &iElfDynSym[aIdx], aIdx); //set version table info... iVersionTbl[aIdx] = DEFAULT_VERSION; AddToHashTable(aSym->SymbolName(), aIdx); aItr++;aIdx++; } CreateVersionTable(); //Fill section headers... CreateSections(); //Copy dyn entries.. CreateDynamicEntries(); //create code section data - this has the ordinal numbers... CreateProgHeader(); }
void print_symbols( std::vector< Symbol *>& allsymbols ) { FILE* fd = stdout; Symbol *sym; std::string modname; if (!____sym_hdr_printed) { fprintf(fd, "%-20s %-15s %-10s %5s SEC TYP LN VIS INFO\n", "SYMBOL", "MODULE", "ADDR", "SIZE"); ____sym_hdr_printed = true; } for (unsigned i=0; i<allsymbols.size(); i++) { sym = allsymbols[i]; modname = (sym->getModule() ? sym->getModule()->fileName() : ""); //if (sym->getName() == "__gmon_start__") { //if (modname == "libspecial.so" || modname == "libprofile.so") { //if (sym->getLinkage() == Symbol::SL_WEAK) { //if (sym->isInDynSymtab()) { if (1) { fprintf(fd, "%-20s %-15s 0x%08x %5u %3u", sym->getMangledName().substr(0,20).c_str(), //modname.size() > 15 ? modname.substr(modname.size()-15,15).c_str() : modname.c_str(), "", (unsigned)sym->getOffset(), (unsigned)sym->getSize(), sym->getRegion() ? sym->getRegion()->getRegionNumber() : 0 ); switch (sym->getType()) { case Symbol::ST_FUNCTION: fprintf(fd, " FUN"); break; case Symbol::ST_TLS: fprintf(fd, " TLS"); break; case Symbol::ST_OBJECT: fprintf(fd, " OBJ"); break; case Symbol::ST_MODULE: fprintf(fd, " MOD"); break; case Symbol::ST_SECTION: fprintf(fd, " SEC"); break; case Symbol::ST_DELETED: fprintf(fd, " DEL"); break; case Symbol::ST_NOTYPE: fprintf(fd, " - "); break; default: case Symbol::ST_UNKNOWN: fprintf(fd, " ???"); break; } switch (sym->getLinkage()) { case Symbol::SL_UNKNOWN: fprintf(fd, " ??"); break; case Symbol::SL_GLOBAL: fprintf(fd, " GL"); break; case Symbol::SL_LOCAL: fprintf(fd, " LO"); break; case Symbol::SL_WEAK: fprintf(fd, " WK"); break; case Symbol::SL_UNIQUE: fprintf(fd, " UQ"); break; } switch (sym->getVisibility()) { case Symbol::SV_UNKNOWN: fprintf(fd, " ???"); break; case Symbol::SV_DEFAULT: fprintf(fd, " - "); break; case Symbol::SV_INTERNAL: fprintf(fd, " INT"); break; case Symbol::SV_HIDDEN: fprintf(fd, " HID"); break; case Symbol::SV_PROTECTED: fprintf(fd, " PRO"); break; } fprintf(fd, " "); if (sym->isInSymtab()) fprintf(fd, " STA"); if (sym->isInDynSymtab()) fprintf(fd, " DYN"); if (sym->isAbsolute()) fprintf(fd, " ABS"); if (sym->isDebug()) fprintf(fd, " DBG"); std::string fileName; std::vector<std::string> *vers; if (sym->getVersionFileName(fileName)) fprintf(fd, " [%s]", fileName.c_str()); if (sym->getVersions(vers)) { fprintf(fd, " {"); for (unsigned j=0; j < vers->size(); j++) { if (j > 0) fprintf(fd, ", "); fprintf(fd, "%s", (*vers)[j].c_str()); } fprintf(fd, "}"); } fprintf(fd,"\n"); } } }
void StrPrinter::bvisit(const Symbol &x) { str_ = x.get_name(); }
String Symbol::toString(const std::shared_ptr<Project> &project, const Flags<ToStringFlag> cursorInfoFlags, Flags<Location::ToStringFlag> locationToStringFlags, const Set<String> &pieceFilters) const { auto filterPiece = [&pieceFilters](const char *name) { return pieceFilters.isEmpty() || pieceFilters.contains(name); }; auto properties = [this, &filterPiece]() -> String { List<String> ret; if (isDefinition() && filterPiece("definition")) ret << "Definition"; if (isContainer() && filterPiece("container")) ret << "Container"; if ((flags & PureVirtualMethod) == PureVirtualMethod && filterPiece("purevirtual")) ret << "Pure Virtual"; if (flags & VirtualMethod && filterPiece("virtual")) ret << "Virtual"; if (flags & ConstMethod) { if (filterPiece("constmethod")) ret << "ConstMethod"; } else if (flags & StaticMethod && filterPiece("static")) { ret << "Static"; } if (flags & Variadic && filterPiece("variadic")) ret << "Variadic"; if (flags & Auto && filterPiece("auto")) ret << "Auto"; if (flags & MacroExpansion && filterPiece("macroexpansion")) ret << "MacroExpansion"; if (flags & TemplateSpecialization && filterPiece("templatespecialization")) ret << "TemplateSpecialization"; if (flags & TemplateReference && filterPiece("templatereference")) ret << "TemplateReference"; if (ret.isEmpty()) return String(); return String::join(ret, ' ') + '\n'; }; List<String> bases; List<String> args; if (project) { if (filterPiece("baseclasses")) { for (const auto &base : baseClasses) { bool found = false; for (const auto &sym : project->findByUsr(base, location.fileId(), Project::ArgDependsOn)) { bases << sym.symbolName; found = true; break; } if (!found) { bases << base; } } } if (filterPiece("arguments")) { for (const auto &arg : arguments) { const String symName = project->findSymbol(arg.cursor).symbolName; if (!symName.isEmpty()) { args << symName; } else { args << arg.cursor.toString(locationToStringFlags & ~Location::ShowContext); } } } } else if (filterPiece("baseClasses")) { bases = baseClasses; } String ret; auto writePiece = [&ret, &filterPiece](const char *key, const char *filter, const String &piece) { if (piece.isEmpty()) return; if (!filterPiece(filter)) return; if (key && strlen(key)) ret << key << ": "; ret << piece << "\n"; }; writePiece(0, "location", location.toString(locationToStringFlags)); writePiece("SymbolName", "symbolname", symbolName); writePiece("Kind", "kind", kindSpelling()); if (filterPiece("type")) { if (!typeName.isEmpty()) { ret += "Type: " + typeName + "\n"; } else if (type != CXType_Invalid) { ret += "Type: " + RTags::eatString(clang_getTypeKindSpelling(type)) + "\n"; } } writePiece("SymbolLength", "symbollength", std::to_string(symbolLength)); if (startLine != -1) writePiece("Range", "range", String::format<32>("%d:%d-%d:%d", startLine, startColumn, endLine, endColumn)); #if CINDEX_VERSION_MINOR > 1 if (kind == CXCursor_EnumConstantDecl) writePiece("Enum Value", "enumvalue", String::format<32>("%lld/0x%0llx", static_cast<long long>(enumValue), static_cast<long long>(enumValue))); if (isDefinition() && RTags::isFunction(kind)) writePiece("Stack cost", "stackcost", std::to_string(stackCost)); #endif writePiece(0, "linkage", linkageSpelling(linkage)); ret += properties(); writePiece("Usr", "usr", usr); if (size) writePiece("sizeof", "sizeof", std::to_string(size)); if (fieldOffset >= 0) writePiece("Field offset (bits/bytes)", "fieldoffset", String::format<32>("%d/%d", fieldOffset, fieldOffset / 8)); if (alignment >= 0) writePiece("Alignment", "alignment", std::to_string(alignment)); if (!args.isEmpty()) writePiece("Arguments", "arguments", String::join(args, ", ")); if (!bases.isEmpty()) writePiece("Base classes", "baseclasses", String::join(bases, ", ")); writePiece("Brief comment", "briefcomment", briefComment); writePiece("XML comment", "xmlcomment", xmlComment); if ((cursorInfoFlags & IncludeParents && filterPiece("parent")) || (cursorInfoFlags & (IncludeContainingFunction) && filterPiece("cf")) || (cursorInfoFlags & (IncludeContainingFunctionLocation) && filterPiece("cfl"))) { auto syms = project->openSymbols(location.fileId()); uint32_t idx = -1; if (syms) { idx = syms->lowerBound(location); if (idx == std::numeric_limits<uint32_t>::max()) { idx = syms->count() - 1; } } const unsigned int line = location.line(); const unsigned int column = location.column(); while (idx-- > 0) { const Symbol s = syms->valueAt(idx); if (s.isDefinition() && s.isContainer() && comparePosition(line, column, s.startLine, s.startColumn) >= 0 && comparePosition(line, column, s.endLine, s.endColumn) <= 0) { if (cursorInfoFlags & IncludeContainingFunctionLocation) writePiece("Containing function location", "cfl", s.location.toString(locationToStringFlags)); if (cursorInfoFlags & IncludeContainingFunction) writePiece("Containing function", "cf", s.symbolName); if (cursorInfoFlags & IncludeParents) writePiece("Parent", "parent", s.location.toString(locationToStringFlags)); // redundant, this is a mess break; } } } if (cursorInfoFlags & IncludeTargets && project && filterPiece("targets")) { const auto targets = project->findTargets(*this); if (targets.size()) { ret.append("Targets:\n"); auto best = RTags::bestTarget(targets); ret.append(String::format<128>(" %s\n", best.location.toString(locationToStringFlags).constData())); for (const auto &tit : targets) { if (tit.location != best.location) ret.append(String::format<128>(" %s\n", tit.location.toString(locationToStringFlags).constData())); } } } if (cursorInfoFlags & IncludeReferences && project && !isReference() && filterPiece("references")) { const auto references = project->findCallers(*this); if (references.size()) { ret.append("References:\n"); for (const auto &r : references) { ret.append(String::format<128>(" %s\n", r.location.toString(locationToStringFlags).constData())); } } } return ret; }
void ParameterExpression::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { FunctionScopePtr func = getFunctionScope(); VariableTablePtr variables = func->getVariables(); Symbol *sym = variables->getSymbol(m_name); assert(sym && sym->isParameter()); bool inHeader = cg.isFileOrClassHeader(); cg.setFileOrClassHeader(true); CodeGenerator::Context context = cg.getContext(); bool typedWrapper = (context == CodeGenerator::CppTypedParamsWrapperImpl || context == CodeGenerator::CppTypedParamsWrapperDecl); TypePtr paramType = typedWrapper && func->getParamTypeSpec(sym->getParameterIndex()) ? Type::Variant : func->getParamType(sym->getParameterIndex()); bool wrapper = typedWrapper || context == CodeGenerator::CppFunctionWrapperImpl || context == CodeGenerator::CppFunctionWrapperDecl; bool isCVarRef = false; const char *prefix = ""; if (m_ref) { cg_printf("VRefParam"); if (!wrapper) { prefix = "r"; } } else if (wrapper || (!variables->isLvalParam(m_name) && !variables->getAttribute(VariableTable::ContainsDynamicVariable) && !variables->getAttribute(VariableTable::ContainsExtract))) { if (paramType->is(Type::KindOfVariant) || paramType->is(Type::KindOfSome)) { cg_printf("CVarRef"); isCVarRef = true; } else if (paramType->is(Type::KindOfArray)) cg_printf("CArrRef"); else if (paramType->is(Type::KindOfString)) cg_printf("CStrRef"); else paramType->outputCPPDecl(cg, ar, getScope()); } else { paramType->outputCPPDecl(cg, ar, getScope()); } cg_printf(" %s%s%s", prefix, Option::VariablePrefix, CodeGenerator::FormatLabel(m_name).c_str()); if (m_defaultValue && sym->getParameterIndex() >= func->getMinParamCount()) { bool comment = context == CodeGenerator::CppTypedParamsWrapperImpl || context == CodeGenerator::CppFunctionWrapperImpl || context == CodeGenerator::CppImplementation || (context == CodeGenerator::CppDeclaration && func->isInlined()); if (comment) { cg_printf(" // "); } cg_printf(" = "); ConstantExpressionPtr con = dynamic_pointer_cast<ConstantExpression>(m_defaultValue); bool done = false; if (con && con->isNull()) { done = true; if (isCVarRef) { cg_printf("null_variant"); } else if (paramType->is(Type::KindOfVariant) || paramType->is(Type::KindOfSome)) { cg_printf("null"); } else if (paramType->is(Type::KindOfObject)) { cg_printf("Object()"); } else if (paramType->is(Type::KindOfArray)) { cg_printf("Array()"); } else if (paramType->is(Type::KindOfString)) { cg_printf("String()"); } else { done = false; } } if (!done) { if (comment) { cg.setContext(CodeGenerator::CppParameterDefaultValueImpl); } else { cg.setContext(CodeGenerator::CppParameterDefaultValueDecl); } bool isScalar = m_defaultValue->isScalar(); if (isCVarRef && isScalar) { ASSERT(!cg.hasScalarVariant()); cg.setScalarVariant(); } m_defaultValue->outputCPP(cg, ar); if (isCVarRef && isScalar) cg.clearScalarVariant(); ASSERT(!cg.hasScalarVariant()); cg.setContext(context); } if (comment) { cg_printf("\n"); } } cg.setFileOrClassHeader(inHeader); }
/*! Handle (1) Simple declarations like in "char *s, *t, *int foo();" (2) Return types of function declarations. */ bool PointerDeclarationFormatter::visit(SimpleDeclarationAST *ast) { CHECK_RV(ast, "Invalid AST", true); printCandidate(ast); const unsigned tokenKind = tokenAt(ast->firstToken()).kind(); const bool astIsOk = tokenKind != T_CLASS && tokenKind != T_STRUCT && tokenKind != T_ENUM; CHECK_RV(astIsOk, "Nothing to do for class/struct/enum", true); DeclaratorListAST *declaratorList = ast->declarator_list; CHECK_RV(declaratorList, "No declarator list", true); DeclaratorAST *firstDeclarator = declaratorList->value; CHECK_RV(firstDeclarator, "No declarator", true); CHECK_RV(ast->symbols, "No Symbols", true); CHECK_RV(ast->symbols->value, "No Symbol", true); List<Symbol *> *sit = ast->symbols; DeclaratorListAST *dit = declaratorList; for (; sit && dit; sit = sit->next, dit = dit->next) { DeclaratorAST *declarator = dit->value; Symbol *symbol = sit->value; const bool isFirstDeclarator = declarator == firstDeclarator; // If were not handling the first declarator, we need to remove // characters from the beginning since our rewritten declaration // will contain all type specifiers. int charactersToRemove = 0; if (!isFirstDeclarator) { const int startAST = m_cppRefactoringFile->startOf(ast); const int startFirstDeclarator = m_cppRefactoringFile->startOf(firstDeclarator); CHECK_RV(startAST < startFirstDeclarator, "No specifier", true); charactersToRemove = startFirstDeclarator - startAST; } // Specify activation range int lastActivationToken = 0; TokenRange range; // (2) Handle function declaration's return type if (symbol->type()->asFunctionType()) { PostfixDeclaratorListAST *pfDeclaratorList = declarator->postfix_declarator_list; CHECK_RV(pfDeclaratorList, "No postfix declarator list", true); PostfixDeclaratorAST *pfDeclarator = pfDeclaratorList->value; CHECK_RV(pfDeclarator, "No postfix declarator", true); FunctionDeclaratorAST *functionDeclarator = pfDeclarator->asFunctionDeclarator(); CHECK_RV(functionDeclarator, "No function declarator", true); // End the activation range before the '(' token. lastActivationToken = functionDeclarator->lparen_token - 1; SpecifierListAST *specifierList = isFirstDeclarator ? ast->decl_specifier_list : declarator->attribute_list; unsigned firstActivationToken = 0; bool foundBegin = false; firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( specifierList, m_cppRefactoringFile->cppDocument()->translationUnit(), lastActivationToken, &foundBegin); if (!foundBegin) { CHECK_RV(!isFirstDeclarator, "Declaration without attributes not supported", true); firstActivationToken = declarator->firstToken(); } range.start = firstActivationToken; // (1) Handle 'normal' declarations. } else { if (isFirstDeclarator) { bool foundBegin = false; unsigned firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( ast->decl_specifier_list, m_cppRefactoringFile->cppDocument()->translationUnit(), declarator->firstToken(), &foundBegin); CHECK_RV(foundBegin, "Declaration without attributes not supported", true); range.start = firstActivationToken; } else { range.start = declarator->firstToken(); } lastActivationToken = declarator->equal_token ? declarator->equal_token - 1 : declarator->lastToken() - 1; } range.end = lastActivationToken; checkAndRewrite(declarator, symbol, range, charactersToRemove); } return true; }
bool operator==(const Symbol &lhs, const Symbol &rhs) { return lhs.GetName() == rhs.GetName(); }
void OMPTransform::for_postorder(PragmaCustomConstruct ctr) { ForStatement for_statement(ctr.get_statement().get_ast(), ctr.get_scope_link()); Statement for_body = for_statement.get_loop_body(); OpenMP::DataSharingEnvironment& data_sharing = openmp_info->get_data_sharing(ctr.get_ast()); ObjectList<OpenMP::DependencyItem> dependences; data_sharing.get_all_dependences(dependences); Source loop_info_field; loop_info_field << "nanos_loop_info_t loop_info;" ; DataEnvironInfo data_environ_info; compute_data_environment( data_sharing, ctr, data_environ_info, _converted_vlas); std::string struct_arg_type_name; define_arguments_structure(ctr, struct_arg_type_name, data_environ_info, ObjectList<OpenMP::DependencyItem>(), loop_info_field); FunctionDefinition funct_def = ctr.get_enclosing_function(); Symbol function_symbol = funct_def.get_function_symbol(); int outline_num = TL::CounterManager::get_counter(NANOX_OUTLINE_COUNTER); TL::CounterManager::get_counter(NANOX_OUTLINE_COUNTER)++; std::stringstream ss; ss << "_ol_" << function_symbol.get_name() << "_" << outline_num; std::string outline_name = ss.str(); Source loop_distr_setup; loop_distr_setup << "int _nth_lower = _args->loop_info.lower;" << "int _nth_upper = _args->loop_info.upper;" << "int _nth_step = _args->loop_info.step;" << "int _nth_step_sign = 1;" << "if (_nth_step < 0)" << "_nth_step_sign = -1;" ; Source final_barrier; if ( (!ctr.get_clause("nowait").is_defined() && !ctr.get_clause("input").is_defined() && !ctr.get_clause("output").is_defined() && !ctr.get_clause("inout").is_defined() ) || !data_environ_info.get_reduction_symbols().empty()) { final_barrier << get_barrier_code(ctr.get_ast()); } Source induction_var_name = for_statement.get_induction_variable().prettyprint(); Source device_descriptor, device_description, device_description_line, num_devices, ancillary_device_description; device_descriptor << outline_name << "_devices"; device_description << ancillary_device_description << "nanos_device_t " << device_descriptor << "[] =" << "{" << device_description_line << "};" ; OutlineFlags outline_flags; DeviceHandler &device_handler = DeviceHandler::get_device_handler(); ObjectList<std::string> current_targets; data_sharing.get_all_devices(current_targets); for (ObjectList<std::string>::iterator it = current_targets.begin(); it != current_targets.end(); it++) { DeviceProvider* device_provider = device_handler.get_device(*it); if (device_provider == NULL) { internal_error("invalid device '%s' at '%s'\n", it->c_str(), ctr.get_ast().get_locus().c_str()); } Source initial_setup, replaced_body; device_provider->do_replacements(data_environ_info, for_statement.get_loop_body().get_ast(), ctr.get_scope_link(), initial_setup, replaced_body); Source outline_body; outline_body << loop_distr_setup << "for (" << induction_var_name << "= _nth_lower;" << "(_nth_step_sign * " << induction_var_name << ")" << "<= (_nth_step_sign * _nth_upper);" << induction_var_name << "+= _nth_step" << ")" << "{" << replaced_body << "}" ; device_provider->create_outline(outline_name, struct_arg_type_name, data_environ_info, outline_flags, ctr.get_statement().get_ast(), ctr.get_scope_link(), initial_setup, outline_body); device_provider->get_device_descriptor(outline_name, data_environ_info, outline_flags, ctr.get_statement().get_ast(), ctr.get_scope_link(), ancillary_device_description, device_description_line); } num_devices << current_targets.size(); Source fill_outline_arguments, fill_dependences_outline; Source dependency_array, num_dependences; fill_data_args("ol_args", data_environ_info, dependences, /* is_pointer */ true, fill_outline_arguments); bool env_is_runtime_sized = data_environ_info.environment_is_runtime_sized(); // Fill dependences, if any if (!dependences.empty()) { num_dependences << dependences.size(); Source dependency_defs_outline; fill_dependences_outline << "nanos_dependence_t _dependences[" << num_dependences << "] = {" << dependency_defs_outline << "};" ; dependency_array << "_dependences"; int num_dep = 0; for (ObjectList<OpenMP::DependencyItem>::iterator it = dependences.begin(); it != dependences.end(); it++) { Source dependency_flags; dependency_flags << "{"; OpenMP::DependencyDirection attr = it->get_kind(); if ((attr & OpenMP::DEP_DIR_INPUT) == OpenMP::DEP_DIR_INPUT) { dependency_flags << "1,"; } else { dependency_flags << "0,"; } if ((attr & OpenMP::DEP_DIR_OUTPUT) == OpenMP::DEP_DIR_OUTPUT) { dependency_flags << "1,"; } else { dependency_flags << "0,"; } Source dependency_field_name; DataReference data_ref = it->get_dependency_expression(); Symbol sym = data_ref.get_base_symbol(); DataEnvironItem data_env_item = data_environ_info.get_data_of_symbol(sym); if (data_env_item.get_symbol().is_valid()) { dependency_field_name << data_env_item.get_field_name(); } else { internal_error("symbol without data environment info %s", it->get_dependency_expression().prettyprint().c_str()); } // Can rename in this case dependency_flags << "1" ; dependency_flags << "}" ; DataReference dependency_expression = it->get_dependency_expression(); Source dep_size; dep_size << dependency_expression.get_sizeof(); Source dependency_offset; dependency_defs_outline << "{" << "(void**)&ol_args->" << dependency_field_name << "," << dependency_offset << "," << dependency_flags << "," << dep_size << "}" ; Source dep_expr_addr = data_ref.get_address(); dependency_offset << "((char*)(" << dep_expr_addr << ") - " << "(char*)ol_args->" << dependency_field_name << ")" ; if ((it + 1) != dependences.end()) { dependency_defs_outline << ","; } num_dep++; } } else { dependency_array << "0"; num_dependences << "0"; } Source tiedness, priority; PragmaCustomClause untied_clause = ctr.get_clause("untied"); if (untied_clause.is_defined()) { tiedness << "props.tied = 0;"; } else { tiedness << "props.tied = 1;"; } PragmaCustomClause priority_clause = ctr.get_clause("__priority"); if (priority_clause.is_defined()) { priority << "props.tied = " << priority_clause.get_arguments()[0] << ";" ; } Source struct_runtime_size, struct_size; if (env_is_runtime_sized) { struct_runtime_size << "int struct_runtime_size = " << "sizeof(" << struct_arg_type_name << ") + " << "(" << data_environ_info.sizeof_variable_part(ctr.get_scope()) << ")" << ";" ; struct_size << "struct_runtime_size" ; } else { struct_size << "sizeof(" << struct_arg_type_name << ")" ; } bool some_device_needs_copies = false; Source num_copies; ObjectList<OpenMP::CopyItem> copy_items = data_environ_info.get_copy_items(); Source copy_data, copy_decl, copy_setup; if (copy_items.empty() || !some_device_needs_copies) { num_copies << "0"; copy_data << "(nanos_copy_data_t**)0"; } else { num_copies << copy_items.size(); copy_decl << "nanos_copy_data_t* copy_data = (nanos_copy_data_t*)0;"; Source copy_items_src; copy_setup << copy_items_src; copy_data << "©_data"; int i = 0; for (ObjectList<OpenMP::CopyItem>::iterator it = copy_items.begin(); it != copy_items.end(); it++) { Source copy_direction_in, copy_direction_out; if (it->get_kind() == OpenMP::COPY_DIR_IN) { copy_direction_in << 1; copy_direction_out << 0; } else if (it->get_kind() == OpenMP::COPY_DIR_OUT) { copy_direction_in << 0; copy_direction_out << 1; } else if (it->get_kind() == OpenMP::COPY_DIR_INOUT) { copy_direction_in << 1; copy_direction_out << 1; } DataReference data_ref = it->get_copy_expression(); OpenMP::DataSharingAttribute data_attr = data_sharing.get_data_sharing(data_ref.get_base_symbol()); ERROR_CONDITION(data_attr == OpenMP::DS_UNDEFINED, "Invalid data sharing for copy", 0); bool has_shared_data_sharing = (data_attr & OpenMP::DS_SHARED) == OpenMP::DS_SHARED; Source copy_sharing; if (has_shared_data_sharing) { copy_sharing << "NANOS_SHARED"; } else { copy_sharing << "NANOS_PRIVATE"; } struct { Source *source; const char* array; const char* struct_name; } fill_copy_data_info[] = { { ©_items_src, "copy_data", "ol_args->" }, { NULL, "" }, }; for (int j = 0; fill_copy_data_info[j].source != NULL; j++) { Source expression_size, expression_address; const char* array_name = fill_copy_data_info[j].array; (*(fill_copy_data_info[j].source)) << array_name << "[" << i << "].address = (uintptr_t)(" << expression_address << ");" << array_name << "[" << i << "].sharing = " << copy_sharing << ";" << array_name << "[" << i << "].flags.input = " << copy_direction_in << ";" << array_name << "[" << i << "].flags.output = " << copy_direction_out << ";" << array_name << "[" << i << "].size = " << expression_size << ";" ; DataReference copy_expr = it->get_copy_expression(); if (has_shared_data_sharing) { expression_address << copy_expr.get_address(); } else { DataEnvironItem data_env_item = data_environ_info.get_data_of_symbol(copy_expr.get_base_symbol()); // We have to use the value of the argument structure if it // is private expression_address << "&(" << fill_copy_data_info[j].struct_name << data_env_item.get_field_name() << ")" ; } expression_size << copy_expr.get_sizeof(); } i++; } } Source current_slicer; Source chunk_value; chunk_value = Source("0"); current_slicer = Source("static_for"); PragmaCustomClause schedule_clause = ctr.get_clause("schedule"); if (schedule_clause.is_defined()) { ObjectList<std::string> args = schedule_clause.get_arguments(ExpressionTokenizerTrim()); current_slicer = args[0] + "_for"; if (args.size() > 1) { chunk_value = Source(args[1]); } } // FIXME - Move this to a tl-workshare.cpp Source spawn_source; // FIXME - This will be meaningful with 'copy_in' and 'copy_out' Source num_copies1, copy_data1; num_copies1 << "0"; copy_data1 << "(nanos_copy_data_t**)0"; Source creation; if ( current_targets.contains( "cuda" ) ) { creation << "props.mandatory_creation = 1;" ; } ObjectList<OpenMP::ReductionSymbol> reduction_symbols = data_environ_info.get_reduction_symbols(); Source reduction_join_arr_decls; if (!reduction_symbols.empty()) reduction_join_arr_decls << "int _nth_team = omp_get_num_threads();" ; if (!reduction_symbols.empty()) reduction_join_arr_decls << "int rs_i;" ; for(ObjectList<OpenMP::ReductionSymbol>::iterator it = reduction_symbols.begin(); it != reduction_symbols.end(); it++) { Symbol rs = it->get_symbol(); OpenMP::UDRInfoItem2 udr2 = it->get_udr_2(); Source auxiliar_initializer; if (rs.get_type().is_class()) { // When the symbol has class type, we must build an auxiliary variable initialized to the symbol's identity // in order to initialize the reduction's vector auxiliar_initializer << "aux_" << rs.get_name(); Source identity; reduction_join_arr_decls << rs.get_type().get_declaration(rs.get_scope(), "") << " " << auxiliar_initializer << identity << ";" ; if (udr2.has_identity()) { identity << udr2.get_identity().prettyprint() << ";" ; } } else { auxiliar_initializer << udr2.get_identity().prettyprint(); } reduction_join_arr_decls << rs.get_type().get_declaration(rs.get_scope(), "") << " rdv_" << rs.get_name() << "[_nth_team];" << "for(rs_i=0; rs_i<_nth_team; rs_i++)" << "{" ; CXX_LANGUAGE() { if (udr2.has_identity()) { if (udr2.get_need_equal_initializer()) { reduction_join_arr_decls << "rdv_" << rs.get_name() << "[rs_i] = " << auxiliar_initializer << ";" ; } else { if (udr2.get_is_constructor()) { reduction_join_arr_decls << "rdv_" << rs.get_name() << "[rs_i] " << auxiliar_initializer << ";" ; } else if (!rs.get_type().is_enum()) { reduction_join_arr_decls << "rdv_" << rs.get_name() << "[rs_i] (" << auxiliar_initializer << ");" ; } } } } C_LANGUAGE() { reduction_join_arr_decls << "rdv_" << rs.get_name() << "[rs_i] = " << auxiliar_initializer << ";" ; } reduction_join_arr_decls << "}"; } Source omp_reduction_join, omp_reduction_argument; // Get reduction code for (ObjectList<std::string>::iterator it = current_targets.begin(); it != current_targets.end(); it++) { DeviceProvider* device_provider = device_handler.get_device(*it); if (device_provider->get_name()=="smp") { omp_reduction_join << device_provider->get_reduction_code(reduction_symbols, ctr.get_scope_link()) ; } } // Fill outline variables for (ObjectList<OpenMP::ReductionSymbol>::iterator it = reduction_symbols.begin(); it != reduction_symbols.end(); it++) { omp_reduction_argument << "ol_args->rdv_" << it->get_symbol().get_name() << " = rdv_" << it->get_symbol().get_name() << ";"; } Source alignment, slicer_alignment; if (Nanos::Version::interface_is_at_least("master", 5004)) { alignment << "__alignof__(" << struct_arg_type_name << ")," ; slicer_alignment << "__alignof__(nanos_slicer_data_for_t)," ; } Source create_sliced_wd, loop_information, decl_slicer_data_if_needed; if (Nanos::Version::interface_is_at_least("master", 5008)) { create_sliced_wd <<"nanos_create_sliced_wd(&wd, " << /* num_devices */ "1, " << device_descriptor << ", " << "sizeof(" << struct_arg_type_name << ")," << alignment << "(void**)&ol_args," << "nanos_current_wd()," << current_slicer << "," << "&props," << num_copies1 << "," << copy_data1 << ");" ; loop_information << "ol_args->loop_info.lower = " << for_statement.get_lower_bound() << ";" << "ol_args->loop_info.upper = " << for_statement.get_upper_bound() << ";" << "ol_args->loop_info.step = " << for_statement.get_step() << ";" << "ol_args->loop_info.chunk = " << chunk_value << ";" ; } else { create_sliced_wd << "nanos_create_sliced_wd(&wd, " << /* num_devices */ "1, " << device_descriptor << ", " << "sizeof(" << struct_arg_type_name << ")," << alignment << "(void**)&ol_args," << "nanos_current_wd()," << current_slicer << "," << "sizeof(nanos_slicer_data_for_t)," << slicer_alignment << "(nanos_slicer_t*) &slicer_data_for," << "&props," << num_copies1 << "," << copy_data1 << ");" ; decl_slicer_data_if_needed << "nanos_slicer_data_for_t* slicer_data_for = (nanos_slicer_data_for_t*)0;" ; loop_information << "slicer_data_for->_lower = " << for_statement.get_lower_bound() << ";" << "slicer_data_for->_upper = " << for_statement.get_upper_bound() << ";" << "slicer_data_for->_step = " << for_statement.get_step() << ";" << "slicer_data_for->_chunk = " << chunk_value << ";" ; } if(!_no_nanox_calls) { spawn_source << "{" << get_single_guard("single_guard") << "if (err != NANOS_OK) nanos_handle_error(err);" << reduction_join_arr_decls << "if (single_guard)" << "{" << struct_arg_type_name << "* ol_args = (" << struct_arg_type_name << "*)0;" << struct_runtime_size << "nanos_wd_t wd = (nanos_wd_t)0;" << "nanos_wd_props_t props;" << "__builtin_memset(&props, 0, sizeof(props));" << creation << "props.mandatory_creation = 1;" << priority << tiedness << copy_decl << "static nanos_slicer_t " << current_slicer << " = 0;" << device_description << "if (!" << current_slicer << ") " << current_slicer << " = nanos_find_slicer(\"" << current_slicer << "\");" << decl_slicer_data_if_needed << "err = " << create_sliced_wd << "if (err != NANOS_OK) nanos_handle_error(err);" << fill_outline_arguments << omp_reduction_argument << fill_dependences_outline << copy_setup << loop_information << "err = nanos_submit(wd, " << num_dependences << ", (nanos_dependence_t*)" << dependency_array << ", (nanos_team_t)0);" << "if (err != NANOS_OK) nanos_handle_error (err);" << "}" << final_barrier << omp_reduction_join << "}" ; } else { if(current_targets.contains("smp")) { std::stringstream smp_device_call; smp_device_call << "_smp_" << outline_name << "(ol_args);"; // The code generated must not contain calls to runtime. The execution will be serial spawn_source << "{" << struct_arg_type_name << "* ol_args = (" << struct_arg_type_name << "*)0;" << fill_outline_arguments << omp_reduction_argument << loop_information << smp_device_call.str() << "}" ; } else { running_error("%s: error: the code generation without calls to runtime only works in smp devices\n", ctr.get_ast().get_locus().c_str()); } } AST_t spawn_tree = spawn_source.parse_statement(ctr.get_ast(), ctr.get_scope_link()); ctr.get_ast().replace(spawn_tree); }
void handle(OsmWay& osmWay, XmapTree& xmapTree) { auto& tagMap = osmWay.getTagMap(); const Symbol symbol = Main::rules.groupList.getSymbol(tagMap, ElemType::way); XmapWay way = xmapTree.add(symbol.Id(), tagMap); addCoordsToWay(way,symbol,osmWay); }
void MapPainterAgg::DrawSymbol(const Projection& projection, const MapParameter& parameter, const Symbol& symbol, double x, double y) { double minX; double minY; double maxX; double maxY; double centerX; double centerY; symbol.GetBoundingBox(minX,minY,maxX,maxY); centerX=maxX-minX; centerY=maxY-minY; for (std::list<DrawPrimitiveRef>::const_iterator p=symbol.GetPrimitives().begin(); p!=symbol.GetPrimitives().end(); ++p) { DrawPrimitive* primitive=p->Get(); if (dynamic_cast<PolygonPrimitive*>(primitive)!=NULL) { PolygonPrimitive* polygon=dynamic_cast<PolygonPrimitive*>(primitive); FillStyleRef style=polygon->GetFillStyle(); agg::path_storage path; for (std::list<Coord>::const_iterator pixel=polygon->GetCoords().begin(); pixel!=polygon->GetCoords().end(); ++pixel) { if (pixel==polygon->GetCoords().begin()) { path.move_to(x+projection.ConvertWidthToPixel(pixel->x-centerX), y+projection.ConvertWidthToPixel(maxY-pixel->y-centerY)); } else { path.line_to(x+projection.ConvertWidthToPixel(pixel->x-centerX), y+projection.ConvertWidthToPixel(maxY-pixel->y-centerY)); } } path.close_polygon(); rasterizer->add_path(path); DrawFill(projection, parameter, *style, path); } else if (dynamic_cast<RectanglePrimitive*>(primitive)!=NULL) { RectanglePrimitive* rectangle=dynamic_cast<RectanglePrimitive*>(primitive); FillStyleRef style=rectangle->GetFillStyle(); agg::path_storage path; double xPos=x+projection.ConvertWidthToPixel(rectangle->GetTopLeft().x-centerX); double yPos=y+projection.ConvertWidthToPixel(maxY-rectangle->GetTopLeft().y-centerY); double width=projection.ConvertWidthToPixel(rectangle->GetWidth()); double height=projection.ConvertWidthToPixel(rectangle->GetHeight()); path.move_to(xPos,yPos); path.line_to(xPos+width,yPos); path.line_to(xPos+width,yPos+height); path.line_to(xPos,yPos+height); path.close_polygon(); rasterizer->add_path(path); DrawFill(projection, parameter, *style, path); } else if (dynamic_cast<CirclePrimitive*>(primitive)!=NULL) { CirclePrimitive* circle=dynamic_cast<CirclePrimitive*>(primitive); FillStyleRef style=circle->GetFillStyle(); agg::path_storage path; double radius=projection.ConvertWidthToPixel(circle->GetRadius()); agg::ellipse ellipse(x+projection.ConvertWidthToPixel(circle->GetCenter().x-centerX), y+projection.ConvertWidthToPixel(maxY-circle->GetCenter().y-centerY), radius, radius); path.concat_path(ellipse); rasterizer->add_path(path); DrawFill(projection, parameter, *style, path); } } }
inline void PathProbeIndex<Alloc,Symbol,MaxTermDepth,MaxTermSize>::Integrator::function(const Symbol& f) { CALL("function(const Symbol& f)"); SubtermDescriptor* subtermDesc = _subtermDescriptorPool.reserveObject(); #ifndef NO_DEBUG subtermDesc->_debugNestNumber = _debugNextNestNumber; ++_debugNextNestNumber; #endif if (!_allSubtermDescriptors) { _allSubtermDescriptors = subtermDesc; }; subtermDesc->_previous = _lastSubtermDescriptor; subtermDesc->_next = (SubtermDescriptor*)0; if (_lastSubtermDescriptor) { _lastSubtermDescriptor->_next = subtermDesc; }; subtermDesc->_topSymbol = f; bool isNonConstant = (bool)f.arity(); subtermDesc->_nest = _currentOpenNest; if (_currentOpenNest) { subtermDesc->_numberInNest = _currentOpenNest->_nextArgumentNum; ++(_currentOpenNest->_nextArgumentNum); ASSERT(_currentOpenNest->_nextArgumentNum <= _currentOpenNest->_topSymbol.arity()); if (_currentOpenNest->_nextArgumentNum < _currentOpenNest->_topSymbol.arity()) { // the nest remains open if (isNonConstant) { _openNests.push(_currentOpenNest); _currentOpenNest = subtermDesc; }; } else // the nest is closed { if (isNonConstant) { _currentOpenNest = subtermDesc; } else { _currentOpenNest = (_openNests)? _openNests.pop() : (SubtermDescriptor*)0; }; }; } else // !_currentOpenNest { subtermDesc->_numberInNest = 0UL; if (isNonConstant) { _currentOpenNest = subtermDesc; }; }; subtermDesc->_nextArgumentNum = 0UL; // temporary _lastSubtermDescriptor = subtermDesc; }; // void PathProbeIndex<..>::Integrator::function(const Symbol& f)
void BackendLLVM::llvm_assign_initial_value (const Symbol& sym) { // Don't write over connections! Connection values are written into // our layer when the earlier layer is run, as part of its code. So // we just don't need to initialize it here at all. if (sym.valuesource() == Symbol::ConnectedVal && !sym.typespec().is_closure_based()) return; if (sym.typespec().is_closure_based() && sym.symtype() == SymTypeGlobal) return; int arraylen = std::max (1, sym.typespec().arraylength()); // Closures need to get their storage before anything can be // assigned to them. Unless they are params, in which case we took // care of it in the group entry point. if (sym.typespec().is_closure_based() && sym.symtype() != SymTypeParam && sym.symtype() != SymTypeOutputParam) { llvm_assign_zero (sym); return; } if ((sym.symtype() == SymTypeLocal || sym.symtype() == SymTypeTemp) && shadingsys().debug_uninit()) { // Handle the "debug uninitialized values" case bool isarray = sym.typespec().is_array(); int alen = isarray ? sym.typespec().arraylength() : 1; llvm::Value *u = NULL; if (sym.typespec().is_closure_based()) { // skip closures } else if (sym.typespec().is_floatbased()) u = ll.constant (std::numeric_limits<float>::quiet_NaN()); else if (sym.typespec().is_int_based()) u = ll.constant (std::numeric_limits<int>::min()); else if (sym.typespec().is_string_based()) u = ll.constant (Strings::uninitialized_string); if (u) { for (int a = 0; a < alen; ++a) { llvm::Value *aval = isarray ? ll.constant(a) : NULL; for (int c = 0; c < (int)sym.typespec().aggregate(); ++c) llvm_store_value (u, sym, 0, aval, c); } } return; } if ((sym.symtype() == SymTypeLocal || sym.symtype() == SymTypeTemp) && sym.typespec().is_string_based()) { // Strings are pointers. Can't take any chance on leaving // local/tmp syms uninitialized. llvm_assign_zero (sym); return; // we're done, the parts below are just for params } ASSERT_MSG (sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam, "symtype was %d, data type was %s", (int)sym.symtype(), sym.typespec().c_str()); if (sym.has_init_ops() && sym.valuesource() == Symbol::DefaultVal) { // Handle init ops. build_llvm_code (sym.initbegin(), sym.initend()); } else if (! sym.lockgeom() && ! sym.typespec().is_closure()) { // geometrically-varying param; memcpy its default value TypeDesc t = sym.typespec().simpletype(); ll.op_memcpy (llvm_void_ptr (sym), ll.constant_ptr (sym.data()), t.size(), t.basesize() /*align*/); if (sym.has_derivs()) llvm_zero_derivs (sym); } else { // Use default value int num_components = sym.typespec().simpletype().aggregate; TypeSpec elemtype = sym.typespec().elementtype(); for (int a = 0, c = 0; a < arraylen; ++a) { llvm::Value *arrind = sym.typespec().is_array() ? ll.constant(a) : NULL; if (sym.typespec().is_closure_based()) continue; for (int i = 0; i < num_components; ++i, ++c) { // Fill in the constant val llvm::Value* init_val = 0; if (elemtype.is_floatbased()) init_val = ll.constant (((float*)sym.data())[c]); else if (elemtype.is_string()) init_val = ll.constant (((ustring*)sym.data())[c]); else if (elemtype.is_int()) init_val = ll.constant (((int*)sym.data())[c]); ASSERT (init_val); llvm_store_value (init_val, sym, 0, arrind, i); } } if (sym.has_derivs()) llvm_zero_derivs (sym); } // Handle interpolated params. // FIXME -- really, we shouldn't assign defaults or run init ops if // the values are interpolated. The perf hit is probably small, since // there are so few interpolated params, but we should come back and // fix this later. if ((sym.symtype() == SymTypeParam || sym.symtype() == SymTypeOutputParam) && ! sym.lockgeom()) { std::vector<llvm::Value*> args; args.push_back (sg_void_ptr()); args.push_back (ll.constant (sym.name())); args.push_back (ll.constant (sym.typespec().simpletype())); args.push_back (ll.constant ((int) sym.has_derivs())); args.push_back (llvm_void_ptr (sym)); ll.call_function ("osl_bind_interpolated_param", &args[0], args.size()); } }
/// Are two symbols equivalent (from the point of view of merging /// shader instances)? Note that this is not a true ==, it ignores /// the m_data, m_node, and m_alias pointers! static bool equivalent (const Symbol &a, const Symbol &b) { // If they aren't used, don't consider them a mismatch if (! a.everused() && ! b.everused()) return true; // Different symbol types or data types are a mismatch if (a.symtype() != b.symtype() || a.typespec() != b.typespec()) return false; // Don't consider different names to be a mismatch if the symbol // is a temp or constant. if (a.symtype() != SymTypeTemp && a.symtype() != SymTypeConst && a.name() != b.name()) return false; // But constants had better match their values! if (a.symtype() == SymTypeConst && memcmp (a.data(), b.data(), a.typespec().simpletype().size())) return false; return a.has_derivs() == b.has_derivs() && a.lockgeom() == b.lockgeom() && a.valuesource() == b.valuesource() && a.fieldid() == b.fieldid() && a.initbegin() == b.initbegin() && a.initend() == b.initend() ; }
void SignalThread::print_backtraces() { STATE = shared_.env()->state; ThreadList* threads = shared_.thread_nexus()->threads(); for(ThreadList::iterator i = threads->begin(); i != threads->end(); ++i) { VM* vm = (*i)->as_vm(); if(!vm) continue; bool first = true; CallFrame* frame = vm->call_frame(); while(frame) { if(first) { logger::fatal("--- %s %d backtrace ---", vm->kind_name(), vm->thread_id()); first = false; } std::ostringstream stream; if(NativeMethodFrame* nmf = frame->native_method_frame()) { stream << static_cast<void*>(frame) << ": "; NativeMethod* nm = try_as<NativeMethod>(nmf->get_object(nmf->method())); if(nm && nm->name()->symbol_p()) { stream << "capi:" << nm->name()->debug_str(state) << " at "; stream << nm->file()->c_str(state); } else { stream << "unknown capi"; } } else if(frame->compiled_code) { if(frame->is_block_p(state)) { stream << "__block__"; } else { if(SingletonClass* sc = try_as<SingletonClass>(frame->module())) { Object* obj = sc->singleton(); if(Module* mod = try_as<Module>(obj)) { stream << mod->debug_str(state) << "."; } else { if(obj == G(main)) { stream << "MAIN."; } else { stream << "#<" << obj->class_object(state)->debug_str(state) << ":" << (void*)obj->id(state)->to_native() << ">."; } } } else if(IncludedModule* im = try_as<IncludedModule>(frame->module())) { stream << im->module()->debug_str(state) << "#"; } else { Symbol* name; std::string mod_name; if(frame->module()->nil_p()) { mod_name = frame->lexical_scope()->module()->debug_str(state); } else { if((name = try_as<Symbol>(frame->module()->module_name()))) { mod_name = name->debug_str(state); } else if((name = try_as<Symbol>( frame->lexical_scope()->module()->module_name()))) { mod_name = name->debug_str(state); } else { mod_name = "<anonymous module>"; } } stream << mod_name << "#"; } Symbol* name = try_as<Symbol>(frame->name()); if(name) { stream << name->debug_str(state); } else { stream << frame->compiled_code->name()->debug_str(state); } } stream << " in "; if(Symbol* file_sym = try_as<Symbol>(frame->compiled_code->file())) { stream << file_sym->debug_str(state) << ":" << frame->line(state); } else { stream << "<unknown>"; } stream << " (+" << frame->ip(); if(frame->is_inline_frame()) { stream << " inline"; } else if(frame->jitted_p()) { stream << " jit"; } stream << ")"; } logger::fatal(stream.str().c_str()); frame = frame->previous; } } }