Index: uspace/app/sbi/src/parse.c
===================================================================
--- uspace/app/sbi/src/parse.c	(revision 39e8406404efea86e341847c0720d5d65bed7959)
+++ uspace/app/sbi/src/parse.c	(revision 4204ad9995854e56dae719be52c05abf90dee4e7)
@@ -43,4 +43,5 @@
 #include "stree.h"
 #include "strtab.h"
+#include "symbol.h"
 
 #include "parse.h"
@@ -49,10 +50,13 @@
  * Module members
  */
-static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass);
+static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
+    stree_csi_t *outer_csi);
 static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi);
 
-static stree_fun_t *parse_fun(parse_t *parse);
-static stree_var_t *parse_var(parse_t *parse);
-static stree_prop_t *parse_prop(parse_t *parse);
+static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi);
+static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi);
+static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi);
+
+static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse);
 
 static stree_proc_arg_t *parse_proc_arg(parse_t *parse);
@@ -63,5 +67,4 @@
  */
 static stree_block_t *parse_block(parse_t *parse);
-static stree_stat_t *parse_stat(parse_t *parse);
 
 static stree_vdecl_t *parse_vdecl(parse_t *parse);
@@ -89,5 +92,4 @@
 	stree_csi_t *csi;
 	stree_modm_t *modm;
