/* ----------------------------------------------------------------------------- 
 * allocate.cxx
 *
 *     This module tries to figure out which classes and structures support
 *     default constructors and destructors in C++.   There are several rules that
 *     define this behavior including pure abstract methods, private sections,
 *     and non-default constructors in base classes.  See the ARM or
 *     Doc/Manual/SWIGPlus.html for details.
 * 
 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
 *
 * Copyright (C) 1998-2002.  The University of Chicago
 * Copyright (C) 1995-1998.  The University of Utah and The Regents of the
 *                           University of California.
 *
 * See the file LICENSE for information on usage and redistribution.	
 * ----------------------------------------------------------------------------- */

char cvsroot_allocate_cxx[] = "$Header$";

#include "swigmod.h"

static int virtual_elimination_mode = 0;   /* set to 0 on default */

/* Set virtual_elimination_mode */
void Wrapper_virtual_elimination_mode_set(int flag) {
  virtual_elimination_mode = flag;
}

/* Helper function to assist with abstract class checking.  
   This is a major hack. Sorry.  */

extern "C" {
static String *search_decl = 0;            /* Declarator being searched */ 
static int check_implemented(Node *n) {
  String *decl;
  if (!n) return 0;
  while (n) {
    if (Strcmp(nodeType(n), "cdecl") == 0) {
      decl = Getattr(n,"decl");
      if (SwigType_isfunction(decl)) {
	SwigType *decl1 = SwigType_typedef_resolve_all(decl);
	SwigType *decl2 = SwigType_pop_function(decl1);
	if (Strcmp(decl2, search_decl) == 0) {
	  if (!Getattr(n,"abstract")) {
	    Delete(decl1);
	    Delete(decl2);
	    return 1;
	  }
	}
	Delete(decl1);
	Delete(decl2);
      }
    }
    n = Getattr(n,"csym:nextSibling");
  }
  return 0;
}
}

class Allocate : public Dispatcher {
  Node  *inclass;
  int extendmode;

  /* Checks if a function, n, is the same as any in the base class, ie if the method is polymorphic.
   * Also checks for methods which will be hidden (ie a base has an identical non-virtual method).
   * Both methods must have public access for a match to occur. */
  int function_is_defined_in_bases(Node *n, Node *bases) {

    if (!bases)
      return 0;

    String *this_decl = Getattr(n, "decl");
    if (!this_decl)
      return 0;

    String *name = Getattr(n, "name");
    String *this_type = Getattr(n, "type");
    String *resolved_decl = SwigType_typedef_resolve_all(this_decl);

    // Search all base classes for methods with same signature
    for (int i = 0; i < Len(bases); i++) {
      Node *b = Getitem(bases,i);
      Node *base = firstChild (b);
      while (base) {
	if (Strcmp(nodeType(base),"extend") == 0) {
	  // Loop through all the %extend methods
	  Node *extend = firstChild(base);
	  while (extend) {
	    if (function_is_defined_in_bases_seek(n, b, extend, this_decl, name, this_type, resolved_decl)) {
	      Delete(resolved_decl);
	      return 1;
	    }
	    extend = nextSibling(extend);
	  }
	} else if (Strcmp(nodeType(base),"using") == 0) {
	  // Loop through all the using declaration methods
	  Node *usingdecl = firstChild(base);
	  while (usingdecl) {
	    if (function_is_defined_in_bases_seek(n, b, usingdecl, this_decl, name, this_type, resolved_decl)) {
	      Delete(resolved_decl);
	      return 1;
	    }
	    usingdecl = nextSibling(usingdecl);
	  }
	} else {
	  // normal methods
	  if (function_is_defined_in_bases_seek(n, b, base, this_decl, name, this_type, resolved_decl)) {
	    Delete(resolved_decl);
	    return 1;
	  }
	}
	base = nextSibling(base);
      }
    }
    Delete(resolved_decl);
    resolved_decl = 0;
    for (int j = 0; j < Len(bases); j++) {
      Node *b = Getitem(bases,j);
      if (function_is_defined_in_bases(n, Getattr(b, "allbases")))
	return 1;
    }
    return 0;
  }

