⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objc-actions.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	*q = 0;      }    /* Make the constructor name from the name we have found.  */    buf = (char *) xmalloc (sizeof (CONSTRUCTOR_NAME_FORMAT)			    + strlen (global_object_name));    sprintf (buf, CONSTRUCTOR_NAME_FORMAT, global_object_name);    /* Declare void __objc_execClass (void*); */    void_list_node = build_tree_list (NULL_TREE, void_type_node);    function_type      = build_function_type (void_type_node,  			     tree_cons (NULL_TREE, ptr_type_node,  					void_list_node));    function_decl = build_decl (FUNCTION_DECL,  				get_identifier ("__objc_execClass"),  				function_type);    DECL_EXTERNAL (function_decl) = 1;    TREE_PUBLIC (function_decl) = 1;    pushdecl (function_decl);    rest_of_decl_compilation (function_decl, 0, 0, 0);    parms      = build_tree_list (NULLT,			 build_unary_op (ADDR_EXPR, _OBJC_MODULES_decl, 0));    decelerator = build_function_call (function_decl, parms);    /* void __objc_file_init () {objc_execClass(&L_OBJC_MODULES);}  */    start_function (void_list_node,		    build_parse_node (CALL_EXPR, get_identifier (buf),				      /* This has the format of the output					 of get_parm_info.  */				      tree_cons (NULL_TREE, NULL_TREE,						 void_list_node),				      NULL_TREE),		    0, 0);#if 0 /* This should be turned back on later	 for the systems where collect is not needed.  */    /* Make these functions nonglobal       so each file can use the same name.  */    TREE_PUBLIC (current_function_decl) = 0;#endif    TREE_USED (current_function_decl) = 1;    store_parm_decls ();    assemble_external (function_decl);    c_expand_expr_stmt (decelerator);    finish_function (0);    /* Return the name of the constructor function.  */    return buf;  }#else /* NEXT_OBJC_RUNTIME */  return 0;#endif /* NEXT_OBJC_RUNTIME */}/* extern const char _OBJC_STRINGS[]; */static voidgenerate_forward_declaration_to_string_table (){  tree sc_spec, decl_specs, expr_decl;  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_EXTERN], NULLT);  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);  expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);  _OBJC_STRINGS_decl = define_decl (expr_decl, decl_specs);}/* static char _OBJC_STRINGS[] = "..."; */static voidbuild_message_selector_pool (){  tree sc_spec, decl_specs, expr_decl;  tree chain, string_expr;  int goolengthtmp = 0, msg_pool_size = 0;  char *string_goo;  sc_spec = tree_cons (NULLT, ridpointers[(int) RID_STATIC], NULLT);  decl_specs = tree_cons (NULLT, ridpointers[(int) RID_CHAR], sc_spec);  expr_decl = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULLT);  _OBJC_STRINGS_decl = start_decl (expr_decl, decl_specs, 1);  for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))    msg_pool_size += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;  msg_pool_size++;  string_goo = (char *)xmalloc (msg_pool_size);  bzero (string_goo, msg_pool_size);  for (chain = sel_refdef_chain; chain; chain = TREE_CHAIN (chain))    {      strcpy (string_goo + goolengthtmp, IDENTIFIER_POINTER (TREE_VALUE (chain)));      goolengthtmp += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;    }  string_expr = my_build_string (msg_pool_size, string_goo);  finish_decl (_OBJC_STRINGS_decl, string_expr, NULLT);}/* * synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>] * * the cast stops the compiler from issuing the following message: * * grok.m: warning: initialization of non-const * pointer from const * * grok.m: warning: initialization between incompatible pointer types */static treebuild_msg_pool_reference (offset)     int offset;{  tree expr = build_int_2 (offset, 0);  tree cast;  expr = build_array_ref (_OBJC_STRINGS_decl, expr);  expr = build_unary_op (ADDR_EXPR, expr, 0);  cast = build_tree_list (build_tree_list (NULLT, ridpointers[(int) RID_CHAR]),			  build1 (INDIRECT_REF, NULLT, NULLT));  TREE_TYPE (expr) = groktypename (cast);  return expr;}#ifndef OBJC_SELECTORS_WITHOUT_LABELSstatic treebuild_selector_reference (idx)      int idx;{  tree ref, decl, name, ident;  char buf[256];  struct obstack *save_current_obstack = current_obstack;  struct obstack *save_rtl_obstack = rtl_obstack;  sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);  /* new stuff */  rtl_obstack = current_obstack = &permanent_obstack;  ident = get_identifier (buf);  if (IDENTIFIER_GLOBAL_VALUE (ident))    decl = IDENTIFIER_GLOBAL_VALUE (ident); /* set by pushdecl() */  else     {      decl = build_decl (VAR_DECL, ident, selector_type);      DECL_EXTERNAL (decl) = 1;      TREE_PUBLIC (decl) = 1;      TREE_USED (decl) = 1;        make_decl_rtl (decl, 0, 1); /* usually called from `rest_of_decl_compilation' */      pushdecl_top_level (decl);  /* our `extended/custom' pushdecl in c-decl.c */    }  current_obstack = save_current_obstack;  rtl_obstack = save_rtl_obstack;  return decl;}#endifstatic treeinit_selector (offset)     int offset;{  tree expr = build_msg_pool_reference (offset);  TREE_TYPE (expr) = selector_type; /* cast */  return expr;}static voidbuild_selector_translation_table (){  tree sc_spec, decl_specs, expr_decl;  tree chain, initlist = NULLT;  int offset = 0;#ifndef OBJC_SELECTORS_WITHOUT_LABELS  tree decl, var_decl;  int idx = 0;  char buf[256];#else  /* The corresponding pop_obstacks is in finish_decl,     called at the end of this function.  */  push_obstacks_nochange ();#endif  for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))    {      tree expr;#ifndef OBJC_SELECTORS_WITHOUT_LABELS      sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx);      sc_spec = build_tree_list (NULLT, ridpointers[(int) RID_STATIC]);      /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */      decl_specs = tree_cons (NULLT, selector_type, sc_spec);      var_decl = get_identifier (buf);      /* the `decl' that is returned from start_decl is the one that we	* forward declared in `build_selector_reference()'	*/      decl = start_decl (var_decl, decl_specs, 1); #endif      expr = init_selector (offset);      /* add one for the '\0' character */      offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;#ifndef OBJC_SELECTORS_WITHOUT_LABELS      finish_decl (decl, expr, NULLT);      idx++;#else      initlist = tree_cons (NULLT, expr, initlist);#endif    }#ifdef OBJC_SELECTORS_WITHOUT_LABELS  /* Cause the variable and its initial value to be actually output.  */  DECL_EXTERNAL (_OBJC_SELECTOR_REFERENCES_decl) = 0;  TREE_STATIC (_OBJC_SELECTOR_REFERENCES_decl) = 1;  /* NULL terminate the list and fix the decl for output. */  initlist = tree_cons (NULLT, build_int_2 (0, 0), initlist);  DECL_INITIAL (_OBJC_SELECTOR_REFERENCES_decl) = (tree) 1;  initlist = build_nt (CONSTRUCTOR, NULLT, nreverse (initlist));  finish_decl (_OBJC_SELECTOR_REFERENCES_decl, initlist, NULLT);#endif}static voidadd_class_reference (ident)     tree ident;{  tree chain;  if (chain = cls_ref_chain)    {      tree tail;      do        {	  if (ident == TREE_VALUE (chain))	    return;	  tail = chain;	  chain = TREE_CHAIN (chain);        }      while (chain);      /* append to the end of the list */      TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);    }  else    cls_ref_chain = perm_tree_cons (NULLT, ident, NULLT);}/* * sel_ref_chain is a list whose "value" fields will be instances of * identifier_node that represent the selector. */static intadd_selector_reference (ident)     tree ident;{  tree chain;  int index = 0;  /* this adds it to sel_refdef_chain, the global pool of selectors */  add_objc_string (ident);  if (chain = sel_ref_chain)    {      tree tail;      do        {	  if (ident == TREE_VALUE (chain))	    return index;	  index++;	  tail = chain;	  chain = TREE_CHAIN (chain);        }      while (chain);      /* append to the end of the list */      TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);    }  else    sel_ref_chain = perm_tree_cons (NULLT, ident, NULLT);  max_selector_index++;  return index;}/* * sel_refdef_chain is a list whose "value" fields will be instances of * identifier_node that represent the selector. It returns the offset of * the selector from the beginning of the _OBJC_STRINGS pool. This offset * is typically used by "init_selector ()" during code generation. */static intadd_objc_string (ident)     tree ident;{  tree chain;  int offset = 0;  if (chain = sel_refdef_chain)    {      tree tail;      do        {	  if (ident == TREE_VALUE (chain))	    return offset;	  /* add one for the '\0' character */	  offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;	  tail = chain;	  chain = TREE_CHAIN (chain);        }      while (chain);      /* append to the end of the list */      TREE_CHAIN (tail) = perm_tree_cons (NULLT, ident, NULLT);    }  else    sel_refdef_chain = perm_tree_cons (NULLT, ident, NULLT);  return offset;}treelookup_interface (ident)     tree ident;{  tree chain;  for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))    {      if (ident == CLASS_NAME (chain))	return chain;    }  return NULLT;}static treeobjc_copy_list (list, head)     tree list;     tree *head;{  tree newlist = NULL_TREE, tail = NULL_TREE;  while (list)    {      tail = copy_node (list);      /* the following statement fixes a bug when inheriting instance	 variables that are declared to be bitfields. finish_struct () expects	 to find the width of the bitfield in DECL_INITIAL (), which it	 nulls out after processing the decl of the super class...rather	 than change the way finish_struct () works (which is risky),	 I create the situation it expects...s.naroff (7/23/89).	 */      if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)	DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0);      newlist = chainon (newlist, tail);      list = TREE_CHAIN (list);    }  *head = newlist;  return tail;}/* used by: * build_private_template (), get_class_ivars (), and get_static_reference (). */static treebuild_ivar_chain (interface)     tree interface;{  tree my_name, super_name, ivar_chain;  my_name = CLASS_NAME (interface);  super_name = CLASS_SUPER_NAME (interface);  /* "leaf" ivars never get copied...there is no reason to. */  ivar_chain = CLASS_IVARS (interface);  while (super_name)    {      tree op1;      tree super_interface = lookup_interface (super_name);      if (!super_interface)        {	  /* fatal did not work with 2 args...should fix */	  error ("Cannot find interface declaration for `%s', superclass of `%s'",		 IDENTIFIER_POINTER (super_name), IDENTIFIER_POINTER (my_name));	  exit (34);        }      if (super_interface == interface)        {          fatal ("Circular inheritance in interface declaration for `%s'",                 IDENTIFIER_POINTER (super_name));        }      interface = super_interface;      my_name = CLASS_NAME (interface);      super_name = CLASS_SUPER_NAME (interface);      op1 = CLASS_IVARS (interface);      if (op1)        {	  tree head, tail = objc_copy_list (op1, &head);	  /* prepend super class ivars...make a copy of the list, we	   * do not want to alter the original.	   */	  TREE_CHAIN (tail) = ivar_chain;	  ivar_chain = head;        }    }  return ivar_chain;}/* *  struct <classname> { *    struct objc_class *isa; *    ... *  }; */static treebuild_private_template (class)     tree class;{  tree ivar_context;  if (CLASS_STATIC_TEMPLATE (class))    {      _PRIVATE_record = CLASS_STATIC_TEMPLATE (class);      ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));    }  else    {      _PRIVATE_record = start_struct (RECORD_TYPE, CLASS_NAME (class));      ivar_context = build_ivar_chain (class);      finish_struct (_PRIVATE_record, ivar_context);      CLASS_STATIC_TEMPLATE (class) = _PRIVATE_record;      /* mark this record as class template - for class type checking */      TREE_STATIC_TEMPLATE (_PRIVATE_record) = 1;    }  instance_type = groktypename (				build_tree_list (build_tree_list (NULLT, _PRIVATE_record),						 build1 (INDIRECT_REF, NULLT, NULLT)));  return ivar_context;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -