예제 #1
0
const IR::Node* ReplaceStructs::postorder(IR::Type_Struct* type) {
    auto canon = replacementMap->typeMap->getTypeType(getOriginal(), true);
    auto repl = replacementMap->getReplacement(canon);
    if (repl != nullptr)
        return repl->replacementType;
    return type;
}
예제 #2
0
const IR::Node* DoBindTypeVariables::postorder(IR::Expression* expression) {
    // This is needed to handle newly created expressions because
    // their children have changed.
    auto type = typeMap->getType(getOriginal(), true);
    typeMap->setType(expression, type);
    return expression;
}
예제 #3
0
const IR::Node* DoRemoveActionParameters::postorder(IR::P4Action* action) {
    LOG1("Visiting " << dbp(action));
    BUG_CHECK(getParent<IR::P4Control>() || getParent<IR::P4Program>(),
              "%1%: unexpected parent %2%", getOriginal(), getContext()->node);
    auto result = new IR::IndexedVector<IR::Declaration>();
    auto leftParams = new IR::IndexedVector<IR::Parameter>();
    auto initializers = new IR::IndexedVector<IR::StatOrDecl>();
    auto postamble = new IR::IndexedVector<IR::StatOrDecl>();
    auto invocation = invocations->get(getOriginal<IR::P4Action>());
    if (invocation == nullptr)
        return action;
    auto args = invocation->arguments;

    ParameterSubstitution substitution;
    substitution.populate(action->parameters, args);

    bool removeAll = invocations->removeAllParameters(getOriginal<IR::P4Action>());
    for (auto p : action->parameters->parameters) {
        if (p->direction == IR::Direction::None && !removeAll) {
            leftParams->push_back(p);
        } else {
            auto decl = new IR::Declaration_Variable(p->srcInfo, p->name,
                                                     p->annotations, p->type, nullptr);
            LOG3("Added declaration " << decl << " annotations " << p->annotations);
            result->push_back(decl);
            auto arg = substitution.lookup(p);
            if (arg == nullptr) {
                ::error("action %1%: parameter %2% must be bound", invocation, p);
                continue;
            }

            if (p->direction == IR::Direction::In ||
                p->direction == IR::Direction::InOut ||
                p->direction == IR::Direction::None) {
                auto left = new IR::PathExpression(p->name);
                auto assign = new IR::AssignmentStatement(arg->srcInfo, left, arg->expression);
                initializers->push_back(assign);
            }
            if (p->direction == IR::Direction::Out ||
                p->direction == IR::Direction::InOut) {
                auto right = new IR::PathExpression(p->name);
                auto assign = new IR::AssignmentStatement(arg->srcInfo, arg->expression, right);
                postamble->push_back(assign);
            }
        }
    }
    if (result->empty())
        return action;

    initializers->append(action->body->components);
    initializers->append(*postamble);

    action->parameters = new IR::ParameterList(action->parameters->srcInfo, *leftParams);
    action->body = new IR::BlockStatement(action->body->srcInfo, *initializers);
    LOG1("To replace " << dbp(action));
    result->push_back(action);
    return result;
}
예제 #4
0
const IR::Node* TypeVariableSubstitutionVisitor::replacement(IR::ITypeVar* typeVariable) {
    LOG3("Visiting " << dbp(getOriginal()));
    const IR::ITypeVar* current = getOriginal<IR::ITypeVar>();
    const IR::Type* replacement = nullptr;
    while (true) {
        // This will end because there should be no circular chain of variables pointing
        // to each other.
        const IR::Type* type = bindings->lookup(current);
        if (type == nullptr)
            break;
        replacement = type;
        if (!type->is<IR::ITypeVar>())
            break;
        current = type->to<IR::ITypeVar>();
    }
    if (replacement == nullptr)
        return typeVariable->getNode();
    LOG2("Replacing " << getOriginal() << " with " << replacement);
    return replacement;
}
예제 #5
0
const IR::Node* DoConvertEnums::postorder(IR::Type_Name* type) {
    auto canontype = typeMap->getTypeType(getOriginal(), true);
    if (!canontype->is<IR::Type_Enum>())
        return type;
    if (findContext<IR::TypeNameExpression>() != nullptr)
        // This will be resolved by the caller.
        return type;
    auto enumType = canontype->to<IR::Type_Enum>();
    auto r = ::get(repr, enumType);
    if (r == nullptr)
        return type;
    return r->type;
}
예제 #6
0
const IR::Node* DoConvertEnums::preorder(IR::Type_Enum* type) {
    bool convert = policy->convert(type);
    if (!convert)
        return type;
    unsigned long long count = type->members.size();
    unsigned long long width = policy->enumSize(count);
    LOG2("Converting enum " << type->name << " to " << "bit<" << width << ">");
    BUG_CHECK(count <= (1ULL << width),
              "%1%: not enough bits to represent %2%", width, type);
    auto r = new EnumRepresentation(type->srcInfo, width);
    auto canontype = typeMap->getTypeType(getOriginal(), true);
    BUG_CHECK(canontype->is<IR::Type_Enum>(),
              "canon type of enum %s is non enum %s?", type, canontype);
    repr.emplace(canontype->to<IR::Type_Enum>(), r);
    for (auto d : type->members)
        r->add(d->name.name);
    return nullptr;  // delete the declaration
}
예제 #7
0
const IR::Node* ReplaceStructs::postorder(IR::Member* expression) {
    // Find out if this applies to one of the parameters that are being replaced.
    const IR::Expression* e = expression;
    cstring prefix = "";
    while (auto mem = e->to<IR::Member>()) {
        e = mem->expr;
        prefix = cstring(".") + mem->member + prefix;
    }
    auto pe = e->to<IR::PathExpression>();
    if (pe == nullptr)
        return expression;
    // At this point we know that pe is an expression of the form
    // param.field1.etc.fieldN, where param has a type that needs to be replaced.
    auto decl = replacementMap->refMap->getDeclaration(pe->path, true);
    auto param = decl->to<IR::Parameter>();
    if (param == nullptr)
        return expression;
    auto repl = ::get(toReplace, param);
    if (repl == nullptr)
        return expression;
    auto newFieldName = ::get(repl->fieldNameRemap, prefix);
    const IR::Expression* result;
    if (newFieldName.isNullOrEmpty()) {
        auto type = replacementMap->typeMap->getType(getOriginal(), true);
        // This could be, for example, a method like setValid.
        if (!type->is<IR::Type_Struct>())
            return expression;
        if (getParent<IR::Member>() != nullptr)
            // We only want to process the outermost Member
            return expression;
        // Prefix is a reference to a field of the original struct whose
        // type is actually a struct itself.  We need to replace the field
        // with a struct initializer expression.  (This won't work if the
        // field is being used as a left-value.  Hopefully, all such uses
        // of a struct-valued field as a left-value have been already
        // replaced by the NestedStructs pass.)
        result = repl->explode(pe, prefix);
    } else {
        result = new IR::Member(pe, newFieldName);
    }
    LOG3("Replacing " << expression << " with " << result);
    return result;
}
예제 #8
0
const IR::Node* DoResetHeaders::postorder(IR::Declaration_Variable* decl) {
    if (findContext<IR::ParserState>() == nullptr)
        return decl;
    if (decl->initializer != nullptr)
        return decl;
    auto resets = new IR::Vector<IR::StatOrDecl>();
    resets->push_back(decl);
    BUG_CHECK(getContext()->node->is<IR::Vector<IR::StatOrDecl>>() ||
              getContext()->node->is<IR::ParserState>() ||
              getContext()->node->is<IR::BlockStatement>(),
              "%1%: parent is not Vector<StatOrDecl>, but %2%",
              decl, getContext()->node);
    auto type = typeMap->getType(getOriginal(), true);
    auto path = new IR::PathExpression(decl->getName());
    generateResets(typeMap, type, path, resets);
    if (resets->size() == 1)
        return decl;
    return resets;
}
예제 #9
0
const IR::Node* DoBindTypeVariables::postorder(IR::Declaration_Instance* decl) {
    if (decl->type->is<IR::Type_Specialized>())
        return decl;
    auto type = typeMap->getType(getOriginal(), true);
    BUG_CHECK(type->is<IR::IMayBeGenericType>(), "%1%: unexpected type %2% for declaration",
              decl, type);
    auto mt = type->to<IR::IMayBeGenericType>();
    if (mt->getTypeParameters()->empty())
        return decl;
    auto typeArgs = new IR::Vector<IR::Type>();
    for (auto p : mt->getTypeParameters()->parameters) {
        auto type = getVarValue(p, decl);
        if (type == nullptr)
            return decl;
        typeArgs->push_back(type);
    }
    decl->type = new IR::Type_Specialized(
        decl->type->srcInfo, decl->type->to<IR::Type_Name>(), typeArgs);
    return decl;
}
예제 #10
0
const IR::Node* DoBindTypeVariables::postorder(IR::ConstructorCallExpression* expression) {
    if (expression->constructedType->is<IR::Type_Specialized>())
        return expression;
    auto type = typeMap->getType(getOriginal(), true);
    BUG_CHECK(type->is<IR::IMayBeGenericType>(), "%1%: unexpected type %2% for expression",
              expression, type);
    auto mt = type->to<IR::IMayBeGenericType>();
    if (mt->getTypeParameters()->empty())
        return expression;
    auto typeArgs = new IR::Vector<IR::Type>();
    for (auto p : mt->getTypeParameters()->parameters) {
        auto type = getVarValue(p, expression);
        if (type == nullptr)
            return expression;
        typeArgs->push_back(type);
    }
    expression->constructedType = new IR::Type_Specialized(
        expression->constructedType->srcInfo,
        expression->constructedType->to<IR::Type_Name>(), typeArgs);
    return expression;
}
예제 #11
0
파일: command.cpp 프로젝트: bgotink/worker
        string &Replacement::apply(string &str) const {
            switch(getType()) {
            case REPLACE_FIRST: {
                size_t idx = str.find(getOriginal());
                if (idx == string::npos) return str;
                size_t len = getOriginal().length();

                str.replace(idx, len, getReplacement());
                return str;
            }
            case REPLACE_ALL: {
                size_t offset = 0;
                string copy = str;
                while (true) {
                    size_t idx = copy.find(getOriginal());
                    if (idx == string::npos) return str;
                    size_t len = getOriginal().length();

                    str.replace(offset + idx, len, getReplacement());

                    offset += idx + len;
                    copy = str.c_str() + offset;
                }
            }
            case REPLACE_END: {
                size_t offset = str.length() - getOriginal().length();

                if (strcmp(str.c_str() + offset, getOriginal().c_str()) != 0) {
                    return str;
                }

                str.replace(offset, getOriginal().length(), getReplacement());
                return str;
            }
            default:
                return str;
            }
        }