Commit | Line | Data |
---|---|---|
d60bb9a0 C |
1 | /* Interface to LUCID Cadillac system for GNU compiler. |
2 | Copyright (C) 1988, 1992 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GNU CC. | |
5 | ||
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) | |
9 | any later version. | |
10 | ||
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. | |
15 | ||
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, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | ||
20 | #include "config.h" | |
21 | ||
22 | #include "tree.h" | |
23 | #include "flags.h" | |
24 | #include <stdio.h> | |
25 | #include "cp-tree.h" | |
26 | #include "obstack.h" | |
27 | ||
28 | #ifdef CADILLAC | |
29 | #include <compilerreq.h> | |
30 | #include <compilerconn.h> | |
31 | #include <sys/time.h> | |
32 | #include <sys/types.h> | |
33 | #include <errno.h> | |
34 | #include <sys/file.h> | |
35 | ||
36 | #define obstack_chunk_alloc xmalloc | |
37 | #define obstack_chunk_free free | |
38 | ||
39 | void init_cadillac (); | |
40 | ||
41 | extern char *input_filename; | |
42 | extern int lineno; | |
43 | ||
44 | /* Put random information we might want to get back from | |
45 | Cadillac here. */ | |
46 | typedef struct | |
47 | { | |
48 | /* The connection to the Cadillac kernel. */ | |
49 | Connection *conn; | |
50 | ||
51 | /* Input and output file descriptors for Cadillac. */ | |
52 | short fd_input, fd_output; | |
53 | ||
54 | /* #include nesting of current file. */ | |
55 | short depth; | |
56 | ||
57 | /* State variables for the connection. */ | |
58 | char messages; | |
59 | char conversion; | |
60 | char emission; | |
61 | char process_until; | |
62 | ||
63 | /* #if level of current file. */ | |
64 | int iflevel; | |
65 | ||
66 | /* Line number that starts current source file. */ | |
67 | int lineno; | |
68 | ||
69 | /* Name of current file. */ | |
70 | char *filename; | |
71 | ||
72 | /* Where to stop processing (if process_until is set). */ | |
73 | char *end_filename; | |
74 | int end_position; | |
75 | ||
76 | } cadillac_struct; | |
77 | static cadillac_struct cadillacObj; | |
78 | ||
79 | /* Nonzero if in the process of exiting. */ | |
80 | static int exiting; | |
81 | ||
82 | void cadillac_note_source (); | |
83 | static void CWriteLanguageDecl (); | |
84 | static void CWriteLanguageType (); | |
85 | static void CWriteTopLevel (); | |
86 | static void cadillac_note_filepos (); | |
87 | static void cadillac_process_request (), cadillac_process_requests (); | |
88 | static void cadillac_switch_source (); | |
89 | static void exit_cadillac (); | |
90 | ||
91 | /* Blocking test. */ | |
92 | static int | |
93 | readable_p (fd) | |
94 | int fd; | |
95 | { | |
96 | fd_set f; | |
97 | ||
98 | FD_ZERO (&f); | |
99 | FD_SET (fd, &f); | |
100 | ||
101 | return select (32, &f, NULL, NULL, 0) == 1; | |
102 | } | |
103 | ||
104 | static CObjectType *tree_to_cadillac_map; | |
105 | struct obstack cadillac_obstack; | |
106 | ||
107 | \f | |
108 | #include "stack.h" | |
109 | ||
110 | struct context_level | |
111 | { | |
112 | struct stack_level base; | |
113 | ||
114 | tree context; | |
115 | }; | |
116 | ||
117 | /* Stack for maintaining contexts (in case functions or types are nested). | |
118 | When defining a struct type, the `context' field is the RECORD_TYPE. | |
119 | When defining a function, the `context' field is the FUNCTION_DECL. */ | |
120 | ||
121 | static struct context_level *context_stack; | |
122 | ||
123 | static struct context_level * | |
124 | push_context_level (stack, obstack) | |
125 | struct stack_level *stack; | |
126 | struct obstack *obstack; | |
127 | { | |
128 | struct context_level tem; | |
129 | ||
130 | tem.base.prev = stack; | |
131 | return (struct context_level *)push_stack_level (obstack, &tem, sizeof (tem)); | |
132 | } | |
133 | ||
134 | /* Discard a level of search allocation. */ | |
135 | ||
136 | static struct context_level * | |
137 | pop_context_level (stack) | |
138 | struct context_level *stack; | |
139 | { | |
140 | stack = (struct context_level *)pop_stack_level (stack); | |
141 | return stack; | |
142 | } | |
143 | ||
144 | void | |
145 | init_cadillac () | |
146 | { | |
147 | extern FILE *finput; | |
148 | extern int errno; | |
149 | CCompilerMessage* req; | |
150 | cadillac_struct *cp = &cadillacObj; | |
151 | int i; | |
152 | ||
153 | if (! flag_cadillac) | |
154 | return; | |
155 | ||
156 | tree_to_cadillac_map = (CObjectType*) xmalloc (sizeof (CObjectType) * LAST_CPLUS_TREE_CODE); | |
157 | for (i = 0; i < LAST_CPLUS_TREE_CODE; i++) | |
158 | tree_to_cadillac_map[i] = MiscOType; | |
159 | tree_to_cadillac_map[RECORD_TYPE] = StructOType; | |
160 | tree_to_cadillac_map[UNION_TYPE] = UnionOType; | |
161 | tree_to_cadillac_map[ENUMERAL_TYPE] = EnumTypeOType; | |
162 | tree_to_cadillac_map[TYPE_DECL] = TypedefOType; | |
163 | tree_to_cadillac_map[VAR_DECL] = VariableOType; | |
164 | tree_to_cadillac_map[CONST_DECL] = EnumConstantOType; | |
165 | tree_to_cadillac_map[FUNCTION_DECL] = FunctionOType; | |
166 | tree_to_cadillac_map[FIELD_DECL] = FieldOType; | |
167 | ||
168 | #ifdef sun | |
169 | on_exit (&exit_cadillac, 0); | |
170 | #endif | |
171 | ||
172 | gcc_obstack_init (&cadillac_obstack); | |
173 | ||
174 | /* Yow! This is the way Cadillac was designed to deal with | |
175 | Oregon C++ compiler! */ | |
176 | cp->fd_input = flag_cadillac; | |
177 | cp->fd_output = flag_cadillac; | |
178 | ||
179 | /* Start in "turned-on" state. */ | |
180 | cp->messages = 1; | |
181 | cp->conversion = 1; | |
182 | cp->emission = 1; | |
183 | ||
184 | /* Establish a connection with Cadillac here. */ | |
185 | cp->conn = NewConnection (cp, cp->fd_input, cp->fd_output); | |
186 | ||
187 | CWriteHeader (cp->conn, WaitingMType, 0); | |
188 | CWriteRequestBuffer (cp->conn); | |
189 | ||
190 | if (!readable_p (cp->fd_input)) | |
191 | ; | |
192 | ||
193 | req = CReadCompilerMessage (cp->conn); | |
194 | ||
195 | if (!req) | |
196 | switch (errno) | |
197 | { | |
198 | case EWOULDBLOCK: | |
199 | sleep (5); | |
200 | return; | |
201 | ||
202 | case 0: | |
203 | fatal ("init_cadillac: EOF on connection to kernel, exiting\n"); | |
204 | break; | |
205 | ||
206 | default: | |
207 | perror ("Editor to kernel connection"); | |
208 | exit (0); | |
209 | } | |
210 | } | |
211 | ||
212 | static void | |
213 | cadillac_process_requests (conn) | |
214 | Connection *conn; | |
215 | { | |
216 | CCompilerMessage *req; | |
217 | while (req = (CCompilerMessage*) CPeekNextRequest (conn)) | |
218 | { | |
219 | req = CReadCompilerMessage (conn); | |
220 | cadillac_process_request (&cadillacObj, req); | |
221 | } | |
222 | } | |
223 | ||
224 | static void | |
225 | cadillac_process_request (cp, req) | |
226 | cadillac_struct *cp; | |
227 | CCompilerMessage *req; | |
228 | { | |
229 | if (! req) | |
230 | return; | |
231 | ||
232 | switch (req->reqType) | |
233 | { | |
234 | case ProcessUntilMType: | |
235 | if (cp->process_until) | |
236 | my_friendly_abort (23); | |
237 | cp->process_until = 1; | |
238 | /* This is not really right. */ | |
239 | cp->end_position = ((CCompilerCommand*)req)->processuntil.position; | |
240 | #if 0 | |
241 | cp->end_filename = req->processuntil.filename; | |
242 | #endif | |
243 | break; | |
244 | ||
245 | case CommandMType: | |
246 | switch (req->header.data) | |
247 | { | |
248 | case MessagesOnCType: | |
249 | cp->messages = 1; | |
250 | break; | |
251 | case MessagesOffCType: | |
252 | cp->messages = 0; | |
253 | break; | |
254 | case ConversionOnCType: | |
255 | cp->conversion = 1; | |
256 | break; | |
257 | case ConversionOffCType: | |
258 | cp->conversion = 0; | |
259 | break; | |
260 | case EmissionOnCType: | |
261 | cp->emission = 1; | |
262 | break; | |
263 | case EmissionOffCType: | |
264 | cp->emission = 0; | |
265 | break; | |
266 | ||
267 | case FinishAnalysisCType: | |
268 | return; | |
269 | ||
270 | case PuntAnalysisCType: | |
271 | case ContinueAnalysisCType: | |
272 | case GotoFileposCType: | |
273 | case OpenSucceededCType: | |
274 | case OpenFailedCType: | |
275 | fprintf (stderr, "request type %d not implemented\n", req->reqType); | |
276 | return; | |
277 | ||
278 | case DieCType: | |
279 | if (! exiting) | |
280 | my_friendly_abort (24); | |
281 | return; | |
282 | ||
283 | } | |
284 | break; | |
285 | ||
286 | default: | |
287 | fatal ("unknown request type %d", req->reqType); | |
288 | } | |
289 | } | |
290 | \f | |
291 | void | |
292 | cadillac_start () | |
293 | { | |
294 | Connection *conn = cadillacObj.conn; | |
295 | CCompilerMessage *req; | |
296 | ||
297 | /* Let Cadillac know that we start in C++ language scope. */ | |
298 | CWriteHeader (conn, ForeignLinkageMType, LinkCPlus); | |
299 | CWriteLength (conn); | |
300 | CWriteRequestBuffer (conn); | |
301 | ||
302 | cadillac_process_requests (conn); | |
303 | } | |
304 | ||
305 | static void | |
306 | cadillac_printf (msg, name) | |
307 | { | |
308 | if (cadillacObj.messages) | |
309 | printf ("[%s,%4d] %s `%s'\n", input_filename, lineno, msg, name); | |
310 | } | |
311 | ||
312 | void | |
313 | cadillac_start_decl (decl) | |
314 | tree decl; | |
315 | { | |
316 | Connection *conn = cadillacObj.conn; | |
317 | CObjectType object_type = tree_to_cadillac_map [TREE_CODE (decl)]; | |
318 | ||
319 | if (context_stack) | |
320 | switch (TREE_CODE (context_stack->context)) | |
321 | { | |
322 | case FUNCTION_DECL: | |
323 | /* Currently, cadillac only implements top-level forms. */ | |
324 | return; | |
325 | case RECORD_TYPE: | |
326 | case UNION_TYPE: | |
327 | cadillac_printf ("start class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl))); | |
328 | break; | |
329 | default: | |
330 | my_friendly_abort (25); | |
331 | } | |
332 | else | |
333 | { | |
334 | cadillac_printf ("start top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); | |
335 | CWriteTopLevel (conn, StartMType); | |
336 | } | |
337 | ||
338 | CWriteLanguageDecl (conn, decl, tree_to_cadillac_map[TREE_CODE (decl)]); | |
339 | CWriteRequestBuffer (conn); | |
340 | cadillac_process_requests (conn); | |
341 | } | |
342 | ||
343 | void | |
344 | cadillac_finish_decl (decl) | |
345 | tree decl; | |
346 | { | |
347 | Connection *conn = cadillacObj.conn; | |
348 | ||
349 | if (context_stack) | |
350 | switch (TREE_CODE (context_stack->context)) | |
351 | { | |
352 | case FUNCTION_DECL: | |
353 | return; | |
354 | case RECORD_TYPE: | |
355 | case UNION_TYPE: | |
356 | cadillac_printf ("end class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl))); | |
357 | CWriteHeader (conn, EndDefMType, 0); | |
358 | CWriteLength (conn); | |
359 | break; | |
360 | default: | |
361 | my_friendly_abort (26); | |
362 | } | |
363 | else | |
364 | { | |
365 | cadillac_printf ("end top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); | |
366 | CWriteHeader (conn, EndDefMType, 0); | |
367 | CWriteLength (conn); | |
368 | CWriteTopLevel (conn, StopMType); | |
369 | } | |
370 | ||
371 | CWriteRequestBuffer (conn); | |
372 | cadillac_process_requests (conn); | |
373 | } | |
374 | ||
375 | void | |
376 | cadillac_start_function (fndecl) | |
377 | tree fndecl; | |
378 | { | |
379 | Connection *conn = cadillacObj.conn; | |
380 | ||
381 | if (context_stack) | |
382 | /* nested functions not yet handled. */ | |
383 | my_friendly_abort (27); | |
384 | ||
385 | cadillac_printf ("start top-level function", lang_printable_name (fndecl)); | |
386 | context_stack = push_context_level (context_stack, &cadillac_obstack); | |
387 | context_stack->context = fndecl; | |
388 | ||
389 | CWriteTopLevel (conn, StartMType); | |
390 | my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 202); | |
391 | CWriteLanguageDecl (conn, fndecl, | |
392 | (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE | |
393 | ? MemberFnOType : FunctionOType)); | |
394 | CWriteRequestBuffer (conn); | |
395 | cadillac_process_requests (conn); | |
396 | } | |
397 | ||
398 | void | |
399 | cadillac_finish_function (fndecl) | |
400 | tree fndecl; | |
401 | { | |
402 | Connection *conn = cadillacObj.conn; | |
403 | ||
404 | cadillac_printf ("end top-level function", lang_printable_name (fndecl)); | |
405 | context_stack = pop_context_level (context_stack); | |
406 | ||
407 | if (context_stack) | |
408 | /* nested functions not yet implemented. */ | |
409 | my_friendly_abort (28); | |
410 | ||
411 | CWriteHeader (conn, EndDefMType, 0); | |
412 | CWriteLength (conn); | |
413 | CWriteTopLevel (conn, StopMType); | |
414 | CWriteRequestBuffer (conn); | |
415 | cadillac_process_requests (conn); | |
416 | } | |
417 | ||
418 | void | |
419 | cadillac_finish_anon_union (decl) | |
420 | tree decl; | |
421 | { | |
422 | Connection *conn = cadillacObj.conn; | |
423 | ||
424 | if (! global_bindings_p ()) | |
425 | return; | |
426 | cadillac_printf ("finish top-level anon union", ""); | |
427 | CWriteHeader (conn, EndDefMType, 0); | |
428 | CWriteLength (conn); | |
429 | CWriteTopLevel (conn, StopMType); | |
430 | CWriteRequestBuffer (conn); | |
431 | cadillac_process_requests (conn); | |
432 | } | |
433 | ||
434 | void | |
435 | cadillac_start_enum (type) | |
436 | tree type; | |
437 | { | |
438 | Connection *conn = cadillacObj.conn; | |
439 | ||
440 | tree name = TYPE_NAME (type); | |
441 | ||
442 | if (TREE_CODE (name) == TYPE_DECL) | |
443 | name = DECL_NAME (name); | |
444 | ||
445 | if (context_stack) | |
446 | switch (TREE_CODE (context_stack->context)) | |
447 | { | |
448 | case FUNCTION_DECL: | |
449 | return; | |
450 | case RECORD_TYPE: | |
451 | case UNION_TYPE: | |
452 | break; | |
453 | default: | |
454 | my_friendly_abort (29); | |
455 | } | |
456 | else | |
457 | { | |
458 | cadillac_printf ("start top-level enum", IDENTIFIER_POINTER (name)); | |
459 | CWriteTopLevel (conn, StartMType); | |
460 | } | |
461 | ||
462 | CWriteLanguageType (conn, type, tree_to_cadillac_map[ENUMERAL_TYPE]); | |
463 | } | |
464 | ||
465 | void | |
466 | cadillac_finish_enum (type) | |
467 | tree type; | |
468 | { | |
469 | Connection *conn = cadillacObj.conn; | |
470 | tree name = TYPE_NAME (type); | |
471 | ||
472 | if (TREE_CODE (name) == TYPE_DECL) | |
473 | name = DECL_NAME (name); | |
474 | ||
475 | if (context_stack) | |
476 | switch (TREE_CODE (context_stack->context)) | |
477 | { | |
478 | case FUNCTION_DECL: | |
479 | return; | |
480 | case RECORD_TYPE: | |
481 | case UNION_TYPE: | |
482 | CWriteHeader (conn, EndDefMType, 0); | |
483 | CWriteLength (conn); | |
484 | break; | |
485 | default: | |
486 | my_friendly_abort (30); | |
487 | } | |
488 | else | |
489 | { | |
490 | CWriteHeader (conn, EndDefMType, 0); | |
491 | CWriteLength (conn); | |
492 | cadillac_printf ("finish top-level enum", IDENTIFIER_POINTER (name)); | |
493 | CWriteTopLevel (conn, StopMType); | |
494 | } | |
495 | ||
496 | CWriteRequestBuffer (conn); | |
497 | cadillac_process_requests (conn); | |
498 | } | |
499 | ||
500 | void | |
501 | cadillac_start_struct (type) | |
502 | tree type; | |
503 | { | |
504 | Connection *conn = cadillacObj.conn; | |
505 | tree name = TYPE_NAME (type); | |
506 | ||
507 | if (TREE_CODE (name) == TYPE_DECL) | |
508 | name = DECL_NAME (name); | |
509 | ||
510 | if (context_stack) | |
511 | switch (TREE_CODE (context_stack->context)) | |
512 | { | |
513 | case FUNCTION_DECL: | |
514 | return; | |
515 | case RECORD_TYPE: | |
516 | case UNION_TYPE: | |
517 | return; | |
518 | default: | |
519 | my_friendly_abort (31); | |
520 | } | |
521 | else | |
522 | { | |
523 | cadillac_printf ("start struct", IDENTIFIER_POINTER (name)); | |
524 | CWriteTopLevel (conn, StartMType); | |
525 | } | |
526 | ||
527 | context_stack = push_context_level (context_stack, &cadillac_obstack); | |
528 | context_stack->context = type; | |
529 | ||
530 | CWriteLanguageType (conn, type, | |
531 | TYPE_LANG_SPECIFIC (type) && CLASSTYPE_DECLARED_CLASS (type) ? ClassOType : tree_to_cadillac_map[TREE_CODE (type)]); | |
532 | } | |
533 | ||
534 | void | |
535 | cadillac_finish_struct (type) | |
536 | tree type; | |
537 | { | |
538 | Connection *conn = cadillacObj.conn; | |
539 | tree name = TYPE_NAME (type); | |
540 | ||
541 | if (TREE_CODE (name) == TYPE_DECL) | |
542 | name = DECL_NAME (name); | |
543 | ||
544 | context_stack = pop_context_level (context_stack); | |
545 | if (context_stack) | |
546 | return; | |
547 | ||
548 | cadillac_printf ("finish struct", IDENTIFIER_POINTER (name)); | |
549 | CWriteHeader (conn, EndDefMType, 0); | |
550 | CWriteLength (conn); | |
551 | CWriteTopLevel (conn, StopMType); | |
552 | CWriteRequestBuffer (conn); | |
553 | cadillac_process_requests (conn); | |
554 | } | |
555 | ||
556 | void | |
557 | cadillac_finish_exception (type) | |
558 | tree type; | |
559 | { | |
560 | Connection *conn = cadillacObj.conn; | |
561 | ||
562 | fatal ("cadillac_finish_exception"); | |
563 | CWriteHeader (conn, EndDefMType, 0); | |
564 | CWriteLength (conn); | |
565 | CWriteTopLevel (conn, StopMType); | |
566 | CWriteRequestBuffer (conn); | |
567 | cadillac_process_requests (conn); | |
568 | } | |
569 | ||
570 | void | |
571 | cadillac_push_class (type) | |
572 | tree type; | |
573 | { | |
574 | } | |
575 | ||
576 | void | |
577 | cadillac_pop_class () | |
578 | { | |
579 | } | |
580 | ||
581 | void | |
582 | cadillac_push_lang (name) | |
583 | tree name; | |
584 | { | |
585 | Connection *conn = cadillacObj.conn; | |
586 | CLinkLanguageType m; | |
587 | ||
588 | if (name == lang_name_cplusplus) | |
589 | m = LinkCPlus; | |
590 | else if (name == lang_name_c) | |
591 | m = LinkC; | |
592 | else | |
593 | my_friendly_abort (32); | |
594 | CWriteHeader (conn, ForeignLinkageMType, m); | |
595 | CWriteRequestBuffer (conn); | |
596 | cadillac_process_requests (conn); | |
597 | } | |
598 | ||
599 | void | |
600 | cadillac_pop_lang () | |
601 | { | |
602 | Connection *conn = cadillacObj.conn; | |
603 | ||
604 | CWriteHeader (conn, ForeignLinkageMType, LinkPop); | |
605 | CWriteRequestBuffer (conn); | |
606 | cadillac_process_requests (conn); | |
607 | } | |
608 | ||
609 | void | |
610 | cadillac_finish_stmt () | |
611 | { | |
612 | } | |
613 | \f | |
614 | void | |
615 | cadillac_note_source () | |
616 | { | |
617 | cadillacObj.lineno = lineno; | |
618 | cadillacObj.filename = input_filename; | |
619 | } | |
620 | ||
621 | static void | |
622 | CWriteTopLevel (conn, m) | |
623 | Connection *conn; | |
624 | CMessageSubType m; | |
625 | { | |
626 | static context_id = 0; | |
627 | CWriteHeader (conn, TopLevelFormMType, m); | |
628 | cadillac_note_filepos (); | |
629 | ||
630 | /* Eventually, this will point somewhere into the digest file. */ | |
631 | context_id += 1; | |
632 | CWriteSomething (conn, &context_id, sizeof (BITS32)); | |
633 | ||
634 | CWriteSomething (conn, &cadillacObj.iflevel, sizeof (BITS32)); | |
635 | CWriteLength (conn); | |
636 | } | |
637 | ||
638 | static void | |
639 | cadillac_note_filepos () | |
640 | { | |
641 | extern FILE *finput; | |
642 | int pos = ftell (finput); | |
643 | CWriteSomething (cadillacObj.conn, &pos, sizeof (BITS32)); | |
644 | } | |
645 | ||
646 | void | |
647 | cadillac_switch_source (startflag) | |
648 | int startflag; | |
649 | { | |
650 | Connection *conn = cadillacObj.conn; | |
651 | /* Send out the name of the source file being compiled. */ | |
652 | ||
653 | CWriteHeader (conn, SourceFileMType, startflag ? StartMType : StopMType); | |
654 | CWriteSomething (conn, &cadillacObj.depth, sizeof (BITS16)); | |
655 | CWriteVstring0 (conn, input_filename); | |
656 | CWriteLength (conn); | |
657 | CWriteRequestBuffer (conn); | |
658 | cadillac_process_requests (conn); | |
659 | } | |
660 | ||
661 | void | |
662 | cadillac_push_source () | |
663 | { | |
664 | cadillacObj.depth += 1; | |
665 | cadillac_switch_source (1); | |
666 | } | |
667 | ||
668 | void | |
669 | cadillac_pop_source () | |
670 | { | |
671 | cadillacObj.depth -= 1; | |
672 | cadillac_switch_source (0); | |
673 | } | |
674 | ||
675 | struct cadillac_mdep | |
676 | { | |
677 | short object_type; | |
678 | char linkage; | |
679 | char access; | |
680 | short length; | |
681 | }; | |
682 | ||
683 | static void | |
684 | CWriteLanguageElem (conn, p, name) | |
685 | Connection *conn; | |
686 | struct cadillac_mdep *p; | |
687 | char *name; | |
688 | { | |
689 | CWriteSomething (conn, &p->object_type, sizeof (BITS16)); | |
690 | CWriteSomething (conn, &p->linkage, sizeof (BITS8)); | |
691 | CWriteSomething (conn, &p->access, sizeof (BITS8)); | |
692 | CWriteSomething (conn, &p->length, sizeof (BITS16)); | |
693 | CWriteVstring0 (conn, name); | |
694 | ||
695 | #if 0 | |
696 | /* Don't write date_type. */ | |
697 | CWriteVstring0 (conn, ""); | |
698 | #endif | |
699 | CWriteLength (conn); | |
700 | } | |
701 | ||
702 | static void | |
703 | CWriteLanguageDecl (conn, decl, object_type) | |
704 | Connection *conn; | |
705 | tree decl; | |
706 | CObjectType object_type; | |
707 | { | |
708 | struct cadillac_mdep foo; | |
709 | tree name; | |
710 | ||
711 | CWriteHeader (conn, LanguageElementMType, StartDefineMType); | |
712 | foo.object_type = object_type; | |
713 | if (decl_type_context (decl)) | |
714 | { | |
715 | foo.linkage = ParentLinkage; | |
716 | if (TREE_PRIVATE (decl)) | |
717 | foo.access = PrivateAccess; | |
718 | else if (TREE_PROTECTED (decl)) | |
719 | foo.access = ProtectedAccess; | |
720 | else | |
721 | foo.access = PublicAccess; | |
722 | } | |
723 | else | |
724 | { | |
725 | if (TREE_PUBLIC (decl)) | |
726 | foo.linkage = GlobalLinkage; | |
727 | else | |
728 | foo.linkage = FileLinkage; | |
729 | foo.access = PublicAccess; | |
730 | } | |
731 | name = DECL_NAME (decl); | |
732 | foo.length = IDENTIFIER_LENGTH (name); | |
733 | ||
734 | CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name)); | |
735 | CWriteRequestBuffer (conn); | |
736 | cadillac_process_requests (conn); | |
737 | } | |
738 | ||
739 | static void | |
740 | CWriteLanguageType (conn, type, object_type) | |
741 | Connection *conn; | |
742 | tree type; | |
743 | CObjectType object_type; | |
744 | { | |
745 | struct cadillac_mdep foo; | |
746 | tree name = TYPE_NAME (type); | |
747 | ||
748 | CWriteHeader (conn, LanguageElementMType, StartDefineMType); | |
749 | foo.object_type = object_type; | |
750 | if (current_class_type) | |
751 | { | |
752 | foo.linkage = ParentLinkage; | |
753 | if (TREE_PRIVATE (type)) | |
754 | foo.access = PrivateAccess; | |
755 | else if (TREE_PROTECTED (type)) | |
756 | foo.access = ProtectedAccess; | |
757 | else | |
758 | foo.access = PublicAccess; | |
759 | } | |
760 | else | |
761 | { | |
762 | foo.linkage = NoLinkage; | |
763 | foo.access = PublicAccess; | |
764 | } | |
765 | if (TREE_CODE (name) == TYPE_DECL) | |
766 | name = DECL_NAME (name); | |
767 | ||
768 | foo.length = IDENTIFIER_LENGTH (name); | |
769 | ||
770 | CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name)); | |
771 | CWriteRequestBuffer (conn); | |
772 | cadillac_process_requests (conn); | |
773 | } | |
774 | ||
775 | static void | |
776 | CWriteUseObject (conn, type, object_type, use) | |
777 | Connection *conn; | |
778 | tree type; | |
779 | CObjectType object_type; | |
780 | CMessageSubType use; | |
781 | { | |
782 | struct cadillac_mdep foo; | |
783 | tree name = NULL_TREE; | |
784 | ||
785 | CWriteHeader (conn, LanguageElementMType, use); | |
786 | foo.object_type = object_type; | |
787 | if (current_class_type) | |
788 | { | |
789 | foo.linkage = ParentLinkage; | |
790 | if (TREE_PRIVATE (type)) | |
791 | foo.access = PrivateAccess; | |
792 | else if (TREE_PROTECTED (type)) | |
793 | foo.access = ProtectedAccess; | |
794 | else | |
795 | foo.access = PublicAccess; | |
796 | } | |
797 | else | |
798 | { | |
799 | foo.linkage = NoLinkage; | |
800 | foo.access = PublicAccess; | |
801 | } | |
802 | switch (TREE_CODE (type)) | |
803 | { | |
804 | case VAR_DECL: | |
805 | case FIELD_DECL: | |
806 | case TYPE_DECL: | |
807 | case CONST_DECL: | |
808 | case FUNCTION_DECL: | |
809 | name = DECL_NAME (type); | |
810 | break; | |
811 | ||
812 | default: | |
813 | my_friendly_abort (33); | |
814 | } | |
815 | ||
816 | foo.length = IDENTIFIER_LENGTH (name); | |
817 | ||
818 | CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name)); | |
819 | CWriteRequestBuffer (conn); | |
820 | cadillac_process_requests (conn); | |
821 | } | |
822 | \f | |
823 | /* Here's how we exit under cadillac. */ | |
824 | ||
825 | static void | |
826 | exit_cadillac () | |
827 | { | |
828 | extern int errorcount; | |
829 | ||
830 | Connection *conn = cadillacObj.conn; | |
831 | ||
832 | if (flag_cadillac) | |
833 | { | |
834 | CCompilerMessage *req; | |
835 | ||
836 | CWriteHeader (conn, FinishedMType, | |
837 | errorcount ? 0 : CsObjectWritten | CsComplete); | |
838 | /* Bye, bye! */ | |
839 | CWriteRequestBuffer (conn); | |
840 | ||
841 | /* Block on read. */ | |
842 | while (! readable_p (cadillacObj.fd_input)) | |
843 | { | |
844 | if (exiting) | |
845 | my_friendly_abort (34); | |
846 | exiting = 1; | |
847 | } | |
848 | exiting = 1; | |
849 | ||
850 | req = CReadCompilerMessage (conn); | |
851 | cadillac_process_request (&cadillacObj, req); | |
852 | } | |
853 | } | |
854 | ||
855 | #else | |
856 | /* Stubs. */ | |
857 | void init_cadillac () {} | |
858 | void cadillac_start () {} | |
859 | void cadillac_start_decl (decl) | |
860 | tree decl; | |
861 | {} | |
862 | void | |
863 | cadillac_finish_decl (decl) | |
864 | tree decl; | |
865 | {} | |
866 | void | |
867 | cadillac_start_function (fndecl) | |
868 | tree fndecl; | |
869 | {} | |
870 | void | |
871 | cadillac_finish_function (fndecl) | |
872 | tree fndecl; | |
873 | {} | |
874 | void | |
875 | cadillac_finish_anon_union (decl) | |
876 | tree decl; | |
877 | {} | |
878 | void | |
879 | cadillac_start_enum (type) | |
880 | tree type; | |
881 | {} | |
882 | void | |
883 | cadillac_finish_enum (type) | |
884 | tree type; | |
885 | {} | |
886 | void | |
887 | cadillac_start_struct (type) | |
888 | tree type; | |
889 | {} | |
890 | void | |
891 | cadillac_finish_struct (type) | |
892 | tree type; | |
893 | {} | |
894 | void | |
895 | cadillac_finish_exception (type) | |
896 | tree type; | |
897 | {} | |
898 | void | |
899 | cadillac_push_class (type) | |
900 | tree type; | |
901 | {} | |
902 | void | |
903 | cadillac_pop_class () | |
904 | {} | |
905 | void | |
906 | cadillac_push_lang (name) | |
907 | tree name; | |
908 | {} | |
909 | void | |
910 | cadillac_pop_lang () | |
911 | {} | |
912 | void | |
913 | cadillac_note_source () | |
914 | {} | |
915 | void | |
916 | cadillac_finish_stmt () | |
917 | {} | |
918 | void | |
919 | cadillac_switch_source () | |
920 | {} | |
921 | void | |
922 | cadillac_push_source () | |
923 | {} | |
924 | void | |
925 | cadillac_pop_source () | |
926 | {} | |
927 | #endif |