Exemplo n.º 1
0
GLOBAL Node *ArrayType(Node *array)
{
     Node *atype;

     assert(array->typ == Array);
     assert(array->u.array.name);

     atype = NodeDataType(array->u.array.name);

     if (atype->typ == Adcl) {
	  Node *btype = atype, *item;
	  ListMarker marker;

	  /* Loop down the index operations to find the type */
	  IterateList(&marker, array->u.array.dims);
	  while (NextOnList(&marker, (GenericREF) & item))
	       if (btype->typ == Adcl)
		    btype = NodeDataType(btype->u.adcl.type);
	       else if (btype->typ == Ptr)
		    btype = NodeDataType(btype->u.ptr.type);
	       else {
		    SyntaxErrorCoord(array->coord,
				"3 cannot dereference non-pointer type");
		    return PrimVoid;
	       }

	  return btype;
     } else if (atype->typ == Ptr) {
	  Node *btype = atype, *item;
	  ListMarker marker;

	  /* Loop down the index operations to find the type */
	  IterateList(&marker, array->u.array.dims);
	  while (NextOnList(&marker, (GenericREF) & item))
	       if (btype->typ == Adcl)
		    btype = NodeDataType(btype->u.adcl.type);
	       else if (btype->typ == Ptr)
		    btype = NodeDataType(btype->u.ptr.type);
	       else {
		    SyntaxErrorCoord(array->coord,
				     "cannot dereference non-pointer type");
		    return PrimVoid;
	       }

	  return btype;
     } else {
	  fprintf(stderr, "ArrayType: Node at ");
	  PRINT_COORD(stderr, array->coord);
	  fputc('\n', stderr);
	  fPrintNode(stderr, array, 0);
	  fprintf(stderr, "\n");
	  assert(FALSE);
	  return (NULL);
     }
}
Exemplo n.º 2
0
GLOBAL Bool IsConstantZero(Node *node)
{
  Node *val = NodeGetConstantValue(node);
  Node *type;

  if (val == NULL)
    return FALSE;

  type = NodeDataType(val);
  assert(type);

  if (type->typ == Prim) {
    switch (type->u.prim.basic) {
    case Sint:   return val->u.Const.value.i == 0;
    case Uint:   return val->u.Const.value.u == 0;
    case Slong:  return val->u.Const.value.l == 0;
    case Ulong:  return val->u.Const.value.ul == 0;
    case Float:  return val->u.Const.value.f == 0;
    case Double: return val->u.Const.value.d == 0;
    default:     break;
    }
  }
  else if (type->typ == Adcl)
    return FALSE;  /* constant string, never 0 */

  /*assert(("Unexpected constant type", FALSE));*/
  assert(FALSE);
  UNREACHABLE;
  return FALSE;  /* eliminates warning */
}
Exemplo n.º 3
0
GLOBAL Bool NodeConstantBooleanValue(Node *node)
{
  Node *val = NodeGetConstantValue(node);
  Node *type = NodeDataType(val);

  assert(val);
  assert(type);

  if (type->typ == Prim) {
    switch (type->u.prim.basic) {
    case Sint:   return val->u.Const.value.i;
    case Uint:   return val->u.Const.value.u;
    case Slong:  return val->u.Const.value.l;
    case Ulong:  return val->u.Const.value.ul;
    case Float:  return val->u.Const.value.f;
    case Double: return val->u.Const.value.d;
    default: break;
    }
  }
  else if (type->typ == Adcl)
    return TRUE;  /* constant string, always true */

  /*assert(("Unexpected constant type", FALSE));*/
  assert(FALSE);
  UNREACHABLE;
  return FALSE; /* eliminates warning */
}
Exemplo n.º 4
0
GLOBAL unsigned long NodeConstantIntegralValue(Node *node)
{
  Node *val = NodeGetConstantValue(node);
  Node *type = NodeDataType(val);

  assert(val);
  assert(type);

  if (type->typ == Prim) {
    switch (type->u.prim.basic) {
    case Sint:   return val->u.Const.value.i;
    case Uint:   return val->u.Const.value.u;
    case Slong:  return val->u.Const.value.l;
    case Ulong:  return val->u.Const.value.ul;
#if 0
    case Float:  return val->u.Const.value.f;
    case Double: return val->u.Const.value.d;
#endif
    default:     break;
    }
  }
  /*assert(("Unexpected constant type", FALSE));*/
  UNREACHABLE;
  return 0;  /* eliminates warning */
}
Exemplo n.º 5
0
GLOBAL Node *SdclFindField(Node *sdcl, Node *field_name)
{
     if (sdcl->typ == Sdcl)
	  return SUE_FindField(sdcl->u.sdcl.type, field_name);
     else if (sdcl->typ == Udcl)
	  return SUE_FindField(sdcl->u.udcl.type, field_name);
     else if (sdcl->typ == Ptr) {
	  assert(sdcl->u.ptr.type);
	  return SdclFindField(NodeDataType(sdcl->u.ptr.type), field_name);
     } else if (sdcl->typ == Binop)
	  if (sdcl->u.binop.op == '.' || sdcl->u.binop.op == ARROW)
	       return (SdclFindField(sdcl->u.binop.type, field_name));
	  else {
	       printf("SdclFindField(): not a supported binop\n");
	       fPrintNode(stdout, sdcl, 0);
	       printf("\n");
	       fPrintNode(stdout, field_name, 0);
	       printf("\n");
	       assert(FALSE);
     } else {
	  printf("SdclFindField(): not a recognized type\n");
	  fPrintNode(stdout, sdcl, 0);
	  printf("\n");
	  fPrintNode(stdout, field_name, 0);
	  printf("\n");
	  assert(FALSE);
     }
     UNREACHABLE;
     return NULL;		/* eliminates warning */
}
Exemplo n.º 6
0
PRIVATE inline void PrintReturn(GBUF *out, UNUSED(Node *node), ReturnNode *u, int offset, Bool UNUSED(norecurse))
{
     gbputs("Return: ", out);
#if 0
     if (u->expr) {
	  PrintCRSpaces(out, offset + 2);
	  PrintNode(out, NodeDataType(u->expr), offset + 2);
     }
#endif
     PrintCRSpaces(out, offset + 2);
     PrintNode(out, u->expr, offset + 2);
}
Exemplo n.º 7
0
GLOBAL Node *DemoteProcArgs(Node *fdcl)
{
     Node *arg;
     ListMarker marker;

     assert(fdcl != NULL);

     IterateList(&marker, fdcl->u.fdcl.args);
     while (NextOnList(&marker, (GenericREF) & arg)) {
	  if (arg->typ == Decl) {
	       Node *decltype = NodeDataType(arg);

	       /* convert Adcl to pointer */
	       if (decltype->typ == Adcl) {
		    /* 
		     * ``If the specification of an array type
		     * includes any type qualifiers, the element type
		     * is so-qualified, not the array type. If the
		     * specification of a function type includes any
		     * type qualifiers, the behavior is
		     * undefined.'' 
		     * 
		     * (WG14/N843 6.7.3.8)
		     */

		    Node *t = decltype->u.adcl.type;

		    /* the type qualifiers of the specification */
		    TypeQual tq = NodeTq(NodeDataTypeSuperior(arg));
		    
		    if (tq_has_anything(tq)) {
			 t = NodeCopy(t, NodeOnly);
			 /* add qualifiers to the element type */
			 NodeUpdateTq2(t, tq_union, tq);
		    }
		    /* the pointer type is never qualified, hence EMPTY_TQ */
		    arg->u.decl.type = 
			 MakePtrCoord(EMPTY_TQ, t, decltype->coord);
	       }
	  }
     }
Exemplo n.º 8
0
GLOBAL void ConstFoldCast(Node *node)
{
  Node *expr;
  Node *from_type, *to_type;
  BasicType from_basic, to_basic;

  /* this function works on both casts and implicitcasts */
  switch (node->typ) {
  case Cast:
    expr = node->u.cast.expr;
    break;
  case ImplicitCast:
    expr = node->u.implicitcast.expr;
    if (expr == NULL)
      return;
    break;
  default:
    UNREACHABLE;
  }

  if (!NodeIsConstant(expr))
    return;

  to_type = NodeDataType(node);
  from_type = NodeDataType(expr);


  /* can only constant-fold scalar expressions (integral, floating,
     and pointer) */

  if (IsScalarType(to_type) && IsScalarType(from_type)) {
    from_basic = BasicTypeOfConstantValue(from_type);
    to_basic = BasicTypeOfConstantValue(to_type);

    switch (to_basic) {
    case Slonglong:
    case Ulonglong:
    case Longdouble:
      /* fix: cannot represent these types internally, so no constant-folding
	 occurs. */
      return;
    default:
      break;
    }

    switch (from_basic) {
    case Sint:
      { int eval = NodeConstantSintValue(expr);
	switch (to_basic) {
	case Sint:
	  NodeSetSintValue(node, eval);   return;
	case Uint:
	  NodeSetUintValue(node, eval);   return;
	case Slong:
	  NodeSetSlongValue(node, eval);  return;
	case Ulong:
	  NodeSetUlongValue(node, eval);  return;
	case Float:
	  NodeSetFloatValue(node, eval);  return;
	case Double:
	  NodeSetDoubleValue(node, eval); return;
	default:
	  UNREACHABLE;
	}
      }
    case Uint:
      { unsigned eval = NodeConstantUintValue(expr);
	switch (to_basic) {
	case Sint:
	  NodeSetSintValue(node, eval);   return;
	case Uint:
	  NodeSetUintValue(node, eval);   return;
	case Slong:
	  NodeSetSlongValue(node, eval);  return;
	case Ulong:
	  NodeSetUlongValue(node, eval);  return;
	case Float:
	  NodeSetFloatValue(node, eval);  return;
	case Double:
	  NodeSetDoubleValue(node, eval); return;
	default:
	  UNREACHABLE;
	}
      }
    case Slong:
      { long eval = NodeConstantSlongValue(expr);
	switch (to_basic) {
	case Sint:
	  NodeSetSintValue(node, eval);   return;
	case Uint:
	  NodeSetUintValue(node, eval);   return;
	case Slong:
	  NodeSetSlongValue(node, eval);  return;
	case Ulong:
	  NodeSetUlongValue(node, eval);  return;
	case Float:
	  NodeSetFloatValue(node, eval);  return;
	case Double:
	  NodeSetDoubleValue(node, eval); return;
	default:
	  UNREACHABLE;
	}
      }
    case Ulong:
      { unsigned long eval = NodeConstantUlongValue(expr);
	switch (to_basic) {
	case Sint:
	  NodeSetSintValue(node, eval);   return;
	case Uint:
	  NodeSetUintValue(node, eval);   return;
	case Slong:
	  NodeSetSlongValue(node, eval);  return;
	case Ulong:
	  NodeSetUlongValue(node, eval);  return;
	case Float:
	  NodeSetFloatValue(node, eval);  return;
	case Double:
	  NodeSetDoubleValue(node, eval); return;
	default:
	  UNREACHABLE;
	}
      }
    case Float:
      { float eval = NodeConstantFloatValue(expr);
	switch (to_basic) {
	case Sint:
	  NodeSetSintValue(node, eval);   return;
	case Uint:
	  NodeSetUintValue(node, eval);   return;
	case Slong:
	  NodeSetSlongValue(node, eval);  return;
	case Ulong:
	  NodeSetUlongValue(node, eval);  return;
	case Float:
	  NodeSetFloatValue(node, eval);  return;
	case Double:
	  NodeSetDoubleValue(node, eval); return;
	default:
	  UNREACHABLE;
	}
      }
    case Double:
      { double eval = NodeConstantDoubleValue(expr);
	switch (to_basic) {
	case Sint:
	  NodeSetSintValue(node, eval);   return;
	case Uint:
	  NodeSetUintValue(node, eval);   return;
	case Slong:
	  NodeSetSlongValue(node, eval);  return;
	case Ulong:
	  NodeSetUlongValue(node, eval);  return;
	case Float:
	  NodeSetFloatValue(node, eval);  return;
	case Double:
	  NodeSetDoubleValue(node, eval); return;
	default:
	  UNREACHABLE;
	}
      }
    default:
      UNREACHABLE;
    }
  }
}
Exemplo n.º 9
0
/* Must mutate original if changes required for consistency */
GLOBAL void FunctionConflict(Node *orig, Node *create)
{
     Node *ofdcl, *nfdcl;

     assert(orig);
     assert(create);
     assert(orig->typ == Decl);
     assert(create->typ == Decl);

     ofdcl = NodeDataType(orig);
     nfdcl = NodeDataType(create);

     if (ofdcl->typ != Fdcl || nfdcl->typ != Fdcl)
	  goto Mismatch;


     /* 
      * Check if one declaration is T_PROCEDURE and the other is not.
      * BUG: I think the whole way we treat 'cilk' and 'inlet' keywords
      * is broken.  We treat 'cilk' like 'const', but 
      *
      *  const int foo()
      *
      * is not the same as
      *
      *  cilk int foo()
      *
      * The former returns a 'const int', but the latter does not return a
      * 'cilk int' !  - athena
      *
      * BTW, the following line is a hack :-)
      *   ((ofdcl->u.fdcl.tq ^ nfdcl->u.fdcl.tq) & (T_PROCEDURE | T_INLET))
      * Bradley rewrote it has follows:
      */
     if ((tq_has_procedure(ofdcl->u.fdcl.tq) != tq_has_procedure(nfdcl->u.fdcl.tq))
	 || (tq_has_inlet(ofdcl->u.fdcl.tq) != tq_has_inlet(nfdcl->u.fdcl.tq)))
	  goto Mismatch;

     /* The Result Type must be equal */
     if (!TypeEqual(ofdcl->u.fdcl.returns, nfdcl->u.fdcl.returns))
	  goto Mismatch;

     /* Inspect the parameter lists */
     {
	  List *optr = ofdcl->u.fdcl.args, *nptr = nfdcl->u.fdcl.args;

	  /* Are both definitions in prototype form? */
	  if (optr && nptr) {

	       /* Then every parameter must be compatible */
	       for (; optr && nptr; optr = Rest(optr), nptr = Rest(nptr)) {
		    Node *oitem = FirstItem(optr), *otype = NodeDataType(oitem),
		    *nitem = FirstItem(nptr), *ntype = NodeDataType(nitem);

		    if (!TypeEqualFormals(otype, ntype)) {
			 SetItem(optr, nitem);
			 goto Mismatch;
		    }

	       }

	       /* And the parameter lists must be of the same length */
	       if (optr || nptr)
		    goto Mismatch;
	  }
	  /* Check for <Type> f(void)  vs  <Type> f() */
	  else if (IsVoidArglist(optr));

	  /* Check for <Type> f()  vs  <Type> f(void) */
	  else if (IsVoidArglist(nptr))
	       ofdcl->u.fdcl.args = MakeNewList(PrimVoid);

	  /* Else the provided types must be the "usual unary conversions" */
	  else {

	       /* Either this loop will run */
	       for (; optr; optr = Rest(optr)) {
		    Node *oitem = FirstItem(optr), *otype = NodeDataType(oitem);
		    if (!TypeEqual(otype, UsualUnaryConversionType(otype)) ||
			IsEllipsis(otype))
			 goto Mismatch;
	       }

	       /* Or this one will */
	       for (; nptr; nptr = Rest(nptr)) {
		    Node *nitem = FirstItem(nptr), *ntype = NodeDataType(nitem);
		    if (!TypeEqual(ntype, UsualUnaryConversionType(ntype)) ||
			IsEllipsis(ntype))
			 goto Mismatch;
	       }
	  }
     }

     return;

   Mismatch:
     SyntaxErrorCoord(create->coord,
		      "identifier `%s' redeclared", VAR_NAME(orig));
     fprintf(stderr, "\tPrevious declaration: ");
     PRINT_COORD(stderr, orig->coord);
     fputc('\n', stderr);
     return;
}
Exemplo n.º 10
0
/* DEAD CODE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
GLOBAL Bool IsCompatibleFdcls(Node *node1, Node *node2)
{
     assert(node1->typ == Fdcl);
     assert(node2->typ == Fdcl);

#if 0
     printf("IsCompatibleFdcls\n");
     PrintNode(stdout, node1, 0);
     printf("\n");
     PrintNode(stdout, node2, 0);
     printf("\n");
#endif

     /* The Result Type must be equal */
     if (!TypeEqual(node1->u.fdcl.returns, node2->u.fdcl.returns))
	  return FALSE;

     /* Inspect the parameter lists */
     {
	  List *optr = node1->u.fdcl.args, *nptr = node2->u.fdcl.args;

	  /* Are both definitions in prototype form? */
	  if (optr && nptr) {

	       /* Then every parameter must be compatible */
	       for (; optr && nptr; optr = Rest(optr), nptr = Rest(nptr)) {
		    Node *oitem = FirstItem(optr), *otype = NodeDataType(oitem),
		    *nitem = FirstItem(nptr), *ntype = NodeDataType(nitem);

		    if (!TypeEqual(otype, ntype)) {
#if 0
			 PrintNode(stdout, otype, 0);
			 printf("\n");
			 PrintNode(stdout, ntype, 0);
			 printf("\n");
#endif
			 return FALSE;
		    }
	       }

	       /* And the parameter lists must be of the same length */
	       if (optr || nptr)
		    return FALSE;
	       else
		    return TRUE;
	  }
	  /* Check for <Type> f(void)  vs  <Type> f() */
	  else if (IsVoidArglist(optr))
	       return TRUE;

	  /* Check for <Type> f()  vs  <Type> f(void) */
	  else if (IsVoidArglist(nptr))
	       return TRUE;

	  /* Else the provided types must be the "usual unary conversions" */
	  else {

	       /* Either this loop will run */
	       for (; optr; optr = Rest(optr)) {
		    Node *oitem = FirstItem(optr), *otype = NodeDataType(oitem);

		    if (!TypeEqual(otype, UsualUnaryConversionType(otype)) ||
			IsEllipsis(otype))
			 return FALSE;
	       }

	       /* Or this one will */
	       for (; nptr; nptr = Rest(nptr)) {
		    Node *nitem = FirstItem(nptr), *ntype = NodeDataType(nitem);

		    if (!TypeEqual(ntype, UsualUnaryConversionType(ntype)) ||
			IsEllipsis(ntype))
			 return FALSE;
	       }

	       return TRUE;
	  }
     }
}
Exemplo n.º 11
0
Bool EqualImplicitCast(implicitcastNode *u1, implicitcastNode *u2) {
  return (NodeDataType(u1->type) == NodeDataType(u2->type));
}