Logo Search packages:      
Sourcecode: fauhdlc version File versions

intermediate::OpCode * ast::GenCode::setArg ( Callable c,
ValDeclaration vd,
AssociationElement element,
const char *  foreign 
) [private]

push an argument of a function call on the stack.

Parameters:
c Callable in question.
vd corresponding declaration of the formal.
arg argument
foreign desired foreign annotation or NULL if not foreign
Returns:
intermediate opcode to copy back the actual to the formal (or NULL if not applicable).

Definition at line 1939 of file GenCode.cpp.

References ast::AssociationElement::actual, assignExpression, ast::Expression::baseType, container, destRegs, ast::Callable::drivers, ast::AssociationElement::formal, ast::SymbolDeclaration::getICName(), isTarget, ast::ValDeclaration::mode, ast::ValDeclaration::MODE_IN, ast::ValDeclaration::MODE_INOUT, ast::ValDeclaration::MODE_OUT, ast::SymbolDeclaration::name, ast::ValDeclaration::OBJ_CLASS_CONSTANT, ast::ValDeclaration::OBJ_CLASS_SIGNAL, ast::ValDeclaration::OBJ_CLASS_VARIABLE, setArgByDriver(), setArgByPointer(), setArgByValue(), sourceRegs, and ast::ValDeclaration::storageClass.

Referenced by setArgList().

{
      //FIXME individiual association?
      // imo this *should* have been cleared somewhere else. (but is not)
      
      assert(element.formal == NULL);
      assert(element.actual != NULL);
      assert(! this->isTarget);
      assert(! this->assignExpression);
      
      Reference *callee = NULL;
      if (foreign != NULL) {
            callee = new Reference(*c.name);
      } else {
            callee = new Reference(c.getICName());
      }
      OpCode *op = NULL;

      this->sourceRegs = RegisterSet(*this->container);
      this->destRegs = RegisterSet(*this->container);

      switch (vd.storageClass) {
      case ValDeclaration::OBJ_CLASS_CONSTANT:
            switch (element.actual->baseType) {
            case BASE_TYPE_INTEGER:
            case BASE_TYPE_ENUM:
            case BASE_TYPE_REAL:
                  this->setArgByValue(callee, &vd, element, foreign, 
                              false);
                  break;

            case BASE_TYPE_RECORD:
            case BASE_TYPE_ARRAY:
                  this->setArgByBasePointerToTemporary(
                                          callee, 
                                          vd, 
                                          element,
                                          foreign);
                  break;

            default:
                  // must not happen
                  assert(false);
            }
            break;

      case ValDeclaration::OBJ_CLASS_VARIABLE:
            switch (element.actual->baseType) {
            case BASE_TYPE_INTEGER:
            case BASE_TYPE_ENUM:
            case BASE_TYPE_REAL:
                  switch (vd.mode) {
                  case ValDeclaration::MODE_IN:
                        op = this->setArgByValue(
                                          callee, 
                                          &vd, 
                                          element, 
                                          foreign,
                                          false); 
                        assert(op == NULL);
                        break;

                  case ValDeclaration::MODE_INOUT:
                  case ValDeclaration::MODE_OUT:
                        // need to copy back to op.
                        op = this->setArgByValue(
                                          callee,
                                          &vd, 
                                          element,
                                          foreign,
                                          true);
                        assert(op != NULL);
                        break;
                  }

                  break;

            case BASE_TYPE_RECORD:
            case BASE_TYPE_ARRAY:
                  this->setArgByBasePointer(
                                    callee,
                                    &vd,
                                    element,
                                    foreign);
                  break;

            default:
                  // must not happen
                  assert(false);
            }
            break;

      case ValDeclaration::OBJ_CLASS_SIGNAL:
            switch (element.actual->baseType) {
            case BASE_TYPE_ARRAY:
            case BASE_TYPE_RECORD:
                  switch (vd.mode) {
                  case ValDeclaration::MODE_IN:
                        this->setArgByBasePointer(
                                    callee,
                                    &vd,
                                    element,
                                    foreign);
                        break;

                  case ValDeclaration::MODE_INOUT:
                        this->setArgByBasePointer(
                                    callee,
                                    &vd,
                                    element,
                                    foreign);
                        /* fall through */

                  case ValDeclaration::MODE_OUT:
                        this->setArgByDriver(
                                    callee,
                                    c.drivers,
                                    vd,
                                    element,
                                    foreign,
                                    true);
                        break;
                  }
                  break;

            case BASE_TYPE_INTEGER:
            case BASE_TYPE_ENUM:
            case BASE_TYPE_REAL:
                  switch (vd.mode) {
                  case ValDeclaration::MODE_IN:
                        this->setArgByPointer(
                                    callee,
                                    &vd,
                                    element,
                                    foreign);
                        break;

                  case ValDeclaration::MODE_INOUT:
                        this->setArgByPointer(
                                    callee,
                                    &vd,
                                    element,
                                    foreign);
                        /* fall through */

                  case ValDeclaration::MODE_OUT:
                        this->setArgByDriver(
                                    callee,
                                    c.drivers,
                                    vd,
                                    element,
                                    foreign,
                                    false);
                        break;
                  }
                  break;

            default:
                  assert(0);
            }
            break;

      default:
            // must not happen
            assert(false);
      }

      this->sourceRegs = RegisterSet(*this->container);
      this->destRegs = RegisterSet(*this->container);
      return op;
}


Generated by  Doxygen 1.6.0   Back to index