diff --git a/src/language.yacc b/src/language.yacc
index a802f9a4daa7f3f0ec8354c286258e1b2ba134fc..ef124c23ba096e67eb6d1a052d182a5b605730af 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -110,7 +110,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.208 2000/08/18 22:05:40 grubba Exp $");
+RCSID("$Id: language.yacc,v 1.209 2000/08/30 21:58:15 grubba Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -711,7 +711,8 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 			check_node_hash($<n>$)->u.sval.u.string,
 			$1 & (~ID_EXTERN),
 			IDENTIFIER_PIKE_FUNCTION,
-			0);
+			0,
+			OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);
 
       if ($1 & ID_VARIANT) {
 	fprintf(stderr, "Function number: %d\n",
@@ -728,6 +729,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
       node *check_args = NULL;
       int save_line = lex.current_line;
       int num_required_args = 0;
+      struct identifier *i;
 #ifdef PIKE_DEBUG
       struct pike_string *save_file = lex.current_file;
       lex.current_file = $8->current_file;
@@ -785,7 +787,6 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
       }
 
       if ($1 & ID_VARIANT) {
-	int i = isidentifier($4->u.sval.u.string);
 	struct pike_string *bad_arg_str;
 	MAKE_CONSTANT_SHARED_STRING(bad_arg_str,
 				    "Bad number of arguments!\n");
@@ -820,6 +821,9 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 		  check_node_hash($<n>9)->u.sval.u.string,
 		  $1);
 
+      i = ID_FROM_INT(Pike_compiler->new_program, f);
+      i->opt_flags = Pike_compiler->compiler_frame->opt_flags;
+
       if ($1 & ID_VARIANT) {
 	fprintf(stderr, "Function number: %d\n", f);
       }
@@ -1729,7 +1733,8 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args
 		       type,
 		       0,
 		       IDENTIFIER_PIKE_FUNCTION,
-		       0);
+		       0,
+		       OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
     n=0;
 #if 0
     if(Pike_compiler->compiler_pass > 1 &&
@@ -1757,6 +1762,8 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args
 	      i->type,
 	      ID_STATIC | ID_PRIVATE | ID_INLINE);
 
+    i->opt_flags = Pike_compiler->compiler_frame->opt_flags;
+
     pop_compiler_frame();
     free_node($1);
 
@@ -1848,7 +1855,8 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args
 		       type,
 		       0,
 		       IDENTIFIER_PIKE_FUNCTION,
-		       0);
+		       0,
+		       OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
     n=0;
 #if 0
     if(Pike_compiler->compiler_pass > 1 &&
@@ -1877,6 +1885,8 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args
 	      i->type,
 	      ID_STATIC | ID_PRIVATE | ID_INLINE);
 
+    i->opt_flags = Pike_compiler->compiler_frame->opt_flags;
+
     pop_compiler_frame();
     free_node($2);
 
@@ -1983,7 +1993,8 @@ optional_create_arguments: /* empty */ { $$ = 0; }
 
     Pike_compiler->compiler_frame->current_function_number=
       define_function(create_string, type,
-		      ID_STATIC, IDENTIFIER_PIKE_FUNCTION, 0);
+		      ID_STATIC, IDENTIFIER_PIKE_FUNCTION, 0,
+		      OPT_SIDE_EFFECT);
 
     /* Third: Generate the initialization code.
      *
diff --git a/src/las.c b/src/las.c
index 8825a221717a6998493fb52224f8601256e6992c..14a0f12f921f8b9bdffa84431c0bc9cefca6e980 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.198 2000/08/28 10:29:47 grubba Exp $");
+RCSID("$Id: las.c,v 1.199 2000/08/30 21:58:16 grubba Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -617,16 +617,59 @@ node *debug_mknode(short token, node *a, node *b)
     break;
 
   case F_APPLY:
-    if(a && a->token == F_CONSTANT &&
-       a->u.sval.type == T_FUNCTION &&
-       a->u.sval.subtype == FUNCTION_BUILTIN)
     {
-      res->node_info |= a->u.sval.u.efun->flags;
-    }else{
-      res->node_info |= OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; /* for now */
-      if(a) res->tree_info |= a->tree_info;
+      unsigned INT16 opt_flags = OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND;
+      struct identifier *i = NULL;
+
+      if (a) {
+	switch(a->token) {
+	case F_CONSTANT:
+	  if (a->u.sval.type == T_FUNCTION) {
+	    if (a->u.sval.subtype == FUNCTION_BUILTIN) {
+	      opt_flags = a->u.sval.u.efun->flags;
+	    } else if (a->u.sval.u.object->prog) {
+	      i = ID_FROM_INT(a->u.sval.u.object->prog, a->u.sval.subtype);
+	    } else {
+	      yyerror("Calling function in destructed module.");
+	    }
+	  }
+	  break;
+	case F_EXTERNAL:
+	  {
+	    struct program_state *state = Pike_compiler;
+	    int program_id = a->u.integer.a;
+	    while (state && (state->new_program->id != program_id)) {
+	      state = state->previous;
+	    }
+	    if (state) {
+	      i = ID_FROM_INT(state->new_program, a->u.integer.b);
+	    } else {
+	      yyerror("Parent has left.");
+	    }
+	  }
+	  break;
+	case F_LOCAL:
+	  /* FIXME: Should lookup functions in the local scope. */
+	default:
+	  res->tree_info |= a->tree_info;
+	}
+	if (i && IDENTIFIER_IS_FUNCTION(i->identifier_flags)) {
+#ifdef PIKE_DEBUG
+	  /* Temporary check to see that the flags aren't reset somewhere. */
+	  if (i->opt_flags != (OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND)) {
+	    my_yyerror("Identifier %s has opt_flags 0x%04x!",
+		       i->name->str, i->opt_flags);
+	  }
+#endif /* PIKE_DEBUG */
+	  res->node_info |= i->opt_flags;
+	} else {
+	  res->node_info |= opt_flags;
+	}
+      } else {
+	res->node_info |= opt_flags;
+      }
+      if(b) res->tree_info |= b->tree_info;
     }