  /* Helper function for function_is_defined_in_bases */
  int function_is_defined_in_bases_seek(Node *n, Node *b, Node *base, String *this_decl, String *name, String *this_type, String *resolved_decl) {

    String *base_decl = Getattr(base, "decl");
    SwigType *base_type = Getattr(base, "type");
    if (base_decl && base_type) {
      if (checkAttribute(base, "name", name) && !GetFlag(b, "feature:ignore") /* whole class is ignored */ ) {
	if (SwigType_isfunction(resolved_decl) && SwigType_isfunction(base_decl)) {
	  // We have found a method that has the same name as one in a base class
	  bool covariant_returntype  = false;
	  bool returntype_match = Strcmp(base_type, this_type) == 0 ? true : false;
	  bool decl_match = Strcmp(base_decl, this_decl) == 0 ? true : false;
	  if (returntype_match && decl_match) {
	    // Exact match - we have found a method with identical signature
	    // No typedef resolution was done, but skipping it speeds things up slightly
	  } else {
	    // Either we have:
	    //  1) matching methods but are one of them uses a different typedef (return type or parameter) to the one in base class' method
	    //  2) matching polymorphic methods with covariant return type
	    //  3) a non-matching method (ie an overloaded method of some sort)
	    //  4) a matching method which is not polymorphic, ie it hides the base class' method

	    // Check if fully resolved return types match (including covariant return types)
	    String *this_returntype = function_return_type(n);
	    String *base_returntype = function_return_type(base);
	    returntype_match = Strcmp(this_returntype, base_returntype) == 0 ? true : false;
	    if (!returntype_match) {
	      covariant_returntype = SwigType_issubtype(this_returntype, base_returntype) ? true : false;
	      returntype_match = covariant_returntype;
	    }

	    // The return types must match at this point, for the whole method to match
	    if (returntype_match) {
	      // Now need to check the parameter list
	      // First do an inexpensive parameter count
	      ParmList *this_parms = Getattr(n,"parms");
	      ParmList *base_parms = Getattr(base,"parms");
	      if (ParmList_len(this_parms) == ParmList_len(base_parms)) {
		// Number of parameters are the same, now check that all the parameters match
		SwigType *base_fn = NewString("");
		SwigType *this_fn = NewString("");
		SwigType_add_function(base_fn, base_parms);
		SwigType_add_function(this_fn, this_parms);
		base_fn = SwigType_typedef_resolve_all(base_fn);
		this_fn = SwigType_typedef_resolve_all(this_fn);
		if (Strcmp(base_fn, this_fn) == 0) {
		  // Finally check that the qualifiers match
		  int base_qualifier = SwigType_isqualifier(resolved_decl);
		  int this_qualifier = SwigType_isqualifier(base_decl);
		  if (base_qualifier == this_qualifier) {
		    decl_match = true;
		  }
		}
		Delete(base_fn);
		Delete(this_fn);
	      }
	    }
	    Delete(this_returntype);
	    Delete(base_returntype);
	  }

	  if (decl_match && returntype_match) {
	    // Found an identical method in the base class
	    String *this_access = Getattr(n, "access");
	    String *base_access = Getattr(base, "access");
	    bool both_have_public_access = !this_access && !base_access;
	    if (checkAttribute(base, "storage", "virtual")) {
	      // Found a polymorphic method.
	      // Mark the polymorphic method, in case the virtual keyword was not used.
	      Setattr(n, "storage", "virtual");

	      if (both_have_public_access)
                if (!is_non_public_base(inclass, b))
                  Setattr(n, "override", base); 

	      // Try and find the most base's covariant return type
	      SwigType *most_base_covariant_type = Getattr(base, "covariant");
	      if (!most_base_covariant_type && covariant_returntype)
		most_base_covariant_type = function_return_type(base, false);

	      if (!most_base_covariant_type) {
		// Eliminate the derived virtual method.
		if (virtual_elimination_mode)
		  if (both_have_public_access)
		    if (!is_non_public_base(inclass, b))
		      SetFlag(n,"feature:ignore");
	      } else {
		// Some languages need to know about covariant return types
		Setattr(n, "covariant", most_base_covariant_type);
	      }

	    } else {
	      // Found an identical method in the base class, but it is not polymorphic.
	      if (both_have_public_access)
                if (!is_non_public_base(inclass, b))
                  Setattr(n, "hides", base);
	    }
	    if (both_have_public_access)
	      return 1;
	  }
	}
      }
    }
    return 0;
  }

