Example #1
0
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;
}
Example #2
0
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);
    }
}
Example #3
0
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;
  }
}
Example #4
0
  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);
    }
  }
Example #5
0
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();
    }
Example #10
0
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);
    }
}
Example #11
0
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;
}
Example #12
0
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;
  }
}
Example #14
0
Symbol* Symbol::create(VM& vm)
{
    Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm);
    symbol->finishCreation(vm);
    return symbol;
}
Example #15
0
 bool operator==(const std::string &lhs, const Symbol &rhs)
 {
   return rhs.GetName() == lhs;
 }
Example #16
0
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;
}
Example #17
0
/**
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();
}
Example #18
0
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");
        }
    }
}
Example #19
0
void StrPrinter::bvisit(const Symbol &x) {
    str_ = x.get_name();
}
Example #20
0
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;
}
Example #23
0
 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 << "&copy_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[] = {
                { &copy_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);
}
Example #25
0
 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);
      }
    }
  }
Example #27
0
  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()
        ;
}
Example #30
0
  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;
      }
    }
  }