-    if(b) res->tree_info |= b->tree_info;
     break;
 
   case F_POP_VALUE:
@@ -4368,7 +4411,8 @@ int dooptcode(struct pike_string *name,
 			      type,
 			      modifiers,
 			    IDENTIFIER_C_FUNCTION | vargs,
-			      &tmp);
+			      &tmp,
+			      foo->u.efun->flags);
 	  free_node(n);
 	  return ret;
 	}
@@ -4399,7 +4443,8 @@ int dooptcode(struct pike_string *name,
 		      type,
 		      modifiers,
 		      IDENTIFIER_PIKE_FUNCTION | vargs,
-		      &tmp);
+		      &tmp,
+		      Pike_compiler->compiler_frame->opt_flags);
 
 
 #ifdef PIKE_DEBUG
diff --git a/src/las.h b/src/las.h
index a602fd25d20eabe06678f771e24a503698927cf8..6e77ba1fad1f792a06bbf8e94de4f52cc64fa008 100644
--- a/src/las.h
+++ b/src/las.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: las.h,v 1.41 2000/08/14 17:48:50 grubba Exp $
+ * $Id: las.h,v 1.42 2000/08/30 21:58:16 grubba Exp $
  */
 #ifndef LAS_H
 #define LAS_H
@@ -53,6 +53,7 @@ struct compiler_frame
   int current_function_number;
   int recur_label;
   int is_inline;
+  unsigned int opt_flags;
   struct local_variable variable[MAX_LOCAL];
 };
 
diff --git a/src/program.c b/src/program.c
index 9f4deaf841941feee61013b4db879a67a79daaf6..48d443475ec5e995af6920e5081faf69d09406f0 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.267 2000/08/28 19:35:04 hubbe Exp $");
+RCSID("$Id: program.c,v 1.268 2000/08/30 21:58:17 grubba Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -2553,9 +2553,10 @@ PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags)
  */
 INT32 define_function(struct pike_string *name,
 		      struct pike_string *type,
-		      INT16 flags,
-		      INT8 function_flags,
-		      union idptr *func)
+		      unsigned INT8 flags,
+		      unsigned INT8 function_flags,
+		      union idptr *func,
+		      unsigned INT16 opt_flags)
 {
   struct identifier *funp,fun;
   struct reference ref;
@@ -2641,6 +2642,8 @@ INT32 define_function(struct pike_string *name,
 
       funp->identifier_flags=function_flags;
 
+      funp->opt_flags = opt_flags;
+
       free_string(funp->type);
       copy_shared_string(funp->type, type);
     }else{
@@ -2675,6 +2678,8 @@ INT32 define_function(struct pike_string *name,
       else
 	fun.func.offset = -1;
 
+      fun.opt_flags = opt_flags;
+
       ref.identifier_offset=Pike_compiler->new_program->num_identifiers;
       add_to_identifiers(fun);
     }
@@ -2740,6 +2745,8 @@ make_a_new_def:
   else
     fun.func.offset = -1;
 
+  fun.opt_flags = opt_flags;
+
   i=Pike_compiler->new_program->num_identifiers;
 
   add_to_identifiers(fun);
@@ -3429,7 +3436,9 @@ struct program *compile(struct pike_string *prog,
   return p;
 }
 
-PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
+PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32),
+				   char *type, unsigned INT8 flags,
+				   unsigned INT16 opt_flags)
 {
   int ret;
   struct pike_string *name_tmp,*type_tmp;
@@ -3445,13 +3454,15 @@ PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT1
 			type_tmp,
 			flags,
 			IDENTIFIER_C_FUNCTION,
-			&tmp);
+			&tmp,
+			opt_flags);
   }else{
     ret=define_function(name_tmp,
 			type_tmp,
 			flags,
 			IDENTIFIER_C_FUNCTION,
-			0);
+			0,
+			opt_flags);
   }
   free_string(name_tmp);
   free_string(type_tmp);