  /* Determines whether the base class, b, is in the list of private
   * or protected base classes for class n. */
  bool is_non_public_base(Node *n, Node *b) {
    bool non_public_base = false;
    Node *bases = Getattr(n, "privatebases");
    if (bases) {
      for (int i = 0; i < Len(bases); i++) {
        Node *base = Getitem(bases,i);
        if (base == b)
          non_public_base = true;
      }
    }
    bases = Getattr(n, "protectedbases");
    if (bases) {
      for (int i = 0; i < Len(bases); i++) {
        Node *base = Getitem(bases,i);
        if (base == b)
          non_public_base = true;
      }
    }
    return non_public_base;
  }

  /* Returns the return type for a function. The node n should be a function.
     If resolve is true the fully returned type is fully resolved.
     Caller is responsible for deleting returned string. */
  String *function_return_type(Node *n, bool resolve = true) {
    String *decl = Getattr(n, "decl");
    SwigType *type  = Getattr(n,"type");
    String *ty = NewString(type);
    SwigType_push(ty,decl);
    if (SwigType_isqualifier(ty))
      Delete(SwigType_pop(ty));
    Delete(SwigType_pop_function(ty));
    if (resolve) {
      String *unresolved = ty;
      ty = SwigType_typedef_resolve_all(unresolved);
      Delete(unresolved);
    }
    return ty;
  }

  /* Checks if a class member is the same as inherited from the class bases */
  int class_member_is_defined_in_bases(Node *member, Node *classnode) {
    Node *bases; /* bases is the closest ancestors of classnode */
    int defined = 0;

    bases = Getattr(classnode, "allbases");
    if (!bases) return 0;

    {
      int old_mode = virtual_elimination_mode;
      if (is_member_director(classnode, member))
	virtual_elimination_mode = 0;
      
      if (function_is_defined_in_bases(member, bases))
	defined = 1;

      virtual_elimination_mode = old_mode;
    }

    if (defined)
      return 1;
    else return 0;
  }

  /* Checks to see if a class is abstract through inheritance,
     and saves the first node that seems to be abstract.
   */
  int is_abstract_inherit(Node *n, Node *base = 0, int first = 0) {
    if (!first && (base == n)) return 0;
    if (!base) {
      /* Root node */
      Symtab *stab = Getattr(n,"symtab");         /* Get symbol table for node */
      Symtab *oldtab = Swig_symbol_setscope(stab);
      int ret = is_abstract_inherit(n,n,1);
      Swig_symbol_setscope(oldtab);
      return ret;
    }
    List *abstract = Getattr(base,"abstract");
    if (abstract) {
      for (int i = 0; i < Len(abstract); i++) {
	Node *nn = Getitem(abstract,i);
	String *name = Getattr(nn,"name");
	if (!name) continue;
	String *base_decl = Getattr(nn,"decl");
	if (base_decl) base_decl = SwigType_typedef_resolve_all(base_decl);
	if (Strstr(name,"~")) continue;   /* Don't care about destructors */

	if (SwigType_isfunction(base_decl)) {
	  search_decl = SwigType_pop_function(base_decl);
	}
	Node *dn = Swig_symbol_clookup_local_check(name,0,check_implemented);
	Delete(search_decl);
	Delete(base_decl);

	if (!dn) {
	  List *abstract = Getattr(n,"abstract");
	  if (!abstract) {
	    abstract = NewList();
	    Setattr(n,"abstract",abstract);
	  } else {
	    if (!Getattr(n,"abstract:firstnode"))
	      Setattr(n,"abstract:firstnode",nn);
	  }
	  Append(abstract,nn);
	}
      }
    }
    List *bases = Getattr(base,"allbases");
    if (!bases) return 0;
    for (int i = 0; i < Len(bases); i++) {
      if (is_abstract_inherit(n,Getitem(bases,i))) {
	return 1;
      }
    }
    return 0;
  }


  /* Grab methods used by smart pointers */

