📄 edsel.c
字号:
/* Interface to LUCID Cadillac system for GNU compiler. Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. */#include "config.h"#include "tree.h"#include "flags.h"#include <stdio.h>#include "cp-tree.h"#include "obstack.h"#ifdef CADILLAC#include <compilerreq.h>#include <compilerconn.h>#include <sys/time.h>#include <sys/types.h>#include <errno.h>#include <sys/file.h>#define obstack_chunk_alloc xmalloc#define obstack_chunk_free freevoid init_cadillac ();extern char *input_filename;extern int lineno;/* Put random information we might want to get back from Cadillac here. */typedef struct{ /* The connection to the Cadillac kernel. */ Connection *conn; /* Input and output file descriptors for Cadillac. */ short fd_input, fd_output; /* #include nesting of current file. */ short depth; /* State variables for the connection. */ char messages; char conversion; char emission; char process_until; /* #if level of current file. */ int iflevel; /* Line number that starts current source file. */ int lineno; /* Name of current file. */ char *filename; /* Where to stop processing (if process_until is set). */ char *end_filename; int end_position;} cadillac_struct;static cadillac_struct cadillacObj;/* Nonzero if in the process of exiting. */static int exiting;void cadillac_note_source ();static void CWriteLanguageDecl ();static void CWriteLanguageType ();static void CWriteTopLevel ();static void cadillac_note_filepos ();static void cadillac_process_request (), cadillac_process_requests ();static void cadillac_switch_source ();static void exit_cadillac ();/* Blocking test. */static intreadable_p (fd) int fd;{ fd_set f; FD_ZERO (&f); FD_SET (fd, &f); return select (32, &f, NULL, NULL, 0) == 1;}static CObjectType *tree_to_cadillac_map;struct obstack cadillac_obstack;#include "stack.h"struct context_level{ struct stack_level base; tree context;};/* Stack for maintaining contexts (in case functions or types are nested). When defining a struct type, the `context' field is the RECORD_TYPE. When defining a function, the `context' field is the FUNCTION_DECL. */static struct context_level *context_stack;static struct context_level *push_context_level (stack, obstack) struct stack_level *stack; struct obstack *obstack;{ struct context_level tem; tem.base.prev = stack; return (struct context_level *)push_stack_level (obstack, &tem, sizeof (tem));}/* Discard a level of search allocation. */static struct context_level *pop_context_level (stack) struct context_level *stack;{ stack = (struct context_level *)pop_stack_level (stack); return stack;}voidinit_cadillac (){ extern FILE *finput; extern int errno; CCompilerMessage* req; cadillac_struct *cp = &cadillacObj; int i; if (! flag_cadillac) return; tree_to_cadillac_map = (CObjectType*) xmalloc (sizeof (CObjectType) * LAST_CPLUS_TREE_CODE); for (i = 0; i < LAST_CPLUS_TREE_CODE; i++) tree_to_cadillac_map[i] = MiscOType; tree_to_cadillac_map[RECORD_TYPE] = StructOType; tree_to_cadillac_map[UNION_TYPE] = UnionOType; tree_to_cadillac_map[ENUMERAL_TYPE] = EnumTypeOType; tree_to_cadillac_map[TYPE_DECL] = TypedefOType; tree_to_cadillac_map[VAR_DECL] = VariableOType; tree_to_cadillac_map[CONST_DECL] = EnumConstantOType; tree_to_cadillac_map[FUNCTION_DECL] = FunctionOType; tree_to_cadillac_map[FIELD_DECL] = FieldOType;#ifdef sun on_exit (&exit_cadillac, 0);#endif gcc_obstack_init (&cadillac_obstack); /* Yow! This is the way Cadillac was designed to deal with Oregon C++ compiler! */ cp->fd_input = flag_cadillac; cp->fd_output = flag_cadillac; /* Start in "turned-on" state. */ cp->messages = 1; cp->conversion = 1; cp->emission = 1; /* Establish a connection with Cadillac here. */ cp->conn = NewConnection (cp, cp->fd_input, cp->fd_output); CWriteHeader (cp->conn, WaitingMType, 0); CWriteRequestBuffer (cp->conn); if (!readable_p (cp->fd_input)) ; req = CReadCompilerMessage (cp->conn); if (!req) switch (errno) { case EWOULDBLOCK: sleep (5); return; case 0: fatal ("init_cadillac: EOF on connection to kernel, exiting\n"); break; default: perror ("Editor to kernel connection"); exit (0); }}static voidcadillac_process_requests (conn) Connection *conn;{ CCompilerMessage *req; while (req = (CCompilerMessage*) CPeekNextRequest (conn)) { req = CReadCompilerMessage (conn); cadillac_process_request (&cadillacObj, req); }}static voidcadillac_process_request (cp, req) cadillac_struct *cp; CCompilerMessage *req;{ if (! req) return; switch (req->reqType) { case ProcessUntilMType: if (cp->process_until) my_friendly_abort (23); cp->process_until = 1; /* This is not really right. */ cp->end_position = ((CCompilerCommand*)req)->processuntil.position;#if 0 cp->end_filename = req->processuntil.filename;#endif break; case CommandMType: switch (req->header.data) { case MessagesOnCType: cp->messages = 1; break; case MessagesOffCType: cp->messages = 0; break; case ConversionOnCType: cp->conversion = 1; break; case ConversionOffCType: cp->conversion = 0; break; case EmissionOnCType: cp->emission = 1; break; case EmissionOffCType: cp->emission = 0; break; case FinishAnalysisCType: return; case PuntAnalysisCType: case ContinueAnalysisCType: case GotoFileposCType: case OpenSucceededCType: case OpenFailedCType: fprintf (stderr, "request type %d not implemented\n", req->reqType); return; case DieCType: if (! exiting) my_friendly_abort (24); return; } break; default: fatal ("unknown request type %d", req->reqType); }}voidcadillac_start (){ Connection *conn = cadillacObj.conn; CCompilerMessage *req; /* Let Cadillac know that we start in C++ language scope. */ CWriteHeader (conn, ForeignLinkageMType, LinkCPlus); CWriteLength (conn); CWriteRequestBuffer (conn); cadillac_process_requests (conn);}static voidcadillac_printf (msg, name){ if (cadillacObj.messages) printf ("[%s,%4d] %s `%s'\n", input_filename, lineno, msg, name);}voidcadillac_start_decl (decl) tree decl;{ Connection *conn = cadillacObj.conn; CObjectType object_type = tree_to_cadillac_map [TREE_CODE (decl)]; if (context_stack) switch (TREE_CODE (context_stack->context)) { case FUNCTION_DECL: /* Currently, cadillac only implements top-level forms. */ return; case RECORD_TYPE: case UNION_TYPE: cadillac_printf ("start class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl))); break; default: my_friendly_abort (25); } else { cadillac_printf ("start top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); CWriteTopLevel (conn, StartMType); } CWriteLanguageDecl (conn, decl, tree_to_cadillac_map[TREE_CODE (decl)]); CWriteRequestBuffer (conn); cadillac_process_requests (conn);}voidcadillac_finish_decl (decl) tree decl;{ Connection *conn = cadillacObj.conn; if (context_stack) switch (TREE_CODE (context_stack->context)) { case FUNCTION_DECL: return; case RECORD_TYPE: case UNION_TYPE: cadillac_printf ("end class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl))); CWriteHeader (conn, EndDefMType, 0); CWriteLength (conn); break; default: my_friendly_abort (26); } else { cadillac_printf ("end top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); CWriteHeader (conn, EndDefMType, 0); CWriteLength (conn); CWriteTopLevel (conn, StopMType); } CWriteRequestBuffer (conn); cadillac_process_requests (conn);}voidcadillac_start_function (fndecl) tree fndecl;{ Connection *conn = cadillacObj.conn; if (context_stack) /* nested functions not yet handled. */ my_friendly_abort (27); cadillac_printf ("start top-level function", lang_printable_name (fndecl)); context_stack = push_context_level (context_stack, &cadillac_obstack); context_stack->context = fndecl; CWriteTopLevel (conn, StartMType); my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 202); CWriteLanguageDecl (conn, fndecl, (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE ? MemberFnOType : FunctionOType)); CWriteRequestBuffer (conn); cadillac_process_requests (conn);}voidcadillac_finish_function (fndecl) tree fndecl;{ Connection *conn = cadillacObj.conn; cadillac_printf ("end top-level function", lang_printable_name (fndecl)); context_stack = pop_context_level (context_stack); if (context_stack) /* nested functions not yet implemented. */ my_friendly_abort (28); CWriteHeader (conn, EndDefMType, 0); CWriteLength (conn); CWriteTopLevel (conn, StopMType); CWriteRequestBuffer (conn); cadillac_process_requests (conn);}voidcadillac_finish_anon_union (decl) tree decl;{ Connection *conn = cadillacObj.conn; if (! global_bindings_p ()) return; cadillac_printf ("finish top-level anon union", ""); CWriteHeader (conn, EndDefMType, 0); CWriteLength (conn); CWriteTopLevel (conn, StopMType); CWriteRequestBuffer (conn); cadillac_process_requests (conn);}voidcadillac_start_enum (type) tree type;{ Connection *conn = cadillacObj.conn; tree name = TYPE_NAME (type); if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); if (context_stack) switch (TREE_CODE (context_stack->context)) { case FUNCTION_DECL: return; case RECORD_TYPE: case UNION_TYPE: break; default: my_friendly_abort (29); } else { cadillac_printf ("start top-level enum", IDENTIFIER_POINTER (name)); CWriteTopLevel (conn, StartMType); } CWriteLanguageType (conn, type, tree_to_cadillac_map[ENUMERAL_TYPE]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -