示例#1
0
PyType PyType::lookupType(const std::string &typeNameIn, ULONG64 module)
{
    if (debuggingTypeEnabled())
        DebugPrint() << "lookup type '" << typeNameIn << "'";
    std::string typeName = typeNameIn;
    trimBack(typeName);
    trimFront(typeName);

    if (isPointerType(typeName) || isArrayType(typeName))
        return PyType(0, 0, typeName);

    if (typeName.find("enum ") == 0)
        typeName.erase(0, 5);
    if (endsWith(typeName, " const"))
        typeName.erase(typeName.length() - 6);
    if (typeName == "__int64" || typeName == "unsigned __int64")
        typeName.erase(typeName.find("__"), 2);

    const static std::regex typeNameRE("^[a-zA-Z_][a-zA-Z0-9_]*!?[a-zA-Z0-9_<>:, \\*\\&\\[\\]]*$");
    if (!std::regex_match(typeName, typeNameRE))
        return PyType();

    CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
    ULONG typeId;
    HRESULT result = S_FALSE;
    if (module != 0 && !isIntegralType(typeName) && !isFloatType(typeName))
        result = symbols->GetTypeId(module, typeName.c_str(), &typeId);
    if (FAILED(result) || result == S_FALSE)
        result = symbols->GetSymbolTypeId(typeName.c_str(), &typeId, &module);
    if (FAILED(result))
        return createUnresolvedType(typeName);
    return PyType(module, typeId, typeName);

}
示例#2
0
std::string PyType::name(bool withModule) const
{
    if (m_name.empty()) {
        auto symbols = ExtensionCommandContext::instance()->symbols();
        ULONG size = 0;
        symbols->GetTypeName(m_module, m_typeId, NULL, 0, &size);
        if (size == 0)
            return std::string();

        std::string typeName(size - 1, '\0');
        if (FAILED(symbols->GetTypeName(m_module, m_typeId, &typeName[0], size, &size)))
            return std::string();

        m_name = typeName;
    }

    if (withModule && !isIntegralType(m_name) && !isFloatType(m_name)) {
        std::string completeName = module();
        if (!completeName.empty())
            completeName.append("!");
        completeName.append(m_name);
        return completeName;
    }

    return m_name;
}
示例#3
0
int PyType::code() const
{
    if (!m_resolved)
        return TypeCodeUnresolvable;

    if (m_tag < 0) {
        // try to parse typeName
        const std::string &typeName = name();
        if (typeName.empty())
            return TypeCodeUnresolvable;
        if (isPointerType(typeName))
            return TypeCodePointer;
        if (isArrayType(typeName))
            return TypeCodeArray;
        if (typeName.find("<function>") == 0)
            return TypeCodeFunction;
        if (isIntegralType(typeName))
            return TypeCodeIntegral;
        if (isFloatType(typeName))
            return TypeCodeFloat;

        IDebugSymbolGroup2 *sg = 0;
        if (FAILED(ExtensionCommandContext::instance()->symbols()->CreateSymbolGroup2(&sg)))
            return TypeCodeStruct;

        if (knownType(name(), 0) != KT_Unknown)
            return TypeCodeStruct;

        const std::string helperValueName = SymbolGroupValue::pointedToSymbolName(0, name(true));
        ULONG index = DEBUG_ANY_ID;
        if (SUCCEEDED(sg->AddSymbol(helperValueName.c_str(), &index)))
            m_tag = PyValue(index, sg).tag();
        sg->Release();
    }
    switch (m_tag) {
    case SymTagUDT: return TypeCodeStruct;
    case SymTagEnum: return TypeCodeEnum;
    case SymTagTypedef: return TypeCodeTypedef;
    case SymTagFunctionType: return TypeCodeFunction;
    case SymTagPointerType: return TypeCodePointer;
    case SymTagArrayType: return TypeCodeArray;
    case SymTagBaseType: return isIntegralType(name()) ? TypeCodeIntegral : TypeCodeFloat;
    default: break;
    }

    return TypeCodeStruct;
}
    void
    Type::generateHeader(std::ostream& ostr, unsigned long _indent) const
    {
      //   if(name_.isEmpty())
      //     throw QString("No class name specified.");

      unsigned long indent = _indent;

      if (!isExtern()) {
	// debug ostream operator
	if (parent_.isEmpty()) {
	  ostr << spaces.left(indent) << "struct " << name_ << "Parameters;" << std::endl
	       << spaces.left(indent) << "std::ostream&" << std::endl
	       << spaces.left(indent) << "operator << (std::ostream& ostr, const " << name_ << "Parameters& rhs);" << std::endl
	       << std::endl;
	}

	ostr << spaces.left(indent) << "class " << name_ << "Parameters";
	if (!parent_.isEmpty())
	  ostr << " : public " << parent_;

	ostr << std::endl
	     << spaces.left(indent) << "{" << std::endl;
	indent += STEP;
  
	if (!parent_.isEmpty())
	  ostr << spaces.left(indent) << "typedef " << parent_ << " Super;" << std::endl
	       << std::endl;

	ostr << spaces.left(indent - STEP) << "public: " << std::endl;

	// data members
	ParameterVector::const_iterator j;
	for (j = parameter_.begin(); j != parameter_.end(); ++j)
	  ostr << spaces.left(indent) 
	       << ((j->type_ != "angle")? j->type_ : QString("double")) 
	       << " " << j->name_ << ";" << std::endl;
	if (parameter_.size() != 0)
	  ostr << std::endl;

	// const static data members
	for (j = staticConstParameter_.begin(); j != staticConstParameter_.end(); ++j) {
	  ostr << spaces.left(indent) 
	       << "static const "
	       << ((j->type_ != "angle")? j->type_ : QString("double")) 
	       << " " << j->name_;
	  
	  if (isIntegralType(j->type_)) {
	    ostr << " = " << j->fullDefault_;
	  }

	  ostr << ";" << std::endl;
	}
	if (staticConstParameter_.size() != 0)
	  ostr << std::endl;


	// static data members
	QStringPairVector::const_iterator k;
	for (k = staticData_.begin(); k != staticData_.end(); ++k)
	  ostr << spaces.left(indent) << "static " << k->first << " " << k->second << ";" << std::endl;
	if (staticData_.size() != 0)
	  ostr << std::endl;
 
	// constructor
	ostr << spaces.left(indent) << name_ << "Parameters();" << std::endl;
	// destructor
	if (parent_.isEmpty())
	  ostr << spaces.left(indent) << "virtual ~"<< name_ << "Parameters();" << std::endl;
	// parsing operator
	ostr << std::endl;
	if (parameter_.size() > 0 || parent_.isEmpty()) {
	  ostr << spaces.left(indent) << "virtual void operator <<= (const QDomNode&);" << std::endl;
	  ostr << spaces.left(indent) << "virtual QDomElement operator >>= (QDomNode&) const;" << std::endl;
	}
	// debug output operator
	if (parameter_.size() > 0 || parent_.isEmpty()) {
	  ostr << spaces.left(indent - STEP) << "protected:" << std::endl
	       << spaces.left(indent) << "virtual void printToStream(std::ostream&) const;" << std::endl;
	}

	if (parent_.isEmpty())
	  ostr << spaces.left(indent) << "friend" << std::endl
	       << spaces.left(indent) << "std::ostream&" << std::endl
	       << spaces.left(indent) << "operator << (std::ostream& ostr, const " << name_ << "Parameters& rhs);" << std::endl;
      }
      else {
	// if this is a externally defined class, 
	// use global operators for parsing
	ostr << spaces.left(indent) << "void operator <<= (" << name_ << "&, const QDomNode&);" << std::endl;
	ostr << spaces.left(indent) << "QDomElement operator >>= (const " << name_ << "&, QDomNode&);" << std::endl;

      }

      while (indent > _indent) {
	indent -= STEP;
	ostr << spaces.left(indent) << "};" << std::endl;
      }
    }
    void
    Type::generateSource(std::ostream& ostr, unsigned long _indent) const
    {
      //   if(name_.isEmpty())
      //     throw QString("No class name specified.");

      unsigned long indent = _indent;

      if (!isExtern()) {
	QStringVector::const_iterator i;
	ParameterVector::const_iterator j;
  
	// debug ostream operator
	if (parent_.isEmpty()) {
	  ostr << spaces.left(indent) << "std::ostream&" << std::endl
	       << spaces.left(indent) << "operator << (std::ostream& ostr, const " << name_ << "Parameters& rhs)" << std::endl
	       << spaces.left(indent) << "{" << std::endl;
	  indent += STEP;
	  ostr << spaces.left(indent) << "rhs.printToStream(ostr);" << std::endl
	       << spaces.left(indent) << "return ostr;" << std::endl;
	  indent -= STEP;
	  ostr << spaces.left(indent) << "}" << std::endl
	       << std::endl;
	}
  
	// static data members
	QStringPairVector::const_iterator k;
	for (k = staticData_.begin(); k != staticData_.end(); ++k)
	  ostr << spaces.left(indent) << k->first << " " << name_ << "Parameters::" << k->second << ";" << std::endl;
	if (staticData_.size() != 0)
	  ostr << std::endl;
  
	// const static data members
	for (j = staticConstParameter_.begin(); j != staticConstParameter_.end(); ++j) {
	  ostr << spaces.left(indent) << "const "
	       << ((j->type_ != "angle")? j->type_ : QString("double")) 
	       << " " << name_ << "Parameters::" << j->name_;
	  
	  if (!isIntegralType(j->type_)) {
	    ostr << "(" << j->fullDefault_ << ")";
	  }

	  ostr << ";" << std::endl;
	}
	if (staticConstParameter_.size() != 0)
	  ostr << std::endl;

	// constructor
	ostr << spaces.left(indent) << name_ << "Parameters::" << name_ << "Parameters()";
	if (parameter_.size() > 0) {
	  ostr << " :";
	  indent += 2;
    
	  for (j = parameter_.begin(); j != parameter_.end(); ++j) {
	    if (j != parameter_.begin())
	      ostr << ",";
	    ostr << std::endl
		 << spaces.left(indent) << j->name_ << "(" << j->fullDefault_ <<")";
	  }
	  indent -= 2;
	}
	ostr << std::endl 
	     << spaces.left(indent) << "{" << std::endl;
  
	indent += STEP;
	for (i = ctor_.begin(); i != ctor_.end(); ++i)
	  ostr << spaces.left(indent) << *i << std::endl;
	indent -= STEP;
  
	ostr << spaces.left(indent) << "}" << std::endl
	     << std::endl;
  
	// destructor
	if (parent_.isEmpty()) 
	  ostr << spaces.left(indent) << name_ << "Parameters::~" << name_ << "Parameters()" << std::endl
	       << spaces.left(indent) << "{}" << std::endl
	       << std::endl;
  
	if (parameter_.size() > 0 || parent_.isEmpty()) {

	  // operator <<=
	  ostr << spaces.left(indent) << "void" << std::endl
	       << spaces.left(indent) << name_ << "Parameters::operator <<= (const QDomNode&";
	  if (parameter_.size() > 0 || !parent_.isEmpty()) 
	    ostr <<" _node";
	  ostr << ")" << std::endl;
    
	  generateQDomOutOperator(ostr, "this->", indent);
    
	  // operator >>=
	  ostr << spaces.left(indent) << "QDomElement" << std::endl
	       << spaces.left(indent) << name_ << "Parameters::operator >>= (QDomNode& _node) const" << std::endl;
	  generateQDomInOperator(ostr, "this->", indent);
    
	  // stream output
	  ostr << std::endl
	       << spaces.left(indent) << "void" << std::endl
	       << spaces.left(indent) << name_ <<"Parameters::printToStream(std::ostream&";
	  if (parameter_.size() > 0 || !parent_.isEmpty())
	    ostr << " ostr";
	  ostr << ") const" << std::endl
	       << spaces.left(indent) << "{" << std::endl;
	  indent += STEP;

	  if (!parent_.isEmpty())
	    ostr << spaces.left(indent) << "Super::printToStream(ostr);" << std::endl
		 << std::endl;

	  if (parameter_.size() > 0) {
	    ostr << spaces.left(indent) << "ostr << ";
	    indent += 5;
	    for (j = parameter_.begin(); j != parameter_.end(); ++j) {
	      if (j != parameter_.begin())
		ostr << std::endl
		     << spaces.left(indent) << "<< ";
	      if (!j->description_.isEmpty())
		ostr << "\"" << j->description_;
	      else {
		QString name(j->name_);
		name[0] = name[0].upper();
	  
		ostr << "\"" << name;
	      }
	      ostr << ": \" << ";

	      if (j->type_ != "angle")
		ostr << j->name_;
	      else
		ostr << "Miro::rad2Deg(" << j->name_ << ")" << std::endl;

	      if (!j->measure_.isEmpty())
		ostr << " << \"" << j->measure_ << "\"";
	      ostr << " << std::endl";
	    }
	    ostr << ";" << std::endl;
	    indent -= 5;
	  }
	  indent -= STEP;
	  ostr << spaces.left(indent) << "}" << std::endl;
	}
      }
      else {
	// operator <<=
	ostr << spaces.left(indent) << "void" << std::endl
	     << spaces.left(indent) << "operator<<= (" << name_ <<"& _lhs, const QDomNode& _node)" << std::endl;
    
	generateQDomOutOperator(ostr, "_lhs.", indent);
    
	// operator >>=
	ostr << spaces.left(indent) << "QDomElement" << std::endl
	     << spaces.left(indent) << "operator>>= (const " << name_ <<"& _lhs, QDomNode& _node)" << std::endl;
	generateQDomInOperator(ostr, "_lhs.", indent);
      }
    }
示例#6
0
TableIndex *TableIndexFactory::getInstance(const TableIndexScheme &scheme) {
    const TupleSchema *tupleSchema = scheme.tupleSchema;
    assert(tupleSchema);
    bool isIntsOnly = true;
    bool isInlinesOrColumnsOnly = true;
    std::vector<ValueType> keyColumnTypes;
    std::vector<int32_t> keyColumnLengths;
    size_t valueCount = 0;
    size_t exprCount = scheme.indexedExpressions.size();
    if (exprCount != 0) {
        valueCount = exprCount;
        // TODO: This is where we could gain some extra runtime and space efficiency by
        // somehow marking which indexed expressions happen to be non-inlined column expressions.
        // This case is significant because it presents an opportunity for the GenericPersistentKey
        // index keys to avoid a persistent allocation and copy of an already persistent value.
        // This could be implemented as a bool attribute of TupleSchema::ColumnInfo that is only
        // set to true in this special case. It would universally disable deep copying of that
        // particular "tuple column"'s referenced object.
        for (size_t ii = 0; ii < valueCount; ++ii) {
            ValueType exprType = scheme.indexedExpressions[ii]->getValueType();
            if ( ! isIntegralType(exprType)) {
                isIntsOnly = false;
            }
            uint32_t declaredLength;
            if (exprType == VALUE_TYPE_VARCHAR || exprType == VALUE_TYPE_VARBINARY) {
                // Setting the column length to TUPLE_SCHEMA_COLUMN_MAX_VALUE_LENGTH constrains the
                // maximum length of expression values that can be indexed with the same limit
                // that gets applied to column values.
                // In theory, indexed expression values could have an independent limit
                // up to any length that can be allocated via ThreadLocalPool.
                // Currently, all of these cases are constrained with the same limit,
                // which is also the default/maximum size for variable columns defined in schema,
                // as controlled in java by VoltType.MAX_VALUE_LENGTH.
                // It's not clear whether scheme.indexedExpressions[ii]->getValueSize()
                // can or should be called for a more useful answer.
                // There's probably little to gain since expressions usually do not contain enough information
                // to reliably determine that the result value is always small enough to "inline".
                declaredLength = TupleSchema::COLUMN_MAX_VALUE_LENGTH;
                isInlinesOrColumnsOnly = false;
            } else {
                declaredLength = NValue::getTupleStorageSize(exprType);
            }
            keyColumnTypes.push_back(exprType);
            keyColumnLengths.push_back(declaredLength);
        }
    } else {
        valueCount = scheme.columnIndices.size();
        for (size_t ii = 0; ii < valueCount; ++ii) {
            ValueType exprType = tupleSchema->columnType(scheme.columnIndices[ii]);
            if ( ! isIntegralType(exprType)) {
                isIntsOnly = false;
            }
            keyColumnTypes.push_back(exprType);
            keyColumnLengths.push_back(tupleSchema->columnLength(scheme.columnIndices[ii]));
        }
    }
    std::vector<bool> keyColumnAllowNull(valueCount, true);
    TupleSchema *keySchema = TupleSchema::createTupleSchema(keyColumnTypes, keyColumnLengths, keyColumnAllowNull, true);
    assert(keySchema);
    VOLT_TRACE("Creating index for '%s' with key schema '%s'", scheme.name.c_str(), keySchema->debug().c_str());
    TableIndexPicker picker(keySchema, isIntsOnly, isInlinesOrColumnsOnly, scheme);
    TableIndex *retval = picker.getInstance();
    return retval;
}