home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
gnu
/
gcc-2.3.3-src.lha
/
GNU
/
src
/
amiga
/
gcc-2.3.3
/
cp-edsel.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-06
|
20KB
|
928 lines
/* Interface to LUCID Cadillac system for GNU compiler.
Copyright (C) 1988, 1992 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 free
void 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 int
readable_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;
}
void
init_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 void
cadillac_process_requests (conn)
Connection *conn;
{
CCompilerMessage *req;
while (req = (CCompilerMessage*) CPeekNextRequest (conn))
{
req = CReadCompilerMessage (conn);
cadillac_process_request (&cadillacObj, req);
}
}
static void
cadillac_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);
}
}
void
cadillac_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 void
cadillac_printf (msg, name)
{
if (cadillacObj.messages)
printf ("[%s,%4d] %s `%s'\n", input_filename, lineno, msg, name);
}
void
cadillac_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);
}
void
cadillac_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", IDEN