-	stree_symbol_t *symbol;
 
 	while (lcur_lc(parse) != lc_eof) {
@@ -96,12 +98,7 @@
 		case lc_struct:
 		case lc_interface:
-			csi = parse_csi(parse, lcur_lc(parse));
+			csi = parse_csi(parse, lcur_lc(parse), NULL);
 			modm = stree_modm_new(mc_csi);
 			modm->u.csi = csi;
-
-			symbol = stree_symbol_new(sc_csi);
-			symbol->u.csi = csi;
-			symbol->outer_csi = NULL;
-			csi->symbol = symbol;
 
 			list_append(&parse->cur_mod->members, modm);
@@ -117,9 +114,11 @@
 
 /** Parse class, struct or interface declaration. */
-static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass)
+static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
+    stree_csi_t *outer_csi)
 {
 	stree_csi_t *csi;
 	csi_class_t cc;
 	stree_csimbr_t *csimbr;
+	stree_symbol_t *symbol;
 
 	switch (dclass) {
@@ -134,4 +133,9 @@
 	csi = stree_csi_new(cc);
 	csi->name = parse_ident(parse);
+
+	symbol = stree_symbol_new(sc_csi);
+	symbol->u.csi = csi;
+	symbol->outer_csi = outer_csi;
+	csi->symbol = symbol;
 
 #ifdef DEBUG_PARSE_TRACE
@@ -171,53 +175,26 @@
 	stree_prop_t *prop;
 
-	stree_symbol_t *symbol;
-
 	switch (lcur_lc(parse)) {
 	case lc_class:
 	case lc_struct:
 	case lc_interface:
-		csi = parse_csi(parse, lcur_lc(parse));
+		csi = parse_csi(parse, lcur_lc(parse), outer_csi);
 		csimbr = stree_csimbr_new(csimbr_csi);
 		csimbr->u.csi = csi;
-
-		symbol = stree_symbol_new(sc_csi);
-		symbol->u.csi = csi;
-		symbol->outer_csi = outer_csi;
-		csi->symbol = symbol;
 		break;
 	case lc_fun:
-		fun = parse_fun(parse);
+		fun = parse_fun(parse, outer_csi);
 		csimbr = stree_csimbr_new(csimbr_fun);
 		csimbr->u.fun = fun;
-
-		symbol = stree_symbol_new(sc_fun);
-		symbol->u.fun = fun;
-		symbol->outer_csi = outer_csi;
-		fun->symbol = symbol;
-		fun->proc->outer_symbol = symbol;
 		break;
 	case lc_var:
-		var = parse_var(parse);
+		var = parse_var(parse, outer_csi);
 		csimbr = stree_csimbr_new(csimbr_var);
 		csimbr->u.var = var;
-
-		symbol = stree_symbol_new(sc_var);
-		symbol->u.var = var;
-		symbol->outer_csi = outer_csi;
-		var->symbol = symbol;
 		break;
 	case lc_prop:
-		prop = parse_prop(parse);
+		prop = parse_prop(parse, outer_csi);
 		csimbr = stree_csimbr_new(csimbr_prop);
 		csimbr->u.prop = prop;
-
-		symbol = stree_symbol_new(sc_prop);
-		symbol->u.prop = prop;
-		symbol->outer_csi = outer_csi;
-		prop->symbol = symbol;
-		if (prop->getter)
-			prop->getter->outer_symbol = symbol;
-		if (prop->setter)
-			prop->setter->outer_symbol = symbol;
 		break;
 	default:
@@ -231,10 +208,17 @@
 
 /** Parse member function. */
-static stree_fun_t *parse_fun(parse_t *parse)
+static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi)
 {
 	stree_fun_t *fun;
 	stree_proc_arg_t *arg;
+	stree_symbol_t *symbol;
+	stree_symbol_attr_t *attr;
 
 	fun = stree_fun_new();
+	symbol = stree_symbol_new(sc_fun);
+
+	symbol->u.fun = fun;
+	symbol->outer_csi = outer_csi;
+	fun->symbol = symbol;
 
 	lmatch(parse, lc_fun);
@@ -277,8 +261,32 @@
 	}
 
-	lmatch(parse, lc_is);
+	list_init(&symbol->attr);
+
+	/* Parse attributes. */
+	while (lcur_lc(parse) == lc_comma) {
+		lskip(parse);
+		attr = parse_symbol_attr(parse);
+		list_append(&symbol->attr, attr);
+	}
+
 	fun->proc = stree_proc_new();
-	fun->proc->body = parse_block(parse);
-	lmatch(parse, lc_end);
+	fun->proc->outer_symbol = symbol;
+
+	if (lcur_lc(parse) == lc_scolon) {
+		lskip(parse);
+
+		/* This function has no body. */
+		if (!stree_symbol_has_attr(symbol, sac_builtin)) {
+			printf("Error: Function '");
+			symbol_print_fqn(symbol);
+			printf("' has no body.\n");
+			exit(1);
+		}
+		fun->proc->body = NULL;
+	} else {
+		lmatch(parse, lc_is);
+		fun->proc->body = parse_block(parse);
+		lmatch(parse, lc_end);
+	}
 
 	return fun;
@@ -286,9 +294,14 @@
 
 /** Parse member variable. */
-static stree_var_t *parse_var(parse_t *parse)
+static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi)
 {
 	stree_var_t *var;
+	stree_symbol_t *symbol;
 
 	var = stree_var_new();
+	symbol = stree_symbol_new(sc_var);
+	symbol->u.var = var;
+	symbol->outer_csi = outer_csi;
+	var->symbol = symbol;
 
 	lmatch(parse, lc_var);
@@ -302,7 +315,9 @@
 
 /** Parse member property. */
-static stree_prop_t *parse_prop(parse_t *parse)
+static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi)
 {
 	stree_prop_t *prop;
+	stree_symbol_t *symbol;
+
 	stree_ident_t *ident;
 	stree_proc_arg_t *arg;
@@ -310,4 +325,9 @@
 	prop = stree_prop_new();
 	list_init(&prop->args);
+
+	symbol = stree_symbol_new(sc_prop);
+	symbol->u.prop = prop;
+	symbol->outer_csi = outer_csi;
+	prop->symbol = symbol;
 
 	lmatch(parse, lc_prop);
@@ -363,4 +383,5 @@
 			prop->getter = stree_proc_new();
 			prop->getter->body = parse_block(parse);
+			prop->getter->outer_symbol = symbol;
 
 			lmatch(parse, lc_end);
@@ -380,4 +401,5 @@
 			prop->setter = stree_proc_new();
 			prop->setter->body = parse_block(parse);
+			prop->setter->outer_symbol = symbol;
 
 			lmatch(parse, lc_end);
@@ -393,4 +415,22 @@
 }
 
+/** Parse symbol attribute. */
+static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse)
+{
+	stree_symbol_attr_t *attr;
+
+	if (lcur_lc(parse) != lc_builtin) {
+		printf("Error: Unexpected attribute '");
+		lem_print(lcur(parse));
+		printf("'.\n");
+		exit(1);
+	}
+
+	lskip(parse);
+
+	attr = stree_symbol_attr_new(sac_builtin);
+	return attr;
+}
+
 /** Parse formal function argument. */
 static stree_proc_arg_t *parse_proc_arg(parse_t *parse)
@@ -455,5 +495,5 @@
 
 /** Parse statement. */
-static stree_stat_t *parse_stat(parse_t *parse)
+stree_stat_t *parse_stat(parse_t *parse)
 {
 	stree_stat_t *stat;
@@ -719,5 +759,5 @@
 lem_t *lcur(parse_t *parse)
 {
-	return &parse->lex->current;
+	return lex_get_current(parse->lex);
 }
 
@@ -725,5 +765,8 @@
 lclass_t lcur_lc(parse_t *parse)
 {
-	return parse->lex->current.lclass;
+	lem_t *lem;
+
+	lem = lcur(parse);
+	return lem->lclass;
 }
 