@@ -3459,19 +3470,19 @@ PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT1
 }
 
 PMOD_EXPORT int quick_add_function(char *name,
-		       int name_length,
-		       void (*cfun)(INT32),
-		       char *type,
-		       int type_length,
-		       INT16 flags,
-		       int opt_flags)
+				   int name_length,
+				   void (*cfun)(INT32),
+				   char *type,
+				   int type_length,
+				   unsigned INT8 flags,
+				   unsigned INT16 opt_flags)
 {
   int ret;
   struct pike_string *name_tmp,*type_tmp;
   union idptr tmp;
 /*  fprintf(stderr,"ADD_FUNC: %s\n",name); */
-  name_tmp=make_shared_binary_string(name,name_length);
-  type_tmp=make_shared_binary_string(type,type_length);
+  name_tmp = make_shared_binary_string(name,name_length);
+  type_tmp = make_shared_binary_string(type,type_length);
 
   if(cfun)
   {
@@ -3480,13 +3491,15 @@ PMOD_EXPORT int quick_add_function(char *name,
 			type_tmp,
 			flags,
 			IDENTIFIER_C_FUNCTION,
-			&tmp);
+			&tmp,
+			opt_flags);
   }else{
     ret=define_function(name_tmp,
 			type_tmp,
 			flags,
 			IDENTIFIER_C_FUNCTION,
-			0);
+			0,
+			opt_flags);
   }
   free_string(name_tmp);
   free_string(type_tmp);
@@ -3921,6 +3934,7 @@ void push_compiler_frame(int lexical_scope)
   f->recur_label=-1;
   f->is_inline=0;
   f->num_args=-1;
+  f->opt_flags = OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND; /* FIXME: Should be 0. */
   Pike_compiler->compiler_frame=f;
 }
 
diff --git a/src/program.h b/src/program.h
index 8a275889a95abbf3cdf9a4c861bf9d723e83fee7..f729129bb5ebb738895fec1e0b506351d60f2b12 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.108 2000/08/29 00:09:47 hubbe Exp $
+ * $Id: program.h,v 1.109 2000/08/30 21:58:17 grubba Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -146,8 +146,9 @@ struct identifier
 {
   struct pike_string *name;
   struct pike_string *type;
-  unsigned INT16 identifier_flags; /* IDENTIFIER_??? */
-  unsigned INT16 run_time_type;
+  unsigned INT8 identifier_flags;	/* IDENTIFIER_??? */
+  unsigned INT8 run_time_type;		/* PIKE_T_??? */
+  unsigned INT16 opt_flags;		/* OPT_??? */
 #ifdef PROFILING
   unsigned INT32 num_calls;
   unsigned INT32 total_time;
@@ -432,9 +433,10 @@ PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * ty
 PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags);
 INT32 define_function(struct pike_string *name,
 		      struct pike_string *type,
-		      INT16 flags,
-		      INT8 function_flags,
-		      union idptr *func);
+		      unsigned INT8 flags,
+		      unsigned INT8 function_flags,
+		      union idptr *func,
+		      unsigned INT16 opt_flags);
 int really_low_find_shared_string_identifier(struct pike_string *name,
 					     struct program *prog,
 					     int flags);
@@ -460,14 +462,16 @@ char *get_line(unsigned char *pc,struct program *prog,INT32 *linep);
 void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)));
 struct program *compile(struct pike_string *prog,
 			struct object *handler);
