A dynamic tracer for Linux

func.c 1.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #include <errno.h>
  2. #include "func.h"
  3. #include "node.h"
  4. #include "sym.h"
  5. #include "type.h"
  6. int func_validate_expr(const struct func *func, struct node *n, int strict)
  7. {
  8. struct tfield *f;
  9. struct node *arg;
  10. int nargs = 0;
  11. for (f = func->type->func.args, arg = n->expr.args;
  12. f && arg; f++, arg = arg->next, nargs++) {
  13. if ((!strict && (arg->sym->type->ttype == T_VOID))
  14. || (f->type->ttype == T_VOID)
  15. || type_compatible(arg->sym->type, f->type) )
  16. continue;
  17. node_error(n, stderr, "type mismatch for argument %d, expected %T, got %T",
  18. nargs, f->type, arg->sym->type);
  19. }
  20. return 0;
  21. }
  22. int func_static_validate(const struct func *func, struct node *n)
  23. {
  24. if ((n->ntype == N_NUM) || (n->ntype == N_STRING)) {
  25. }
  26. switch (n->ntype) {
  27. case N_EXPR:
  28. if (func->type->ttype != T_FUNC) {
  29. node_error(n, stderr, "'%s' is not callable",
  30. n->expr.func);
  31. return -EINVAL;
  32. }
  33. return func_validate_expr(func, n, 0);
  34. case N_IDENT:
  35. if (func->type->ttype == T_FUNC) {
  36. node_error(n, stderr, "'%s' is a function",
  37. n->ident.name);
  38. return -EINVAL;
  39. }
  40. /* fall-through */
  41. case N_NUM:
  42. case N_STRING:
  43. /* ident, num, str. nothing to validate. just copy
  44. * type info to the symbol if statically known */
  45. n->sym->type = func->type;
  46. break;
  47. }
  48. return 0;
  49. }