Mercurial > hg > CbC > CbC_gcc
comparison libiberty/cplus-dem.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Demangler for GNU C++ | 1 /* Demangler for GNU C++ |
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, | 2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, |
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | 3 2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc. |
4 Written by James Clark (jjc@jclark.uucp) | 4 Written by James Clark (jjc@jclark.uucp) |
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling | 5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling |
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling | 6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling |
7 | 7 |
8 This file is part of the libiberty library. | 8 This file is part of the libiberty library. |
893 if (!ISLOWER (mangled[0])) | 893 if (!ISLOWER (mangled[0])) |
894 goto unknown; | 894 goto unknown; |
895 | 895 |
896 /* Most of the demangling will trivially remove chars. Operator names | 896 /* Most of the demangling will trivially remove chars. Operator names |
897 may add one char but because they are always preceeded by '__' which is | 897 may add one char but because they are always preceeded by '__' which is |
898 replaced by '.', they eventually never expand the size. '___elabs' and | 898 replaced by '.', they eventually never expand the size. |
899 '___elabb' add only 2 chars, but they occur only once. */ | 899 A few special names such as '___elabs' add a few chars (at most 7), but |
900 len0 = strlen (mangled) + 2 + 1; | 900 they occur only once. */ |
901 len0 = strlen (mangled) + 7 + 1; | |
901 demangled = XNEWVEC (char, len0); | 902 demangled = XNEWVEC (char, len0); |
902 | 903 |
903 d = demangled; | 904 d = demangled; |
904 p = mangled; | 905 p = mangled; |
905 while (1) | 906 while (1) |
906 { | 907 { |
907 /* Convert name, which is always lower-case. */ | 908 /* An entity names is expected. */ |
908 if (ISLOWER (*p)) | 909 if (ISLOWER (*p)) |
909 { | 910 { |
911 /* An identifier, which is always lower case. */ | |
910 do | 912 do |
911 *d++ = *p++; | 913 *d++ = *p++; |
912 while (ISLOWER(*p) || ISDIGIT (*p) | 914 while (ISLOWER(*p) || ISDIGIT (*p) |
913 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1])))); | 915 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1])))); |
914 } | 916 } |
915 else if (p[0] == 'O') | 917 else if (p[0] == 'O') |
916 { | 918 { |
919 /* An operator name. */ | |
917 static const char * const operators[][2] = | 920 static const char * const operators[][2] = |
918 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"}, | 921 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"}, |
919 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"}, | 922 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"}, |
920 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="}, | 923 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="}, |
921 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"}, | 924 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"}, |
922 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"}, | 925 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"}, |
923 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"}, | 926 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"}, |
924 {"Oexpon", "**"}, {NULL, NULL}}; | 927 {"Oexpon", "**"}, {NULL, NULL}}; |
925 int k; | 928 int k; |
926 | 929 |
927 for (k = 0; operators[k][0]; k++) | 930 for (k = 0; operators[k][0] != NULL; k++) |
928 { | 931 { |
929 int l = strlen (operators[k][0]); | 932 size_t slen = strlen (operators[k][0]); |
930 if (!strncmp (p, operators[k][0], l)) | 933 if (strncmp (p, operators[k][0], slen) == 0) |
931 { | 934 { |
932 p += l; | 935 p += slen; |
933 l = strlen (operators[k][1]); | 936 slen = strlen (operators[k][1]); |
934 *d++ = '"'; | 937 *d++ = '"'; |
935 memcpy (d, operators[k][1], l); | 938 memcpy (d, operators[k][1], slen); |
936 d += l; | 939 d += slen; |
937 *d++ = '"'; | 940 *d++ = '"'; |
938 break; | 941 break; |
939 } | 942 } |
940 } | 943 } |
941 /* Operator not found. */ | 944 /* Operator not found. */ |
942 if (!operators[k][0]) | 945 if (operators[k][0] == NULL) |
943 goto unknown; | 946 goto unknown; |
944 } | 947 } |
945 else | 948 else |
946 { | 949 { |
947 /* Not a GNAT encoding. */ | 950 /* Not a GNAT encoding. */ |
948 goto unknown; | 951 goto unknown; |
949 } | 952 } |
950 | 953 |
954 /* The name can be directly followed by some uppercase letters. */ | |
955 if (p[0] == 'T' && p[1] == 'K') | |
956 { | |
957 /* Task stuff. */ | |
958 if (p[2] == 'B' && p[3] == 0) | |
959 { | |
960 /* Subprogram for task body. */ | |
961 break; | |
962 } | |
963 else if (p[2] == '_' && p[3] == '_') | |
964 { | |
965 /* Inner declarations in a task. */ | |
966 p += 4; | |
967 *d++ = '.'; | |
968 continue; | |
969 } | |
970 else | |
971 goto unknown; | |
972 } | |
973 if (p[0] == 'E' && p[1] == 0) | |
974 { | |
975 /* Exception name. */ | |
976 goto unknown; | |
977 } | |
978 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0) | |
979 { | |
980 /* Protected type subprogram. */ | |
981 break; | |
982 } | |
983 if ((*p == 'N' || *p == 'S') && p[1] == 0) | |
984 { | |
985 /* Enumerated type name table. */ | |
986 goto unknown; | |
987 } | |
988 if (p[0] == 'X') | |
989 { | |
990 /* Body nested. */ | |
991 p++; | |
992 while (p[0] == 'n' || p[0] == 'b') | |
993 p++; | |
994 } | |
995 if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0)) | |
996 { | |
997 /* Stream operations. */ | |
998 const char *name; | |
999 switch (p[1]) | |
1000 { | |
1001 case 'R': | |
1002 name = "'Read"; | |
1003 break; | |
1004 case 'W': | |
1005 name = "'Write"; | |
1006 break; | |
1007 case 'I': | |
1008 name = "'Input"; | |
1009 break; | |
1010 case 'O': | |
1011 name = "'Output"; | |
1012 break; | |
1013 default: | |
1014 goto unknown; | |
1015 } | |
1016 p += 2; | |
1017 strcpy (d, name); | |
1018 d += strlen (name); | |
1019 } | |
1020 else if (p[0] == 'D') | |
1021 { | |
1022 /* Controlled type operation. */ | |
1023 const char *name; | |
1024 switch (p[1]) | |
1025 { | |
1026 case 'F': | |
1027 name = ".Finalize"; | |
1028 break; | |
1029 case 'A': | |
1030 name = ".Adjust"; | |
1031 break; | |
1032 default: | |
1033 goto unknown; | |
1034 } | |
1035 strcpy (d, name); | |
1036 d += strlen (name); | |
1037 break; | |
1038 } | |
1039 | |
951 if (p[0] == '_') | 1040 if (p[0] == '_') |
952 { | 1041 { |
953 /* Separator. */ | 1042 /* Separator. */ |
954 if (p[1] == '_') | 1043 if (p[1] == '_') |
955 { | 1044 { |
956 /* Standard separator. Handled first. */ | 1045 /* Standard separator. Handled first. */ |
957 p += 2; | 1046 p += 2; |
1047 | |
958 if (ISDIGIT (*p)) | 1048 if (ISDIGIT (*p)) |
959 { | 1049 { |
960 /* Overloading. */ | 1050 /* Overloading number. */ |
961 do | 1051 do |
962 p++; | 1052 p++; |
963 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1]))); | 1053 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1]))); |
1054 if (*p == 'X') | |
1055 { | |
1056 p++; | |
1057 while (p[0] == 'n' || p[0] == 'b') | |
1058 p++; | |
1059 } | |
964 } | 1060 } |
965 else if (*p == '_' && !strcmp (p + 1, "elabb")) | 1061 else if (p[0] == '_' && p[1] != '_') |
966 { | 1062 { |
967 memcpy (d, "'Elab_Body", 10); | 1063 /* Special names. */ |
968 d += 10; | 1064 static const char * const special[][2] = { |
969 break; | 1065 { "_elabb", "'Elab_Body" }, |
970 } | 1066 { "_elabs", "'Elab_Spec" }, |
971 else if (*p == '_' && !strcmp (p + 1, "elabs")) | 1067 { "_size", "'Size" }, |
972 { | 1068 { "_alignment", "'Alignment" }, |
973 memcpy (d, "'Elab_Spec", 10); | 1069 { "_assign", ".\":=\"" }, |
974 d += 10; | 1070 { NULL, NULL } |
975 break; | 1071 }; |
1072 int k; | |
1073 | |
1074 for (k = 0; special[k][0] != NULL; k++) | |
1075 { | |
1076 size_t slen = strlen (special[k][0]); | |
1077 if (strncmp (p, special[k][0], slen) == 0) | |
1078 { | |
1079 p += slen; | |
1080 slen = strlen (special[k][1]); | |
1081 memcpy (d, special[k][1], slen); | |
1082 d += slen; | |
1083 break; | |
1084 } | |
1085 } | |
1086 if (special[k][0] != NULL) | |
1087 break; | |
1088 else | |
1089 goto unknown; | |
976 } | 1090 } |
977 else | 1091 else |
978 { | 1092 { |
979 *d++ = '.'; | 1093 *d++ = '.'; |
980 continue; | 1094 continue; |
993 } | 1107 } |
994 else | 1108 else |
995 goto unknown; | 1109 goto unknown; |
996 } | 1110 } |
997 | 1111 |
998 if (p[0] == 'T' && p[1] == 'K') | |
999 { | |
1000 if (p[2] == 'B' && p[3] == 0) | |
1001 { | |
1002 /* Subprogram for task body. */ | |
1003 break; | |
1004 } | |
1005 else if (p[2] == '_' && p[3] == '_') | |
1006 { | |
1007 /* Inner declarations in a task. */ | |
1008 p += 4; | |
1009 *d++ = '.'; | |
1010 continue; | |
1011 } | |
1012 else | |
1013 goto unknown; | |
1014 } | |
1015 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0) | |
1016 { | |
1017 /* Protected type subprogram. */ | |
1018 break; | |
1019 } | |
1020 if (p[0] == 'E' && p[1] == 0) | |
1021 { | |
1022 /* Exception name. */ | |
1023 goto unknown; | |
1024 } | |
1025 if (*p == 'N' || *p == 'S') | |
1026 { | |
1027 /* Enumerated type name table. */ | |
1028 goto unknown; | |
1029 } | |
1030 if (p[0] == 'X') | |
1031 { | |
1032 /* Body nested. */ | |
1033 if (p[1] == 'n' || p[1] == 'b') | |
1034 p += 2; | |
1035 else if (p[1] == 0) | |
1036 p++; | |
1037 } | |
1038 if (p[0] == '.' && ISDIGIT (p[1])) | 1112 if (p[0] == '.' && ISDIGIT (p[1])) |
1039 { | 1113 { |
1040 /* Nested subprogram. */ | 1114 /* Nested subprogram. */ |
1041 p += 2; | 1115 p += 2; |
1042 while (ISDIGIT (*p)) | 1116 while (ISDIGIT (*p)) |