1 /* Interface to LUCID Cadillac system for GNU compiler.
2 Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
30 #include <compilerreq.h>
31 #include <compilerconn.h>
33 #include <sys/types.h>
37 #define obstack_chunk_alloc xmalloc
38 #define obstack_chunk_free free
40 void init_cadillac ();
42 extern char *input_filename;
45 /* Put random information we might want to get back from
49 /* The connection to the Cadillac kernel. */
52 /* Input and output file descriptors for Cadillac. */
53 short fd_input, fd_output;
55 /* #include nesting of current file. */
58 /* State variables for the connection. */
64 /* #if level of current file. */
67 /* Line number that starts current source file. */
70 /* Name of current file. */
73 /* Where to stop processing (if process_until is set). */
78 static cadillac_struct cadillacObj;
80 /* Nonzero if in the process of exiting. */
83 void cadillac_note_source ();
84 static void CWriteLanguageDecl ();
85 static void CWriteLanguageType ();
86 static void CWriteTopLevel ();
87 static void cadillac_note_filepos ();
88 static void cadillac_process_request (), cadillac_process_requests ();
89 static void cadillac_switch_source ();
90 static void exit_cadillac ();
102 return select (32, &f, NULL, NULL, 0) == 1;
105 static CObjectType *tree_to_cadillac_map;
106 struct obstack cadillac_obstack;
113 struct stack_level base;
118 /* Stack for maintaining contexts (in case functions or types are nested).
119 When defining a struct type, the `context' field is the RECORD_TYPE.
120 When defining a function, the `context' field is the FUNCTION_DECL. */
122 static struct context_level *context_stack;
124 static struct context_level *
125 push_context_level (stack, obstack)
126 struct stack_level *stack;
127 struct obstack *obstack;
129 struct context_level tem;
131 tem.base.prev = stack;
132 return (struct context_level *)push_stack_level (obstack, &tem, sizeof (tem));
135 /* Discard a level of search allocation. */
137 static struct context_level *
138 pop_context_level (stack)
139 struct context_level *stack;
141 stack = (struct context_level *)pop_stack_level (stack);
150 CCompilerMessage* req;
151 cadillac_struct *cp = &cadillacObj;
157 tree_to_cadillac_map = (CObjectType*) xmalloc (sizeof (CObjectType) * LAST_CPLUS_TREE_CODE);
158 for (i = 0; i < LAST_CPLUS_TREE_CODE; i++)
159 tree_to_cadillac_map[i] = MiscOType;
160 tree_to_cadillac_map[RECORD_TYPE] = StructOType;
161 tree_to_cadillac_map[UNION_TYPE] = UnionOType;
162 tree_to_cadillac_map[ENUMERAL_TYPE] = EnumTypeOType;
163 tree_to_cadillac_map[TYPE_DECL] = TypedefOType;
164 tree_to_cadillac_map[VAR_DECL] = VariableOType;
165 tree_to_cadillac_map[CONST_DECL] = EnumConstantOType;
166 tree_to_cadillac_map[FUNCTION_DECL] = FunctionOType;
167 tree_to_cadillac_map[FIELD_DECL] = FieldOType;
170 on_exit (&exit_cadillac, 0);
173 gcc_obstack_init (&cadillac_obstack);
175 /* Yow! This is the way Cadillac was designed to deal with
176 Oregon C++ compiler! */
177 cp->fd_input = flag_cadillac;
178 cp->fd_output = flag_cadillac;
180 /* Start in "turned-on" state. */
185 /* Establish a connection with Cadillac here. */
186 cp->conn = NewConnection (cp, cp->fd_input, cp->fd_output);
188 CWriteHeader (cp->conn, WaitingMType, 0);
189 CWriteRequestBuffer (cp->conn);
191 if (!readable_p (cp->fd_input))
194 req = CReadCompilerMessage (cp->conn);
204 fatal ("init_cadillac: EOF on connection to kernel, exiting\n");
208 perror ("Editor to kernel connection");
214 cadillac_process_requests (conn)
217 CCompilerMessage *req;
218 while (req = (CCompilerMessage*) CPeekNextRequest (conn))
220 req = CReadCompilerMessage (conn);
221 cadillac_process_request (&cadillacObj, req);
226 cadillac_process_request (cp, req)
228 CCompilerMessage *req;
233 switch (req->reqType)
235 case ProcessUntilMType:
236 if (cp->process_until)
237 my_friendly_abort (23);
238 cp->process_until = 1;
239 /* This is not really right. */
240 cp->end_position = ((CCompilerCommand*)req)->processuntil.position;
242 cp->end_filename = req->processuntil.filename;
247 switch (req->header.data)
249 case MessagesOnCType:
252 case MessagesOffCType:
255 case ConversionOnCType:
258 case ConversionOffCType:
261 case EmissionOnCType:
264 case EmissionOffCType:
268 case FinishAnalysisCType:
271 case PuntAnalysisCType:
272 case ContinueAnalysisCType:
273 case GotoFileposCType:
274 case OpenSucceededCType:
275 case OpenFailedCType:
276 fprintf (stderr, "request type %d not implemented\n", req->reqType);
281 my_friendly_abort (24);
288 fatal ("unknown request type %d", req->reqType);
295 Connection *conn = cadillacObj.conn;
296 CCompilerMessage *req;
298 /* Let Cadillac know that we start in C++ language scope. */
299 CWriteHeader (conn, ForeignLinkageMType, LinkCPlus);
301 CWriteRequestBuffer (conn);
303 cadillac_process_requests (conn);
307 cadillac_printf (msg, name)
309 if (cadillacObj.messages)
310 printf ("[%s,%4d] %s `%s'\n", input_filename, lineno, msg, name);
314 cadillac_start_decl (decl)
317 Connection *conn = cadillacObj.conn;
318 CObjectType object_type = tree_to_cadillac_map [TREE_CODE (decl)];
321 switch (TREE_CODE (context_stack->context))
324 /* Currently, cadillac only implements top-level forms. */
328 cadillac_printf ("start class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl)));
331 my_friendly_abort (25);
335 cadillac_printf ("start top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
336 CWriteTopLevel (conn, StartMType);
339 CWriteLanguageDecl (conn, decl, tree_to_cadillac_map[TREE_CODE (decl)]);
340 CWriteRequestBuffer (conn);
341 cadillac_process_requests (conn);
345 cadillac_finish_decl (decl)
348 Connection *conn = cadillacObj.conn;
351 switch (TREE_CODE (context_stack->context))
357 cadillac_printf ("end class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl)));
358 CWriteHeader (conn, EndDefMType, 0);
362 my_friendly_abort (26);
366 cadillac_printf ("end top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
367 CWriteHeader (conn, EndDefMType, 0);
369 CWriteTopLevel (conn, StopMType);
372 CWriteRequestBuffer (conn);
373 cadillac_process_requests (conn);
377 cadillac_start_function (fndecl)
380 Connection *conn = cadillacObj.conn;
383 /* nested functions not yet handled. */
384 my_friendly_abort (27);
386 cadillac_printf ("start top-level function", lang_printable_name (fndecl));
387 context_stack = push_context_level (context_stack, &cadillac_obstack);
388 context_stack->context = fndecl;
390 CWriteTopLevel (conn, StartMType);
391 my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 202);
392 CWriteLanguageDecl (conn, fndecl,
393 (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
394 ? MemberFnOType : FunctionOType));
395 CWriteRequestBuffer (conn);
396 cadillac_process_requests (conn);
400 cadillac_finish_function (fndecl)
403 Connection *conn = cadillacObj.conn;
405 cadillac_printf ("end top-level function", lang_printable_name (fndecl));
406 context_stack = pop_context_level (context_stack);
409 /* nested functions not yet implemented. */
410 my_friendly_abort (28);
412 CWriteHeader (conn, EndDefMType, 0);
414 CWriteTopLevel (conn, StopMType);
415 CWriteRequestBuffer (conn);
416 cadillac_process_requests (conn);
420 cadillac_finish_anon_union (decl)
423 Connection *conn = cadillacObj.conn;
425 if (! global_bindings_p ())
427 cadillac_printf ("finish top-level anon union", "");
428 CWriteHeader (conn, EndDefMType, 0);
430 CWriteTopLevel (conn, StopMType);
431 CWriteRequestBuffer (conn);
432 cadillac_process_requests (conn);
436 cadillac_start_enum (type)
439 Connection *conn = cadillacObj.conn;
441 tree name = TYPE_NAME (type);
443 if (TREE_CODE (name) == TYPE_DECL)
444 name = DECL_NAME (name);
447 switch (TREE_CODE (context_stack->context))
455 my_friendly_abort (29);
459 cadillac_printf ("start top-level enum", IDENTIFIER_POINTER (name));
460 CWriteTopLevel (conn, StartMType);
463 CWriteLanguageType (conn, type, tree_to_cadillac_map[ENUMERAL_TYPE]);
467 cadillac_finish_enum (type)
470 Connection *conn = cadillacObj.conn;
471 tree name = TYPE_NAME (type);
473 if (TREE_CODE (name) == TYPE_DECL)
474 name = DECL_NAME (name);
477 switch (TREE_CODE (context_stack->context))
483 CWriteHeader (conn, EndDefMType, 0);
487 my_friendly_abort (30);
491 CWriteHeader (conn, EndDefMType, 0);
493 cadillac_printf ("finish top-level enum", IDENTIFIER_POINTER (name));
494 CWriteTopLevel (conn, StopMType);
497 CWriteRequestBuffer (conn);
498 cadillac_process_requests (conn);
502 cadillac_start_struct (type)
505 Connection *conn = cadillacObj.conn;
506 tree name = TYPE_NAME (type);
508 if (TREE_CODE (name) == TYPE_DECL)
509 name = DECL_NAME (name);
512 switch (TREE_CODE (context_stack->context))
520 my_friendly_abort (31);
524 cadillac_printf ("start struct", IDENTIFIER_POINTER (name));
525 CWriteTopLevel (conn, StartMType);
528 context_stack = push_context_level (context_stack, &cadillac_obstack);
529 context_stack->context = type;
531 CWriteLanguageType (conn, type,
532 TYPE_LANG_SPECIFIC (type) && CLASSTYPE_DECLARED_CLASS (type) ? ClassOType : tree_to_cadillac_map[TREE_CODE (type)]);
536 cadillac_finish_struct (type)
539 Connection *conn = cadillacObj.conn;
540 tree name = TYPE_NAME (type);
542 if (TREE_CODE (name) == TYPE_DECL)
543 name = DECL_NAME (name);
545 context_stack = pop_context_level (context_stack);
549 cadillac_printf ("finish struct", IDENTIFIER_POINTER (name));
550 CWriteHeader (conn, EndDefMType, 0);
552 CWriteTopLevel (conn, StopMType);
553 CWriteRequestBuffer (conn);
554 cadillac_process_requests (conn);
558 cadillac_finish_exception (type)
561 Connection *conn = cadillacObj.conn;
563 fatal ("cadillac_finish_exception");
564 CWriteHeader (conn, EndDefMType, 0);
566 CWriteTopLevel (conn, StopMType);
567 CWriteRequestBuffer (conn);
568 cadillac_process_requests (conn);
572 cadillac_push_class (type)
578 cadillac_pop_class ()
583 cadillac_push_lang (name)
586 Connection *conn = cadillacObj.conn;
589 if (name == lang_name_cplusplus)
591 else if (name == lang_name_c)
594 my_friendly_abort (32);
595 CWriteHeader (conn, ForeignLinkageMType, m);
596 CWriteRequestBuffer (conn);
597 cadillac_process_requests (conn);
603 Connection *conn = cadillacObj.conn;
605 CWriteHeader (conn, ForeignLinkageMType, LinkPop);
606 CWriteRequestBuffer (conn);
607 cadillac_process_requests (conn);
611 cadillac_finish_stmt ()
616 cadillac_note_source ()
618 cadillacObj.lineno = lineno;
619 cadillacObj.filename = input_filename;
623 CWriteTopLevel (conn, m)
627 static context_id = 0;
628 CWriteHeader (conn, TopLevelFormMType, m);
629 cadillac_note_filepos ();
631 /* Eventually, this will point somewhere into the digest file. */
633 CWriteSomething (conn, &context_id, sizeof (BITS32));
635 CWriteSomething (conn, &cadillacObj.iflevel, sizeof (BITS32));
640 cadillac_note_filepos ()
643 int pos = ftell (finput);
644 CWriteSomething (cadillacObj.conn, &pos, sizeof (BITS32));
648 cadillac_switch_source (startflag)
651 Connection *conn = cadillacObj.conn;
652 /* Send out the name of the source file being compiled. */
654 CWriteHeader (conn, SourceFileMType, startflag ? StartMType : StopMType);
655 CWriteSomething (conn, &cadillacObj.depth, sizeof (BITS16));
656 CWriteVstring0 (conn, input_filename);
658 CWriteRequestBuffer (conn);
659 cadillac_process_requests (conn);
663 cadillac_push_source ()
665 cadillacObj.depth += 1;
666 cadillac_switch_source (1);
670 cadillac_pop_source ()
672 cadillacObj.depth -= 1;
673 cadillac_switch_source (0);
685 CWriteLanguageElem (conn, p, name)
687 struct cadillac_mdep *p;
690 CWriteSomething (conn, &p->object_type, sizeof (BITS16));
691 CWriteSomething (conn, &p->linkage, sizeof (BITS8));
692 CWriteSomething (conn, &p->access, sizeof (BITS8));
693 CWriteSomething (conn, &p->length, sizeof (BITS16));
694 CWriteVstring0 (conn, name);
697 /* Don't write date_type. */
698 CWriteVstring0 (conn, "");
704 CWriteLanguageDecl (conn, decl, object_type)
707 CObjectType object_type;
709 struct cadillac_mdep foo;
712 CWriteHeader (conn, LanguageElementMType, StartDefineMType);
713 foo.object_type = object_type;
714 if (decl_type_context (decl))
716 foo.linkage = ParentLinkage;
717 if (TREE_PRIVATE (decl))
718 foo.access = PrivateAccess;
719 else if (TREE_PROTECTED (decl))
720 foo.access = ProtectedAccess;
722 foo.access = PublicAccess;
726 if (TREE_PUBLIC (decl))
727 foo.linkage = GlobalLinkage;
729 foo.linkage = FileLinkage;
730 foo.access = PublicAccess;
732 name = DECL_NAME (decl);
733 foo.length = IDENTIFIER_LENGTH (name);
735 CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name));
736 CWriteRequestBuffer (conn);
737 cadillac_process_requests (conn);
741 CWriteLanguageType (conn, type, object_type)
744 CObjectType object_type;
746 struct cadillac_mdep foo;
747 tree name = TYPE_NAME (type);
749 CWriteHeader (conn, LanguageElementMType, StartDefineMType);
750 foo.object_type = object_type;
751 if (current_class_type)
753 foo.linkage = ParentLinkage;
754 if (TREE_PRIVATE (type))
755 foo.access = PrivateAccess;
756 else if (TREE_PROTECTED (type))
757 foo.access = ProtectedAccess;
759 foo.access = PublicAccess;
763 foo.linkage = NoLinkage;
764 foo.access = PublicAccess;
766 if (TREE_CODE (name) == TYPE_DECL)
767 name = DECL_NAME (name);
769 foo.length = IDENTIFIER_LENGTH (name);
771 CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name));
772 CWriteRequestBuffer (conn);
773 cadillac_process_requests (conn);
777 CWriteUseObject (conn, type, object_type, use)
780 CObjectType object_type;
783 struct cadillac_mdep foo;
784 tree name = NULL_TREE;
786 CWriteHeader (conn, LanguageElementMType, use);
787 foo.object_type = object_type;
788 if (current_class_type)
790 foo.linkage = ParentLinkage;
791 if (TREE_PRIVATE (type))
792 foo.access = PrivateAccess;
793 else if (TREE_PROTECTED (type))
794 foo.access = ProtectedAccess;
796 foo.access = PublicAccess;
800 foo.linkage = NoLinkage;
801 foo.access = PublicAccess;
803 switch (TREE_CODE (type))
810 name = DECL_NAME (type);
814 my_friendly_abort (33);
817 foo.length = IDENTIFIER_LENGTH (name);
819 CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name));
820 CWriteRequestBuffer (conn);
821 cadillac_process_requests (conn);
824 /* Here's how we exit under cadillac. */
829 extern int errorcount;
831 Connection *conn = cadillacObj.conn;
835 CCompilerMessage *req;
837 CWriteHeader (conn, FinishedMType,
838 errorcount ? 0 : CsObjectWritten | CsComplete);
840 CWriteRequestBuffer (conn);
843 while (! readable_p (cadillacObj.fd_input))
846 my_friendly_abort (34);
851 req = CReadCompilerMessage (conn);
852 cadillac_process_request (&cadillacObj, req);
858 void init_cadillac () {}
859 void cadillac_start () {}
860 void cadillac_start_decl (decl)
864 cadillac_finish_decl (decl)
868 cadillac_start_function (fndecl)
872 cadillac_finish_function (fndecl)
876 cadillac_finish_anon_union (decl)
880 cadillac_start_enum (type)
884 cadillac_finish_enum (type)
888 cadillac_start_struct (type)
892 cadillac_finish_struct (type)
896 cadillac_finish_exception (type)
900 cadillac_push_class (type)
904 cadillac_pop_class ()
907 cadillac_push_lang (name)
914 cadillac_note_source ()
917 cadillac_finish_stmt ()
920 cadillac_switch_source ()
923 cadillac_push_source ()
926 cadillac_pop_source ()