No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / usr.bin / g++ / cc1plus / cplus-field.c
blob0d5ab5d8733b857e2c88a15bb9542a4a53f89829
1 /************************************************************************/
2 /* */
3 /* cplus-field.c */
4 /* */
5 /* Code for handling XREF output from g++ */
6 /* */
7 /************************************************************************/
10 #ifdef FIELD_XREF
12 #include "config.h"
13 #include "tree.h"
14 #include "cplus-tree.h"
15 #include "input.h"
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <strings.h>
24 /************************************************************************/
25 /* */
26 /* Common definitions */
27 /* */
28 /************************************************************************/
30 typedef int Integer;
31 typedef char * String;
34 #ifndef TRUE
35 #define TRUE 1
36 #endif
37 #ifndef FALSE
38 #define FALSE 0
39 #endif
40 #ifndef NULL
41 #define NULL 0
42 #endif
45 #define PALLOC(typ) ((typ *) calloc(1,sizeof(typ)))
48 #define SALLOC(str) ((String) ((str == NULL) ? NULL : (strcpy(malloc(strlen(str)+1),str))))
49 #define SFREE(str) (str != NULL && (free(str),0))
51 #define STREQL(s1,s2) (strcmp((s1),(s2)) == 0)
52 #define STRNEQ(s1,s2) (strcmp((s1),(s2)) != 0)
53 #define STRLSS(s1,s2) (strcmp((s1),(s2)) < 0)
54 #define STRLEQ(s1,s2) (strcmp((s1),(s2)) <= 0)
55 #define STRGTR(s1,s2) (strcmp((s1),(s2)) > 0)
56 #define STRGEQ(s1,s2) (strcmp((s1),(s2)) >= 0)
62 /************************************************************************/
63 /* */
64 /* Type definitions */
65 /* */
66 /************************************************************************/
69 typedef struct _XREF_FILE * XREF_FILE;
70 typedef struct _XREF_SCOPE * XREF_SCOPE;
74 typedef struct _XREF_FILE {
75 String name;
76 XREF_FILE next;
77 } XREF_FILE_INFO;
83 typedef struct _XREF_SCOPE {
84 Integer gid;
85 Integer lid;
86 XREF_FILE file;
87 Integer start;
88 XREF_SCOPE outer;
89 } XREF_SCOPE_INFO;
96 /************************************************************************/
97 /* */
98 /* Local storage */
99 /* */
100 /************************************************************************/
103 static char doing_xref = 0;
104 static FILE * xref_file = NULL;
105 static char xref_name[1024];
106 static XREF_FILE all_files = NULL;
107 static String wd_name = NULL;
108 static XREF_SCOPE cur_scope = NULL;
109 static Integer scope_ctr = 0;
110 static XREF_FILE last_file = NULL;
111 static tree last_fct = NULL;
116 /************************************************************************/
117 /* */
118 /* Forward definitions */
119 /* */
120 /************************************************************************/
123 extern void FIELD_xref_begin();
124 extern void FIELD_xref_end();
125 extern void FIELD_xref_file();
126 extern void FIELD_xref_start_scope();
127 extern void FIELD_xref_end_scope();
128 extern void FIELD_xref_ref();
129 extern void FIELD_xref_decl();
130 extern void FIELD_xref_call();
131 extern void FIELD_xref_function();
132 extern void FIELD_xref_assign();
133 extern void FIELD_xref_hier();
134 extern void FIELD_xref_member();
137 static void gen_assign();
138 static XREF_FILE find_file();
139 static String filename();
140 static String fctname();
141 static String declname();
142 static void simplify_type();
143 static String fixname();
144 static void open_xref_file();
146 extern char * type_as_string();
151 /************************************************************************/
152 /* */
153 /* FIELD_xref_begin -- start cross referencing */
154 /* */
155 /************************************************************************/
158 void
159 FIELD_xref_begin(file)
160 String file;
162 String s,t;
164 doing_xref = 1;
166 if (file != NULL && STRNEQ(file,"-")) {
167 open_xref_file(file);
168 FIELD_xref_file(file);
176 /************************************************************************/
177 /* */
178 /* FIELD_xref_end -- finish cross referencing */
179 /* */
180 /************************************************************************/
183 void
184 FIELD_xref_end(ect)
185 int ect;
187 XREF_FILE xf;
189 if (!doing_xref) return;
191 xf = find_file(input_filename);
192 if (xf == NULL) return;
194 while (cur_scope != NULL) {
195 FIELD_xref_end_scope(cur_scope->gid,0,0,0,0);
198 doing_xref = 0;
200 if (xref_file == NULL) return;
202 fclose(xref_file);
204 xref_file = NULL;
205 all_files = NULL;
207 if (ect > 0) unlink(xref_name);
215 /************************************************************************/
216 /* */
217 /* FIELD_xref_file -- handle file xrefing */
218 /* */
219 /************************************************************************/
222 void
223 FIELD_xref_file(name)
224 String name;
226 XREF_FILE xf;
227 char wdbuf[1024];
229 if (!doing_xref || name == NULL) return;
231 if (xref_file == NULL) {
232 open_xref_file(name);
233 if (!doing_xref) return;
236 if (all_files == NULL) {
237 fprintf(xref_file,"SCP * 0 0 0 0 RESET\n");
240 xf = find_file(name);
241 if (xf != NULL) return;
243 xf = PALLOC(XREF_FILE_INFO);
244 xf->name = SALLOC(name);
245 xf->next = all_files;
246 all_files = xf;
248 if (wd_name == NULL) {
249 getwd(wdbuf);
250 wd_name = SALLOC(wdbuf);
253 fprintf(xref_file,"FIL %s %s 0\n",name,wd_name);
255 filename(xf);
256 fctname(NULL);
264 /************************************************************************/
265 /* */
266 /* FIELD_xref_start_scope -- begin a scope */
267 /* FIELD_xref_end_scope -- finish a scope */
268 /* */
269 /************************************************************************/
272 void
273 FIELD_xref_start_scope(id)
274 Integer id;
276 XREF_SCOPE xs;
277 XREF_FILE xf;
279 if (!doing_xref) return;
280 xf = find_file(input_filename);
282 xs = PALLOC(XREF_SCOPE_INFO);
283 xs->file = xf;
284 xs->start = lineno;
285 if (xs->start <= 0) xs->start = 1;
286 xs->gid = id;
287 xs->lid = ++scope_ctr;
288 xs->outer = cur_scope;
289 cur_scope = xs;
296 void
297 FIELD_xref_end_scope(id,inid,prm,keep,trns)
298 Integer id;
299 Integer inid;
300 Integer prm,keep,trns;
302 XREF_FILE xf;
303 XREF_SCOPE xs,lxs,oxs;
304 String stype;
306 if (!doing_xref) return;
307 xf = find_file(input_filename);
308 if (xf == NULL) return;
310 lxs = NULL;
311 for (xs = cur_scope; xs != NULL; xs = xs->outer) {
312 if (xs->gid == id) break;
313 lxs = xs;
315 if (xs == NULL) return;
317 if (inid != 0) {
318 for (oxs = cur_scope; oxs != NULL; oxs = oxs->outer) {
319 if (oxs->gid == inid) break;
321 if (oxs == NULL) return;
322 inid = oxs->lid;
325 if (prm == 2) stype = "SUE";
326 else if (prm != 0) stype = "ARGS";
327 else if (keep == 2 || inid != 0) stype = "INTERN";
328 else stype = "EXTERN";
330 fprintf(xref_file,"SCP %s %d %d %d %d %s\n",
331 filename(xf),xs->start,lineno,xs->lid,inid,stype);
333 if (lxs == NULL) cur_scope = xs->outer;
334 else lxs->outer = xs->outer;
336 free(xs);
343 /************************************************************************/
344 /* */
345 /* FIELD_xref_ref -- handle reference */
346 /* */
347 /************************************************************************/
350 void
351 FIELD_xref_ref(fct,name)
352 tree fct;
353 String name;
355 XREF_FILE xf;
357 if (!doing_xref) return;
358 xf = find_file(input_filename);
359 if (xf == NULL) return;
361 fprintf(xref_file,"REF %s %d %s %s\n",
362 filename(xf),lineno,fctname(fct),name);
370 /************************************************************************/
371 /* */
372 /* FIELD_xref_decl -- handle declaration */
373 /* */
374 /************************************************************************/
377 void
378 FIELD_xref_decl(fct,decl)
379 tree fct;
380 tree decl;
382 XREF_FILE xf;
383 String cls;
384 String name;
385 char buf[10240];
387 if (!doing_xref) return;
388 xf = find_file(input_filename);
389 if (xf == NULL) return;
391 if (DECL_NAME(decl) == NULL) return;
393 if (TREE_CODE(decl) == TYPE_DECL) cls = "TYPEDEF";
394 else if (TREE_CODE(decl) == FIELD_DECL) cls = "FIELD";
395 else if (TREE_CODE(decl) == VAR_DECL) {
396 if (fct == NULL && TREE_STATIC(decl) &&
397 TREE_READONLY(decl) && DECL_INITIAL(decl) != 0 &&
398 !TREE_PUBLIC(decl) && !TREE_EXTERNAL(decl) &&
399 DECL_MODE(decl) != BLKmode) cls = "CONST";
400 else if (TREE_EXTERNAL(decl)) cls = "EXTERN";
401 else if (TREE_PUBLIC(decl)) cls = "EXTDEF";
402 else if (TREE_STATIC(decl)) cls = "STATIC";
403 else if (TREE_REGDECL(decl)) cls = "REGISTER";
404 else cls = "AUTO";
406 else if (TREE_CODE(decl) == PARM_DECL) cls = "PARAM";
407 else if (TREE_CODE(decl) == FIELD_DECL) cls = "FIELD";
408 else if (TREE_CODE(decl) == CONST_DECL) cls = "CONST";
409 else if (TREE_CODE(decl) == FUNCTION_DECL) {
410 if (TREE_EXTERNAL(decl)) cls = "EXTERN";
411 else if (TREE_PUBLIC(decl)) cls = "EFUNCTION";
412 else cls = "SFUNCTION";
414 else if (TREE_CODE(decl) == LABEL_DECL) cls = "LABEL";
415 else if (TREE_CODE(decl) == UNION_TYPE) {
416 cls = "UNIONID";
417 decl = TYPE_NAME(decl);
419 else if (TREE_CODE(decl) == RECORD_TYPE) {
420 if (CLASSTYPE_DECLARED_CLASS(decl)) cls = "CLASSID";
421 else cls = "STRUCTID";
422 decl = TYPE_NAME(decl);
424 else if (TREE_CODE(decl) == ENUMERAL_TYPE) {
425 cls = "ENUMID";
426 decl = TYPE_NAME(decl);
428 else cls = "UNKNOWN";
430 name = IDENTIFIER_POINTER(DECL_NAME(decl));
432 type_as_string(buf,TREE_TYPE(decl));
433 simplify_type(buf);
435 fprintf(xref_file,"DCL %s %d %s %d %s %s %s\n",
436 filename(xf),lineno,name,
437 (cur_scope != NULL ? cur_scope->lid : 0),
438 cls,fctname(fct),buf);
446 /************************************************************************/
447 /* */
448 /* FIELD_xref_call -- handle call */
449 /* */
450 /************************************************************************/
453 void
454 FIELD_xref_call(fct,name)
455 tree fct;
456 String name;
458 XREF_FILE xf;
459 char buf[1024];
461 if (!doing_xref) return;
462 xf = find_file(input_filename);
463 if (xf == NULL) return;
464 name = fixname(name,buf);
466 fprintf(xref_file,"CAL %s %d %s %s\n",
467 filename(xf),lineno,name,fctname(fct));
475 /************************************************************************/
476 /* */
477 /* FIELD_xref_function -- handle functions */
478 /* */
479 /************************************************************************/
482 void
483 FIELD_xref_function(fct,args)
484 tree fct;
485 tree args;
487 XREF_FILE xf;
488 int ct;
489 char buf[1024];
491 if (!doing_xref) return;
492 xf = find_file(input_filename);
493 if (xf == NULL) return;
495 ct = 0;
496 buf[0] = 0;
497 if (args == NULL) args = DECL_ARGUMENTS(fct);
499 FIELD_xref_decl(NULL,fct);
501 for ( ; args != NULL; args = TREE_CHAIN(args)) {
502 FIELD_xref_decl(fct,args);
503 if (ct != 0) strcat(buf,",");
504 strcat(buf,declname(args));
505 ++ct;
508 fprintf(xref_file,"PRC %s %d %s %d %d %s\n",
509 filename(xf),lineno,declname(fct),
510 (cur_scope != NULL ? cur_scope->lid : 0),
511 ct,buf);
519 /************************************************************************/
520 /* */
521 /* FIELD_xref_assign -- handle assignment */
522 /* */
523 /************************************************************************/
526 void
527 FIELD_xref_assign(name)
528 tree name;
530 XREF_FILE xf;
532 if (!doing_xref) return;
533 xf = find_file(input_filename);
534 if (xf == NULL) return;
536 gen_assign(xf,name);
541 static void
542 gen_assign(xf,name)
543 XREF_FILE xf;
544 tree name;
546 String s;
548 s = NULL;
550 switch (TREE_CODE(name)) {
551 case IDENTIFIER_NODE :
552 s = IDENTIFIER_POINTER(name);
553 break;
554 case VAR_DECL :
555 s = declname(name);
556 break;
557 case COMPONENT_REF :
558 gen_assign(xf,TREE_OPERAND(name,0));
559 gen_assign(xf,TREE_OPERAND(name,1));
560 break;
561 case INDIRECT_REF :
562 case OFFSET_REF :
563 case ARRAY_REF :
564 case BUFFER_REF :
565 gen_assign(xf,TREE_OPERAND(name,0));
566 break;
567 case COMPOUND_EXPR :
568 gen_assign(xf,TREE_OPERAND(name,1));
569 break;
570 default :
571 break;
574 if (s != NULL) {
575 fprintf(xref_file,"ASG %s %d %s\n",filename(xf),lineno,s);
583 /************************************************************************/
584 /* */
585 /* FIELD_xref_hier -- handle hierarchy */
586 /* */
587 /************************************************************************/
590 void
591 FIELD_xref_hier(cls,base,pub,virt,frnd)
592 String cls;
593 String base;
594 int pub;
595 int virt;
596 int frnd;
598 XREF_FILE xf;
600 if (!doing_xref) return;
601 xf = find_file(input_filename);
602 if (xf == NULL) return;
604 fprintf(xref_file,"HIE %s %d %s %s %d %d %d\n",
605 filename(xf),lineno,cls,base,pub,virt,frnd);
612 /************************************************************************/
613 /* */
614 /* FIELD_xref_member -- handle member */
615 /* */
616 /************************************************************************/
619 void
620 FIELD_xref_member(cls,fld)
621 tree cls;
622 tree fld;
624 XREF_FILE xf;
625 String prot;
626 Integer confg,pure;
627 String d,p;
628 Integer i;
629 char buf[1024],bufa[1024];
631 if (!doing_xref) return;
632 xf = find_file(fld->decl.filename);
633 if (xf == NULL) return;
635 if (TREE_PRIVATE(fld)) prot = "PRIVATE";
636 else if (TREE_PROTECTED(fld)) prot = "PROTECTED";
637 else prot = "PUBLIC";
639 confg = 0;
640 if (TREE_CODE(fld) == FUNCTION_DECL && DECL_CONST_MEMFUNC_P(fld)) confg = 1;
641 else if (TREE_CODE(fld) == CONST_DECL) confg = 1;
643 pure = 0;
644 if (TREE_CODE(fld) == FUNCTION_DECL && DECL_ABSTRACT_VIRTUAL_P(fld)) pure = 1;
646 d = IDENTIFIER_POINTER(cls);
647 sprintf(buf,"%d%s",strlen(d),d);
648 i = strlen(buf);
649 strcpy(bufa,declname(fld));
650 for (p = &bufa[1]; *p != 0; ++p) {
651 if (p[0] == '_' && p[1] == '_' && p[2] >= '0' && p[2] <= '9') {
652 if (strncmp(&p[2],buf,i) == 0) *p = 0;
653 break;
655 else if (p[0] == '_' && p[1] == '_' && p[2] == 'C' && p[3] >= '0' && p[3] <= '9') {
656 if (strncmp(&p[3],buf,i) == 0) *p = 0;
657 break;
661 fprintf(xref_file,"MEM %s %d %s %s %s %d %d %d %d %d %d %d\n",
662 filename(xf),fld->decl.linenum,d,
663 bufa,
664 prot,
665 (TREE_CODE(fld) == FUNCTION_DECL ? 0 : 1),
666 (TREE_INLINE(fld) ? 1 : 0),
667 (DECL_FRIEND_P(fld) ? 1 : 0),
668 (DECL_VIRTUAL_P(fld) ? 1 : 0),
669 (TREE_STATIC(fld) ? 1 : 0),
670 pure,confg);
678 /************************************************************************/
679 /* */
680 /* find_file -- find file entry given name */
681 /* */
682 /************************************************************************/
686 static XREF_FILE
687 find_file(name)
688 String name;
690 XREF_FILE xf;
692 for (xf = all_files; xf != NULL; xf = xf->next) {
693 if (STREQL(name,xf->name)) break;
696 return xf;
703 /************************************************************************/
704 /* */
705 /* filename -- return name for output */
706 /* */
707 /************************************************************************/
710 static String
711 filename(xf)
712 XREF_FILE xf;
714 if (xf == NULL) {
715 last_file = NULL;
716 return "*";
719 if (last_file == xf) return "*";
721 last_file = xf;
723 return xf->name;
731 /************************************************************************/
732 /* */
733 /* fctname -- return name for function */
734 /* */
735 /************************************************************************/
738 static String
739 fctname(fct)
740 tree fct;
742 extern char * declname();
743 static char fctbuf[1024];
744 String s;
746 if (fct == NULL && last_fct == NULL) return "*";
748 if (fct == NULL) {
749 last_fct = NULL;
750 return "*TOP*";
753 if (fct == last_fct) return "*";
755 last_fct = fct;
757 s = declname(fct);
758 s = fixname(s,fctbuf);
760 return s;
768 /************************************************************************/
769 /* */
770 /* declname -- print name for declaration */
771 /* */
772 /************************************************************************/
775 static String
776 declname(dcl)
777 tree dcl;
779 if (DECL_NAME(dcl) == NULL) return "?";
781 return IDENTIFIER_POINTER (DECL_NAME (dcl));
788 /************************************************************************/
789 /* */
790 /* simplify_type -- simplify a type string */
791 /* */
792 /************************************************************************/
795 static void
796 simplify_type(typ)
797 String typ;
799 String s;
800 Integer lvl,i;
802 i = strlen(typ);
803 while (i > 0 && isspace(typ[i-1])) typ[--i] = 0;
805 if (i > 7 && STREQL(&typ[i-5],"const")) {
806 typ[i-5] = 0;
807 i -= 5;
810 if (typ[i-1] != ')') return;
812 s = &typ[i-2];
813 lvl = 1;
814 while (*s != 0) {
815 if (*s == ')') ++lvl;
816 else if (*s == '(') {
817 --lvl;
818 if (lvl == 0) {
819 s[1] = ')';
820 s[2] = 0;
821 break;
824 --s;
827 if (*s != 0 && s[-1] == ')') {
828 --s;
829 --s;
830 if (*s == '(') s[2] = 0;
831 else if (*s == ':') {
832 while (*s != '(') --s;
833 s[1] = ')';
834 s[2] = 0;
843 /************************************************************************/
844 /* */
845 /* fixname -- fixup a function name (take care of embedded spaces */
846 /* */
847 /************************************************************************/
850 static String
851 fixname(nam,buf)
852 String nam;
853 String buf;
855 String s,t;
856 int fg;
858 s = nam;
859 t = buf;
860 fg = 0;
862 while (*s != 0) {
863 if (*s == ' ') {
864 *t++ = '\36';
865 ++fg;
867 else *t++ = *s;
868 ++s;
871 if (fg == 0) return nam;
873 return buf;
880 /************************************************************************/
881 /* */
882 /* open_xref_file -- open file for xrefing */
883 /* */
884 /************************************************************************/
887 static void
888 open_xref_file(file)
889 String file;
891 String s,t;
893 s = rindex(file,'/');
894 if (s == NULL) sprintf(xref_name,".%s.gxref",file);
895 else {
896 ++s;
897 strcpy(xref_name,file);
898 t = rindex(xref_name,'/');
899 ++t;
900 *t++ = '.';
901 strcpy(t,s);
902 strcat(t,".gxref");
905 xref_file = fopen(xref_name,"w");
907 if (xref_file == NULL) {
908 error("Can't create cross-reference file `%s'",xref_name);
909 doing_xref = 0;
915 #endif
918 /* end of cplus-field.c */