  List *smart_pointer_methods(Node *cls, List *methods, int isconst,
			      String *classname=0) {
    if (!methods) {
      methods = NewList();
    }
    
    Node *c = firstChild(cls);
    String *kind = Getattr(cls,"kind");
    int mode = PUBLIC;
    if (kind && (Strcmp(kind,"class") == 0)) mode = PRIVATE;
    
    while (c) {
      if (Getattr(c,"error") || GetFlag(c,"feature:ignore")) {
	c = nextSibling(c);
	continue;
      }
      if (!isconst && (Strcmp(nodeType(c),"extend") == 0)) {
	methods = smart_pointer_methods(c, methods, isconst, Getattr(cls,"name"));
      } else if (Strcmp(nodeType(c),"cdecl") == 0) {
	if (!GetFlag(c,"feature:ignore")) {
	  String *storage = Getattr(c,"storage");
	  if (!((Cmp(storage,"typedef") == 0))
	      && !((Cmp(storage,"friend") == 0))) {
	    String *name = Getattr(c,"name");
	    String *symname = Getattr(c,"sym:name");
	    Node   *e    = Swig_symbol_clookup_local(name,0);
	    if (e && is_public(e) && !GetFlag(e,"feature:ignore") && (Cmp(symname, Getattr(e,"sym:name")) == 0)) {
	      Swig_warning(WARN_LANG_DEREF_SHADOW,Getfile(e),Getline(e),"Declaration of '%s' shadows declaration accessible via operator->(),\n",
			   name);
	      Swig_warning(WARN_LANG_DEREF_SHADOW,Getfile(c),Getline(c),"previous declaration of '%s'.\n", name);
	    } else {
	      /* Make sure node with same name doesn't already exist */
	      int k;
	      int match = 0;
	      for (k = 0; k < Len(methods); k++) {
		e = Getitem(methods,k);
		if (Cmp(symname,Getattr(e,"sym:name")) == 0) {
		  match = 1;
		  break;
		}
		if ((!symname  || (!Getattr(e,"sym:name"))) && (Cmp(name,Getattr(e,"name")) == 0)) {
		  match = 1;
		  break;
		}
	      }
	      if (!match) {
		Node *cc = c;
		while (cc) {
		  Node *cp = cc;
		  if (classname) {
		    Setattr(cp,"classname",classname);
		  }
		  Setattr(cp,"allocate:smartpointeraccess","1");
		  /* If constant, we have to be careful */
		  if (isconst) {
		    SwigType *decl = Getattr(cp,"decl");
		    if (decl) {
		      if (SwigType_isfunction(decl)) {   /* If method, we only add if it's a const method */
			if (SwigType_isconst(decl)) {
			  Append(methods,cp);
			}
		      } else {
			Append(methods,cp);
		      }
		    } else {
		      Append(methods,cp);
		    }
		  } else {
		    Append(methods,cp);
		  }
		  cc = Getattr(cc,"sym:nextSibling");
		}
	      }
	    }
	  }
	}
      }

      if (Strcmp(nodeType(c),"access") == 0) {
	kind = Getattr(c,"kind");
	if (Strcmp(kind,"public") == 0) mode = PUBLIC;
	else mode = PRIVATE;
      }
      c = nextSibling(c);
    }
    /* Look for methods in base classes */
    {
      Node *bases = Getattr(cls,"bases");
      int k;
      for (k = 0; k < Len(bases); k++) {
	smart_pointer_methods(Getitem(bases,k),methods,isconst);
      }
    }
    /* Remove protected/private members */
    {
      for (int i = 0; i < Len(methods); ) {
	Node *n = Getitem(methods,i);
	if (!is_public(n)) {
	  Delitem(methods,i);
	  continue;
	}
	i++;
      }
    }
    return methods;
  }

  void mark_exception_classes(ParmList *p) {
    while(p) {
      SwigType *ty = Getattr(p,"type");      
      SwigType *t = SwigType_typedef_resolve_all(ty);
      if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) {
	Delete(SwigType_pop(t));
      }
      Node *c = Swig_symbol_clookup(t,0);
      if (c) {
	if (!GetFlag(c,"feature:exceptionclass")) {
	  SetFlag(c,"feature:exceptionclass");
	}
      }
      p = nextSibling(p);
      Delete(t);
    }
  }