-int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags);
+int pike_add_function2(char *name, void (*cfun)(INT32),
+		       char *type, unsigned INT8 flags,
+		       unsigned INT16 opt_flags);
 PMOD_EXPORT int quick_add_function(char *name,
-		       int name_length,
-		       void (*cfun)(INT32),
-		       char *type,
-		       int type_length,
-		       INT16 flags,
-		       int opt_flags);
+				   int name_length,
+				   void (*cfun)(INT32),
+				   char *type,
+				   int type_length,
+				   unsigned INT8 flags,
+				   unsigned INT16 opt_flags);
 void check_all_programs(void);
 void init_program(void);
 void cleanup_program(void);
@@ -499,11 +503,15 @@ int yyexplain_not_implements(struct program *a, struct program *b, int flags);
 void *parent_storage(int depth);
 /* Prototypes end here */
 
-#define ADD_FUNCTION(NAME,FUNC,TYPE,FLAGS) \
-  quick_add_function(NAME,CONSTANT_STRLEN(NAME),FUNC,TYPE,CONSTANT_STRLEN(TYPE),FLAGS,0)
+#define ADD_FUNCTION(NAME, FUNC, TYPE, FLAGS) \
+  quick_add_function(NAME, CONSTANT_STRLEN(NAME), FUNC, TYPE,\
+                     CONSTANT_STRLEN(TYPE), FLAGS, \
+                     OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND)
 
-#define ADD_PROTOTYPE(NAME,TYPE,FLAGS) \
-  quick_add_function(NAME,CONSTANT_STRLEN(NAME),0,TYPE,CONSTANT_STRLEN(TYPE),FLAGS,0)
+#define ADD_PROTOTYPE(NAME, TYPE, FLAGS) \
+  quick_add_function(NAME, CONSTANT_STRLEN(NAME), 0, TYPE, \
+                     CONSTANT_STRLEN(TYPE), FLAGS, \
+                     OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND)
 
 #define ADD_INT_CONSTANT(NAME,CONST,FLAGS) \
   quick_add_integer_constant(NAME,CONSTANT_STRLEN(NAME),CONST,FLAGS)
@@ -511,25 +519,31 @@ void *parent_storage(int depth);
 #define PIKE_MAP_VARIABLE(NAME,OFFSET,TYPE,RTTYPE,FLAGS) \
   quick_map_variable(NAME,CONSTANT_STRLEN(NAME),OFFSET,TYPE,CONSTANT_STRLEN(TYPE),RTTYPE,FLAGS)
 
-#define ADD_FUNCTION_DTYPE(NAME,FUN,DTYPE,FLAGS) do {				\
-  DTYPE_START;									\
-  {DTYPE}									\
-  {										\
-    struct pike_string *_t;							\
-    DTYPE_END(_t);								\
-    quick_add_function(NAME,CONSTANT_STRLEN(NAME),FUN,_t->str,_t->len,FLAGS,0);	\
-    free_string(_t);								\
-  }										\
+#define ADD_FUNCTION_DTYPE(NAME,FUN,DTYPE,FLAGS) do {		\
+  DTYPE_START;							\
+  {DTYPE}							\
+  {								\
+    struct pike_string *_t;					\
+    DTYPE_END(_t);						\
+    quick_add_function(NAME, CONSTANT_STRLEN(NAME), FUN,	\
+                        _t->str, _t->len, FLAGS,		\
+                       OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);	\
+    free_string(_t);						\
+  }								\
 } while (0)
 
+#define pike_add_function(NAME, CFUN, TYPE, FLAGS)	\
+  pike_add_function2(NAME, CFUN, TYPE, FLAGS,		\
+                     OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND)
+
 #ifndef NO_PIKE_SHORTHAND
 #define add_function pike_add_function
 #endif
 
 #define START_NEW_PROGRAM_ID(ID) do { \
-  start_new_program();  \
-  Pike_compiler->new_program->id=PIKE_CONCAT3(PROG_,ID,_ID); \
- }while(0)
+    start_new_program();  \
+    Pike_compiler->new_program->id=PIKE_CONCAT3(PROG_,ID,_ID); \
+  }while(0)
 
 #ifdef DEBUG_MALLOC
 #define end_program() ((struct program *)debug_malloc_pass(debug_end_program()))
@@ -557,3 +571,11 @@ void *parent_storage(int depth);
 
 
 #endif /* PROGRAM_H */
+
+/* Kludge... */
+#ifndef LAS_H
+/* FIXME: Needed for the OPT_??? macros.
+ * Maybe they should be moved here, since las.h includes this file anyway?
+ */
+#include "las.h"
+#endif /* !LAS_H */