// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <u.h>
#include <libc.h>
#include "go.h"

/*
 * look for
 *	unsafe.Sizeof
 *	unsafe.Offsetof
 *	unsafe.Alignof
 * rewrite with a constant
 */
Node*
unsafenmagic(Node *nn)
{
	Node *r, *n, *base, *r1;
	Sym *s;
	Type *t, *tr;
	vlong v;
	Val val;
	Node *fn;
	NodeList *args;

	fn = nn->left;
	args = nn->list;

	if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
		goto no;
	if(s->pkg != unsafepkg)
		goto no;

	if(args == nil) {
		yyerror("missing argument for %S", s);
		goto no;
	}
	r = args->n;

	if(strcmp(s->name, "Sizeof") == 0) {
		typecheck(&r, Erv);
		defaultlit(&r, T);
		tr = r->type;
		if(tr == T)
			goto bad;
		dowidth(tr);
		v = tr->width;
		goto yes;
	}
	if(strcmp(s->name, "Offsetof") == 0) {
		// must be a selector.
		if(r->op != OXDOT)
			goto bad;
		// Remember base of selector to find it back after dot insertion.
		// Since r->left may be mutated by typechecking, check it explicitly
		// first to track it correctly.
		typecheck(&r->left, Erv);
		base = r->left;
		typecheck(&r, Erv);
		switch(r->op) {
		case ODOT:
		case ODOTPTR:
			break;
		case OCALLPART:
			yyerror("invalid expression %N: argument is a method value", nn);
			v = 0;
			goto ret;
		default:
			goto bad;
		}
		v = 0;
		// add offsets for inserted dots.
		for(r1=r; r1->left!=base; r1=r1->left) {
			switch(r1->op) {
			case ODOT:
				v += r1->xoffset;
				break;
			case ODOTPTR:
				yyerror("invalid expression %N: selector implies indirection of embedded %N", nn, r1->left);
				goto ret;
			default:
				dump("unsafenmagic", r);
				fatal("impossible %#O node after dot insertion", r1->op);
				goto bad;
			}
		}
		v += r1->xoffset;
		goto yes;
	}
	if(strcmp(s->name, "Alignof") == 0) {
		typecheck(&r, Erv);
		defaultlit(&r, T);
		tr = r->type;
		if(tr == T)
			goto bad;

		// make struct { byte; T; }
		t = typ(TSTRUCT);
		t->type = typ(TFIELD);
		t->type->type = types[TUINT8];
		t->type->down = typ(TFIELD);
		t->type->down->type = tr;
		// compute struct widths
		dowidth(t);

		// the offset of T is its required alignment
		v = t->type->down->width;
		goto yes;
	}

no:
	return N;

bad:
	yyerror("invalid expression %N", nn);
	v = 0;
	goto ret;

yes:
	if(args->next != nil)
		yyerror("extra arguments for %S", s);
ret:
	// any side effects disappear; ignore init
	val.ctype = CTINT;
	val.u.xval = mal(sizeof(*n->val.u.xval));
	mpmovecfix(val.u.xval, v);
	n = nod(OLITERAL, N, N);
	n->orig = nn;
	n->val = val;
	n->type = types[TUINTPTR];
	nn->type = types[TUINTPTR];
	return n;
}

int
isunsafebuiltin(Node *n)
{
	if(n == N || n->op != ONAME || n->sym == S || n->sym->pkg != unsafepkg)
		return 0;
	if(strcmp(n->sym->name, "Sizeof") == 0)
		return 1;
	if(strcmp(n->sym->name, "Offsetof") == 0)
		return 1;
	if(strcmp(n->sym->name, "Alignof") == 0)
		return 1;
	return 0;
}