public:
  Allocate() :
    inclass(NULL),
    extendmode(0) {}

  virtual int top(Node *n) {
    cplus_mode = PUBLIC;
    inclass = 0;
    extendmode = 0;
    emit_children(n);
    return SWIG_OK;
  }

  virtual int importDirective(Node *n) { return emit_children(n); }
  virtual int includeDirective(Node *n) { return emit_children(n); }
  virtual int externDeclaration(Node *n) { return emit_children(n); }
  virtual int namespaceDeclaration(Node *n) { return emit_children(n); }
  virtual int extendDirective(Node *n) {
      extendmode = 1;
      emit_children(n);
      extendmode = 0;
      return SWIG_OK;
  }

  virtual int classDeclaration(Node *n) {
    Symtab *symtab = Swig_symbol_current();
    Swig_symbol_setscope(Getattr(n,"symtab"));

    if (!CPlusPlus) {
      /* Always have default constructors/destructors in C */
      Setattr(n,"allocate:default_constructor","1");
      Setattr(n,"allocate:default_destructor","1");
    }

    if (Getattr(n,"allocate:visit")) return SWIG_OK;
    Setattr(n,"allocate:visit","1");
    
    /* Always visit base classes first */
    {
      List *bases = Getattr(n,"bases");
      if (bases) {
	for (int i = 0; i < Len(bases); i++) {
	  Node *b = Getitem(bases,i);
	  classDeclaration(b);
	}
      }
    }

    inclass = n;
    String *kind = Getattr(n,"kind");
    if (Strcmp(kind,"class") == 0) {
      cplus_mode = PRIVATE;
    } else {
      cplus_mode = PUBLIC;
    }

    emit_children(n);

    /* Check if the class is abstract via inheritance.   This might occur if a class didn't have
       any pure virtual methods of its own, but it didn't implement all of the pure methods in
       a base class */
    
    if (!Getattr(n,"abstract") && is_abstract_inherit(n)) {
      if (((Getattr(n,"allocate:public_constructor") || (!GetFlag(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) {
	if (!GetFlag(n,"feature:notabstract")) {
	  Node *na = Getattr(n,"abstract:firstnode");
	  if (na) {
	    Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n),
			 "Class '%s' might be abstract, "
			 "no constructors generated,\n",
			 SwigType_namestr(Getattr(n,"name")));
	    Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na),
			 " method '%s' might not be implemented.",
			 SwigType_namestr(Getattr(na,"name")));
	    if (!Getattr(n,"abstract")) {
	      List *abstract = NewList();
	      Append(abstract,na);
	      Setattr(n,"abstract",abstract);
	    }
	  }
	}
      }
    }

    if (!Getattr(n,"allocate:has_constructor")) {
      /* No constructor is defined.  We need to check a few things */
      /* If class is abstract.  No default constructor. Sorry */
      if (Getattr(n,"abstract")) {
	Delattr(n,"allocate:default_constructor");
      } 
      if (!Getattr(n,"allocate:default_constructor")) {
	/* Check base classes */
	List *bases = Getattr(n,"allbases");
	int   allows_default = 1;
	
	for (int i = 0; i < Len(bases); i++) {
	  Node *n = Getitem(bases,i);
	  /* If base class does not allow default constructor, we don't allow it either */
	  if (!Getattr(n,"allocate:default_constructor") && (!Getattr(n,"allocate:default_base_constructor"))) {
	    allows_default = 0;
	  }
	}
	if (allows_default) {
	  Setattr(n,"allocate:default_constructor","1");
	}
      }
    }
    if (!Getattr(n,"allocate:has_destructor")) {
      /* No destructor was defined.  We need to check a few things here too */
      List *bases = Getattr(n,"allbases");
      int allows_destruct = 1;

      for (int i = 0; i < Len(bases); i++) {
	Node *n = Getitem(bases,i);
	/* If base class does not allow default destructor, we don't allow it either */
	if (!Getattr(n,"allocate:default_destructor") && (!Getattr(n,"allocate:default_base_destructor"))) {
	  allows_destruct = 0;
	}
      }
      if (allows_destruct) {
	Setattr(n,"allocate:default_destructor","1");
      }
    }

    if (!Getattr(n,"allocate:has_assign")) {
      /* No destructor was defined.  We need to check a few things here too */
      List *bases = Getattr(n,"allbases");
      int allows_assign = 1;

      for (int i = 0; i < Len(bases); i++) {
	Node *n = Getitem(bases,i);
	/* If base class does not allow default destructor, we don't allow it either */
	if (Getattr(n,"allocate:has_assign")) {
	  allows_assign = !Getattr(n,"allocate:noassign");
	}
      }
      if (!allows_assign) {
	Setattr(n,"allocate:noassign","1");
      }
    }

    if (!Getattr(n,"allocate:has_new")) {
      /* No destructor was defined.  We need to check a few things here too */
      List *bases = Getattr(n,"allbases");
      int allows_new = 1;

      for (int i = 0; i < Len(bases); i++) {
	Node *n = Getitem(bases,i);
	/* If base class does not allow default destructor, we don't allow it either */
	if (Getattr(n,"allocate:has_new")) {
	  allows_new = !Getattr(n,"allocate:nonew");
	}
      }
      if (!allows_new) {
	Setattr(n,"allocate:nonew","1");
      }
    }

    /* Check if base classes allow smart pointers, but might be hidden */
    if (!Getattr(n,"allocate:smartpointer")) {
      Node *sp = Swig_symbol_clookup((char*)"operator ->",0);
      if (sp) {
        /* Look for parent */
	Node *p = parentNode(sp);
	if (Strcmp(nodeType(p),"extend") == 0) {
	  p = parentNode(p);
	}
	if (Strcmp(nodeType(p),"class") == 0) {
	  if (GetFlag(p,"feature:ignore")) {
	    Setattr(n,"allocate:smartpointer",Getattr(p,"allocate:smartpointer"));
	  }
	}
      }
    }

    /* Only care about default behavior.  Remove temporary values */
    Setattr(n,"allocate:visit","1");
    inclass = 0;
    Swig_symbol_setscope(symtab);
    return SWIG_OK;
  }

  virtual int accessDeclaration(Node *n) {
    String *kind = Getattr(n,"kind");
    if (Cmp(kind,"public") == 0) {
      cplus_mode = PUBLIC;
    } else if (Cmp(kind,"private") == 0) {
      cplus_mode = PRIVATE;
    } else if (Cmp(kind,"protected") == 0) {
      cplus_mode = PROTECTED;
    }
    return SWIG_OK;
  }

  virtual int usingDeclaration(Node *n) {

    Node *c = 0;
    for (c = firstChild(n); c; c = nextSibling(c)) {
      if (Strcmp(nodeType(c),"cdecl") == 0) {
	mark_exception_classes(Getattr(c,"throws"));

	if (inclass)
	  class_member_is_defined_in_bases(c, inclass);
      }
    }

    return SWIG_OK;
  }

  virtual int cDeclaration(Node *n) {
    
    mark_exception_classes(Getattr(n,"throws"));

    if (inclass) {
      /* check whether the member node n is defined in class node in class's bases */
      class_member_is_defined_in_bases(n, inclass);

      /* Check to see if this is a static member or not.  If so, we add an attribute
	 cplus:staticbase that saves the current class */

      if (checkAttribute(n,"storage","static")) {
	Setattr(n,"cplus:staticbase", inclass);
      }

      String *name = Getattr(n,"name");
      if (cplus_mode != PUBLIC) {
	if (Strcmp(name,"operator =") == 0) {
	  /* Look for a private assignment operator */
	  Setattr(inclass,"allocate:has_assign","1");
	  Setattr(inclass,"allocate:noassign","1");
	} else if (Strcmp(name,"operator new") == 0) {
	  /* Look for a private new operator */
	  Setattr(inclass,"allocate:has_new","1");
	  Setattr(inclass,"allocate:nonew","1");
	}
      } else {
	if (Strcmp(name,"operator =") == 0) {
	  Setattr(inclass,"allocate:has_assign","1");
	} else if (Strcmp(name,"operator new") == 0) {
	  Setattr(inclass,"allocate:has_new","1");
	}
	/* Look for smart pointer operator */
	if ((Strcmp(name,"operator ->") == 0) && (!GetFlag(n,"feature:ignore"))) {
	  /* Look for version with no parameters */
	  Node *sn = n;
	  while (sn) {
	    if (!Getattr(sn,"parms")) {
	      SwigType *type = SwigType_typedef_resolve_all(Getattr(sn,"type"));
	      SwigType_push(type,Getattr(sn,"decl"));
	      Delete(SwigType_pop_function(type));
	      SwigType *base = SwigType_base(type);
	      Node *sc = Swig_symbol_clookup(base, 0);
	      if ((sc) && (Strcmp(nodeType(sc),"class") == 0)) {
		if (SwigType_check_decl(type,"p.")) {
		  /* Need to check if type is a const pointer */
		  int isconst = 0;
		  Delete(SwigType_pop(type));
		  if (SwigType_isconst(type)) {
		    isconst = 1;
		    Setattr(inclass,"allocate:smartpointerconst","1");
		  }
		  List *methods = smart_pointer_methods(sc,0,isconst);
		  Setattr(inclass,"allocate:smartpointer",methods);
		  Setattr(inclass,"allocate:smartpointerbase",base);
		} else {
		  /* Hmmm.  The return value is not a pointer.  If the type is a value
		     or reference.  We're going to chase it to see if another operator->()
		     can be found */
		  
		  if ((SwigType_check_decl(type,"")) || (SwigType_check_decl(type,"r."))) {
		    Node *nn = Swig_symbol_clookup((char*)"operator ->", Getattr(sc,"symtab"));
		    if (nn) {
		      Delete(base);
		      Delete(type);
		      sn = nn;
		      continue;
		    }
		  }
		}
	      }
	      Delete(base);
	      Delete(type);
	      break;		  
	    }
	  }
	}
      }
    }
    return SWIG_OK;
  }

  virtual int constructorDeclaration(Node *n) {
    if (!inclass) return SWIG_OK;
    Parm   *parms = Getattr(n,"parms");

    mark_exception_classes(Getattr(n,"throws"));
    if (!extendmode) {
	if (!ParmList_numrequired(parms)) {
	    /* Class does define a default constructor */
	    /* However, we had better see where it is defined */
	    if (cplus_mode == PUBLIC) {
		Setattr(inclass,"allocate:default_constructor","1");
	    } else if (cplus_mode == PROTECTED) {
		Setattr(inclass,"allocate:default_base_constructor","1");
	    }
	}
	/* Class defines some kind of constructor. May or may not be public */
	Setattr(inclass,"allocate:has_constructor","1");
	if (cplus_mode == PUBLIC) {
	  Setattr(inclass,"allocate:public_constructor","1");
	}
    }

    /* See if this is a copy constructor */
    if (parms && (ParmList_numrequired(parms) == 1)) {
      /* Look for a few cases. X(const X &), X(X &), X(X *) */

      String *cc = NewStringf("r.q(const).%s", Getattr(inclass,"name"));
      if (Strcmp(cc,Getattr(parms,"type")) == 0) {
	Setattr(n,"copy_constructor","1");
      }
      Delete(cc);
      cc = NewStringf("r.%s", Getattr(inclass,"name"));
      if (Strcmp(cc,Getattr(parms,"type")) == 0) {
	Setattr(n,"copy_constructor","1");
      }
      Delete(cc);
      cc = NewStringf("p.%s", Getattr(inclass,"name"));
      String *ty = SwigType_strip_qualifiers(Getattr(parms,"type"));
      if (Strcmp(cc,ty) == 0) {
	Setattr(n,"copy_constructor","1");
      }
      Delete(cc);
      Delete(ty);
    }
    return SWIG_OK;
  }

  virtual int destructorDeclaration(Node *n) {
    (void)n;
    if (!inclass) return SWIG_OK;
    if (!extendmode) {
	Setattr(inclass,"allocate:has_destructor","1");
	if (cplus_mode == PUBLIC) {
	    Setattr(inclass,"allocate:default_destructor","1");
	} else if (cplus_mode == PROTECTED) {
	    Setattr(inclass,"allocate:default_base_destructor","1");
	}
    }
    return SWIG_OK;
  }
};

void Swig_default_allocators(Node *n) {
  if (!n) return;
  Allocate *a = new Allocate;
  a->top(n);
  delete a;
}





  
