c-ada-spec.c 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451
  1. /* Print GENERIC declaration (functions, variables, types) trees coming from
  2. the C and C++ front-ends as well as macros in Ada syntax.
  3. Copyright (C) 2010-2015 Free Software Foundation, Inc.
  4. Adapted from tree-pretty-print.c by Arnaud Charlet <charlet@adacore.com>
  5. This file is part of GCC.
  6. GCC is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU General Public License as published by the Free
  8. Software Foundation; either version 3, or (at your option) any later
  9. version.
  10. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GCC; see the file COPYING3. If not see
  16. <http://www.gnu.org/licenses/>. */
  17. #include "config.h"
  18. #include "system.h"
  19. #include "coretypes.h"
  20. #include "tm.h"
  21. #include "hash-set.h"
  22. #include "machmode.h"
  23. #include "vec.h"
  24. #include "double-int.h"
  25. #include "input.h"
  26. #include "alias.h"
  27. #include "symtab.h"
  28. #include "options.h"
  29. #include "wide-int.h"
  30. #include "inchash.h"
  31. #include "tree.h"
  32. #include "fold-const.h"
  33. #include "dumpfile.h"
  34. #include "c-ada-spec.h"
  35. #include "cpplib.h"
  36. #include "c-pragma.h"
  37. #include "cpp-id-data.h"
  38. #include "wide-int.h"
  39. /* Local functions, macros and variables. */
  40. static int dump_generic_ada_node (pretty_printer *, tree, tree, int, int,
  41. bool);
  42. static int print_ada_declaration (pretty_printer *, tree, tree, int);
  43. static void print_ada_struct_decl (pretty_printer *, tree, tree, int, bool);
  44. static void dump_sloc (pretty_printer *buffer, tree node);
  45. static void print_comment (pretty_printer *, const char *);
  46. static void print_generic_ada_decl (pretty_printer *, tree, const char *);
  47. static char *get_ada_package (const char *);
  48. static void dump_ada_nodes (pretty_printer *, const char *);
  49. static void reset_ada_withs (void);
  50. static void dump_ada_withs (FILE *);
  51. static void dump_ads (const char *, void (*)(const char *),
  52. int (*)(tree, cpp_operation));
  53. static char *to_ada_name (const char *, int *);
  54. static bool separate_class_package (tree);
  55. #define INDENT(SPACE) \
  56. do { int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
  57. #define INDENT_INCR 3
  58. /* Global hook used to perform C++ queries on nodes. */
  59. static int (*cpp_check) (tree, cpp_operation) = NULL;
  60. /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
  61. as max length PARAM_LEN of arguments for fun_like macros, and also set
  62. SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
  63. static void
  64. macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
  65. int *param_len)
  66. {
  67. int i;
  68. unsigned j;
  69. *supported = 1;
  70. *buffer_len = 0;
  71. *param_len = 0;
  72. if (macro->fun_like)
  73. {
  74. param_len++;
  75. for (i = 0; i < macro->paramc; i++)
  76. {
  77. cpp_hashnode *param = macro->params[i];
  78. *param_len += NODE_LEN (param);
  79. if (i + 1 < macro->paramc)
  80. {
  81. *param_len += 2; /* ", " */
  82. }
  83. else if (macro->variadic)
  84. {
  85. *supported = 0;
  86. return;
  87. }
  88. }
  89. *param_len += 2; /* ")\0" */
  90. }
  91. for (j = 0; j < macro->count; j++)
  92. {
  93. cpp_token *token = &macro->exp.tokens[j];
  94. if (token->flags & PREV_WHITE)
  95. (*buffer_len)++;
  96. if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
  97. {
  98. *supported = 0;
  99. return;
  100. }
  101. if (token->type == CPP_MACRO_ARG)
  102. *buffer_len +=
  103. NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
  104. else
  105. /* Include enough extra space to handle e.g. special characters. */
  106. *buffer_len += (cpp_token_len (token) + 1) * 8;
  107. }
  108. (*buffer_len)++;
  109. }
  110. /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
  111. possible. */
  112. static void
  113. print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
  114. {
  115. int j, num_macros = 0, prev_line = -1;
  116. for (j = 0; j < max_ada_macros; j++)
  117. {
  118. cpp_hashnode *node = macros[j];
  119. const cpp_macro *macro = node->value.macro;
  120. unsigned i;
  121. int supported = 1, prev_is_one = 0, buffer_len, param_len;
  122. int is_string = 0, is_char = 0;
  123. char *ada_name;
  124. unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL;
  125. macro_length (macro, &supported, &buffer_len, &param_len);
  126. s = buffer = XALLOCAVEC (unsigned char, buffer_len);
  127. params = buf_param = XALLOCAVEC (unsigned char, param_len);
  128. if (supported)
  129. {
  130. if (macro->fun_like)
  131. {
  132. *buf_param++ = '(';
  133. for (i = 0; i < macro->paramc; i++)
  134. {
  135. cpp_hashnode *param = macro->params[i];
  136. memcpy (buf_param, NODE_NAME (param), NODE_LEN (param));
  137. buf_param += NODE_LEN (param);
  138. if (i + 1 < macro->paramc)
  139. {
  140. *buf_param++ = ',';
  141. *buf_param++ = ' ';
  142. }
  143. else if (macro->variadic)
  144. {
  145. supported = 0;
  146. break;
  147. }
  148. }
  149. *buf_param++ = ')';
  150. *buf_param = '\0';
  151. }
  152. for (i = 0; supported && i < macro->count; i++)
  153. {
  154. cpp_token *token = &macro->exp.tokens[i];
  155. int is_one = 0;
  156. if (token->flags & PREV_WHITE)
  157. *buffer++ = ' ';
  158. if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
  159. {
  160. supported = 0;
  161. break;
  162. }
  163. switch (token->type)
  164. {
  165. case CPP_MACRO_ARG:
  166. {
  167. cpp_hashnode *param =
  168. macro->params[token->val.macro_arg.arg_no - 1];
  169. memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
  170. buffer += NODE_LEN (param);
  171. }
  172. break;
  173. case CPP_EQ_EQ: *buffer++ = '='; break;
  174. case CPP_GREATER: *buffer++ = '>'; break;
  175. case CPP_LESS: *buffer++ = '<'; break;
  176. case CPP_PLUS: *buffer++ = '+'; break;
  177. case CPP_MINUS: *buffer++ = '-'; break;
  178. case CPP_MULT: *buffer++ = '*'; break;
  179. case CPP_DIV: *buffer++ = '/'; break;
  180. case CPP_COMMA: *buffer++ = ','; break;
  181. case CPP_OPEN_SQUARE:
  182. case CPP_OPEN_PAREN: *buffer++ = '('; break;
  183. case CPP_CLOSE_SQUARE: /* fallthrough */
  184. case CPP_CLOSE_PAREN: *buffer++ = ')'; break;
  185. case CPP_DEREF: /* fallthrough */
  186. case CPP_SCOPE: /* fallthrough */
  187. case CPP_DOT: *buffer++ = '.'; break;
  188. case CPP_EQ: *buffer++ = ':'; *buffer++ = '='; break;
  189. case CPP_NOT_EQ: *buffer++ = '/'; *buffer++ = '='; break;
  190. case CPP_GREATER_EQ: *buffer++ = '>'; *buffer++ = '='; break;
  191. case CPP_LESS_EQ: *buffer++ = '<'; *buffer++ = '='; break;
  192. case CPP_NOT:
  193. *buffer++ = 'n'; *buffer++ = 'o'; *buffer++ = 't'; break;
  194. case CPP_MOD:
  195. *buffer++ = 'm'; *buffer++ = 'o'; *buffer++ = 'd'; break;
  196. case CPP_AND:
  197. *buffer++ = 'a'; *buffer++ = 'n'; *buffer++ = 'd'; break;
  198. case CPP_OR:
  199. *buffer++ = 'o'; *buffer++ = 'r'; break;
  200. case CPP_XOR:
  201. *buffer++ = 'x'; *buffer++ = 'o'; *buffer++ = 'r'; break;
  202. case CPP_AND_AND:
  203. strcpy ((char *) buffer, " and then ");
  204. buffer += 10;
  205. break;
  206. case CPP_OR_OR:
  207. strcpy ((char *) buffer, " or else ");
  208. buffer += 9;
  209. break;
  210. case CPP_PADDING:
  211. *buffer++ = ' ';
  212. is_one = prev_is_one;
  213. break;
  214. case CPP_COMMENT: break;
  215. case CPP_WSTRING:
  216. case CPP_STRING16:
  217. case CPP_STRING32:
  218. case CPP_UTF8STRING:
  219. case CPP_WCHAR:
  220. case CPP_CHAR16:
  221. case CPP_CHAR32:
  222. case CPP_NAME:
  223. case CPP_STRING:
  224. case CPP_NUMBER:
  225. if (!macro->fun_like)
  226. supported = 0;
  227. else
  228. buffer = cpp_spell_token (parse_in, token, buffer, false);
  229. break;
  230. case CPP_CHAR:
  231. is_char = 1;
  232. {
  233. unsigned chars_seen;
  234. int ignored;
  235. cppchar_t c;
  236. c = cpp_interpret_charconst (parse_in, token,
  237. &chars_seen, &ignored);
  238. if (c >= 32 && c <= 126)
  239. {
  240. *buffer++ = '\'';
  241. *buffer++ = (char) c;
  242. *buffer++ = '\'';
  243. }
  244. else
  245. {
  246. chars_seen = sprintf
  247. ((char *) buffer, "Character'Val (%d)", (int) c);
  248. buffer += chars_seen;
  249. }
  250. }
  251. break;
  252. case CPP_LSHIFT:
  253. if (prev_is_one)
  254. {
  255. /* Replace "1 << N" by "2 ** N" */
  256. *char_one = '2';
  257. *buffer++ = '*';
  258. *buffer++ = '*';
  259. break;
  260. }
  261. /* fallthrough */
  262. case CPP_RSHIFT:
  263. case CPP_COMPL:
  264. case CPP_QUERY:
  265. case CPP_EOF:
  266. case CPP_PLUS_EQ:
  267. case CPP_MINUS_EQ:
  268. case CPP_MULT_EQ:
  269. case CPP_DIV_EQ:
  270. case CPP_MOD_EQ:
  271. case CPP_AND_EQ:
  272. case CPP_OR_EQ:
  273. case CPP_XOR_EQ:
  274. case CPP_RSHIFT_EQ:
  275. case CPP_LSHIFT_EQ:
  276. case CPP_PRAGMA:
  277. case CPP_PRAGMA_EOL:
  278. case CPP_HASH:
  279. case CPP_PASTE:
  280. case CPP_OPEN_BRACE:
  281. case CPP_CLOSE_BRACE:
  282. case CPP_SEMICOLON:
  283. case CPP_ELLIPSIS:
  284. case CPP_PLUS_PLUS:
  285. case CPP_MINUS_MINUS:
  286. case CPP_DEREF_STAR:
  287. case CPP_DOT_STAR:
  288. case CPP_ATSIGN:
  289. case CPP_HEADER_NAME:
  290. case CPP_AT_NAME:
  291. case CPP_OTHER:
  292. case CPP_OBJC_STRING:
  293. default:
  294. if (!macro->fun_like)
  295. supported = 0;
  296. else
  297. buffer = cpp_spell_token (parse_in, token, buffer, false);
  298. break;
  299. }
  300. prev_is_one = is_one;
  301. }
  302. if (supported)
  303. *buffer = '\0';
  304. }
  305. if (macro->fun_like && supported)
  306. {
  307. char *start = (char *) s;
  308. int is_function = 0;
  309. pp_string (pp, " -- arg-macro: ");
  310. if (*start == '(' && buffer[-1] == ')')
  311. {
  312. start++;
  313. buffer[-1] = '\0';
  314. is_function = 1;
  315. pp_string (pp, "function ");
  316. }
  317. else
  318. {
  319. pp_string (pp, "procedure ");
  320. }
  321. pp_string (pp, (const char *) NODE_NAME (node));
  322. pp_space (pp);
  323. pp_string (pp, (char *) params);
  324. pp_newline (pp);
  325. pp_string (pp, " -- ");
  326. if (is_function)
  327. {
  328. pp_string (pp, "return ");
  329. pp_string (pp, start);
  330. pp_semicolon (pp);
  331. }
  332. else
  333. pp_string (pp, start);
  334. pp_newline (pp);
  335. }
  336. else if (supported)
  337. {
  338. expanded_location sloc = expand_location (macro->line);
  339. if (sloc.line != prev_line + 1)
  340. pp_newline (pp);
  341. num_macros++;
  342. prev_line = sloc.line;
  343. pp_string (pp, " ");
  344. ada_name = to_ada_name ((const char *) NODE_NAME (node), NULL);
  345. pp_string (pp, ada_name);
  346. free (ada_name);
  347. pp_string (pp, " : ");
  348. if (is_string)
  349. pp_string (pp, "aliased constant String");
  350. else if (is_char)
  351. pp_string (pp, "aliased constant Character");
  352. else
  353. pp_string (pp, "constant");
  354. pp_string (pp, " := ");
  355. pp_string (pp, (char *) s);
  356. if (is_string)
  357. pp_string (pp, " & ASCII.NUL");
  358. pp_string (pp, "; -- ");
  359. pp_string (pp, sloc.file);
  360. pp_colon (pp);
  361. pp_scalar (pp, "%d", sloc.line);
  362. pp_newline (pp);
  363. }
  364. else
  365. {
  366. pp_string (pp, " -- unsupported macro: ");
  367. pp_string (pp, (const char *) cpp_macro_definition (parse_in, node));
  368. pp_newline (pp);
  369. }
  370. }
  371. if (num_macros > 0)
  372. pp_newline (pp);
  373. }
  374. static const char *source_file;
  375. static int max_ada_macros;
  376. /* Callback used to count the number of relevant macros from
  377. cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro
  378. to consider. */
  379. static int
  380. count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node,
  381. void *v ATTRIBUTE_UNUSED)
  382. {
  383. const cpp_macro *macro = node->value.macro;
  384. if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
  385. && macro->count
  386. && *NODE_NAME (node) != '_'
  387. && LOCATION_FILE (macro->line) == source_file)
  388. max_ada_macros++;
  389. return 1;
  390. }
  391. static int store_ada_macro_index;
  392. /* Callback used to store relevant macros from cpp_forall_identifiers.
  393. PFILE is not used. NODE is the current macro to store if relevant.
  394. MACROS is an array of cpp_hashnode* used to store NODE. */
  395. static int
  396. store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED,
  397. cpp_hashnode *node, void *macros)
  398. {
  399. const cpp_macro *macro = node->value.macro;
  400. if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
  401. && macro->count
  402. && *NODE_NAME (node) != '_'
  403. && LOCATION_FILE (macro->line) == source_file)
  404. ((cpp_hashnode **) macros)[store_ada_macro_index++] = node;
  405. return 1;
  406. }
  407. /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
  408. two macro nodes to compare. */
  409. static int
  410. compare_macro (const void *node1, const void *node2)
  411. {
  412. typedef const cpp_hashnode *const_hnode;
  413. const_hnode n1 = *(const const_hnode *) node1;
  414. const_hnode n2 = *(const const_hnode *) node2;
  415. return n1->value.macro->line - n2->value.macro->line;
  416. }
  417. /* Dump in PP all relevant macros appearing in FILE. */
  418. static void
  419. dump_ada_macros (pretty_printer *pp, const char* file)
  420. {
  421. cpp_hashnode **macros;
  422. /* Initialize file-scope variables. */
  423. max_ada_macros = 0;
  424. store_ada_macro_index = 0;
  425. source_file = file;
  426. /* Count all potentially relevant macros, and then sort them by sloc. */
  427. cpp_forall_identifiers (parse_in, count_ada_macro, NULL);
  428. macros = XALLOCAVEC (cpp_hashnode *, max_ada_macros);
  429. cpp_forall_identifiers (parse_in, store_ada_macro, macros);
  430. qsort (macros, max_ada_macros, sizeof (cpp_hashnode *), compare_macro);
  431. print_ada_macros (pp, macros, max_ada_macros);
  432. }
  433. /* Current source file being handled. */
  434. static const char *source_file_base;
  435. /* Compare the declaration (DECL) of struct-like types based on the sloc of
  436. their last field (if LAST is true), so that more nested types collate before
  437. less nested ones.
  438. If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */
  439. static location_t
  440. decl_sloc_common (const_tree decl, bool last, bool orig_type)
  441. {
  442. tree type = TREE_TYPE (decl);
  443. if (TREE_CODE (decl) == TYPE_DECL
  444. && (orig_type || !DECL_ORIGINAL_TYPE (decl))
  445. && RECORD_OR_UNION_TYPE_P (type)
  446. && TYPE_FIELDS (type))
  447. {
  448. tree f = TYPE_FIELDS (type);
  449. if (last)
  450. while (TREE_CHAIN (f))
  451. f = TREE_CHAIN (f);
  452. return DECL_SOURCE_LOCATION (f);
  453. }
  454. else
  455. return DECL_SOURCE_LOCATION (decl);
  456. }
  457. /* Return sloc of DECL, using sloc of last field if LAST is true. */
  458. location_t
  459. decl_sloc (const_tree decl, bool last)
  460. {
  461. return decl_sloc_common (decl, last, false);
  462. }
  463. /* Compare two locations LHS and RHS. */
  464. static int
  465. compare_location (location_t lhs, location_t rhs)
  466. {
  467. expanded_location xlhs = expand_location (lhs);
  468. expanded_location xrhs = expand_location (rhs);
  469. if (xlhs.file != xrhs.file)
  470. return filename_cmp (xlhs.file, xrhs.file);
  471. if (xlhs.line != xrhs.line)
  472. return xlhs.line - xrhs.line;
  473. if (xlhs.column != xrhs.column)
  474. return xlhs.column - xrhs.column;
  475. return 0;
  476. }
  477. /* Compare two declarations (LP and RP) by their source location. */
  478. static int
  479. compare_node (const void *lp, const void *rp)
  480. {
  481. const_tree lhs = *((const tree *) lp);
  482. const_tree rhs = *((const tree *) rp);
  483. return compare_location (decl_sloc (lhs, true), decl_sloc (rhs, true));
  484. }
  485. /* Compare two comments (LP and RP) by their source location. */
  486. static int
  487. compare_comment (const void *lp, const void *rp)
  488. {
  489. const cpp_comment *lhs = (const cpp_comment *) lp;
  490. const cpp_comment *rhs = (const cpp_comment *) rp;
  491. return compare_location (lhs->sloc, rhs->sloc);
  492. }
  493. static tree *to_dump = NULL;
  494. static int to_dump_count = 0;
  495. /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
  496. by a subsequent call to dump_ada_nodes. */
  497. void
  498. collect_ada_nodes (tree t, const char *source_file)
  499. {
  500. tree n;
  501. int i = to_dump_count;
  502. /* Count the likely relevant nodes. */
  503. for (n = t; n; n = TREE_CHAIN (n))
  504. if (!DECL_IS_BUILTIN (n)
  505. && LOCATION_FILE (decl_sloc (n, false)) == source_file)
  506. to_dump_count++;
  507. /* Allocate sufficient storage for all nodes. */
  508. to_dump = XRESIZEVEC (tree, to_dump, to_dump_count);
  509. /* Store the relevant nodes. */
  510. for (n = t; n; n = TREE_CHAIN (n))
  511. if (!DECL_IS_BUILTIN (n)
  512. && LOCATION_FILE (decl_sloc (n, false)) == source_file)
  513. to_dump[i++] = n;
  514. }
  515. /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
  516. static tree
  517. unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
  518. void *data ATTRIBUTE_UNUSED)
  519. {
  520. if (TREE_VISITED (*tp))
  521. TREE_VISITED (*tp) = 0;
  522. else
  523. *walk_subtrees = 0;
  524. return NULL_TREE;
  525. }
  526. /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
  527. to collect_ada_nodes. */
  528. static void
  529. dump_ada_nodes (pretty_printer *pp, const char *source_file)
  530. {
  531. int i, j;
  532. cpp_comment_table *comments;
  533. /* Sort the table of declarations to dump by sloc. */
  534. qsort (to_dump, to_dump_count, sizeof (tree), compare_node);
  535. /* Fetch the table of comments. */
  536. comments = cpp_get_comments (parse_in);
  537. /* Sort the comments table by sloc. */
  538. if (comments->count > 1)
  539. qsort (comments->entries, comments->count, sizeof (cpp_comment),
  540. compare_comment);
  541. /* Interleave comments and declarations in line number order. */
  542. i = j = 0;
  543. do
  544. {
  545. /* Advance j until comment j is in this file. */
  546. while (j != comments->count
  547. && LOCATION_FILE (comments->entries[j].sloc) != source_file)
  548. j++;
  549. /* Advance j until comment j is not a duplicate. */
  550. while (j < comments->count - 1
  551. && !compare_comment (&comments->entries[j],
  552. &comments->entries[j + 1]))
  553. j++;
  554. /* Write decls until decl i collates after comment j. */
  555. while (i != to_dump_count)
  556. {
  557. if (j == comments->count
  558. || LOCATION_LINE (decl_sloc (to_dump[i], false))
  559. < LOCATION_LINE (comments->entries[j].sloc))
  560. print_generic_ada_decl (pp, to_dump[i++], source_file);
  561. else
  562. break;
  563. }
  564. /* Write comment j, if there is one. */
  565. if (j != comments->count)
  566. print_comment (pp, comments->entries[j++].comment);
  567. } while (i != to_dump_count || j != comments->count);
  568. /* Clear the TREE_VISITED flag over each subtree we've dumped. */
  569. for (i = 0; i < to_dump_count; i++)
  570. walk_tree (&to_dump[i], unmark_visited_r, NULL, NULL);
  571. /* Finalize the to_dump table. */
  572. if (to_dump)
  573. {
  574. free (to_dump);
  575. to_dump = NULL;
  576. to_dump_count = 0;
  577. }
  578. }
  579. /* Print a COMMENT to the output stream PP. */
  580. static void
  581. print_comment (pretty_printer *pp, const char *comment)
  582. {
  583. int len = strlen (comment);
  584. char *str = XALLOCAVEC (char, len + 1);
  585. char *tok;
  586. bool extra_newline = false;
  587. memcpy (str, comment, len + 1);
  588. /* Trim C/C++ comment indicators. */
  589. if (str[len - 2] == '*' && str[len - 1] == '/')
  590. {
  591. str[len - 2] = ' ';
  592. str[len - 1] = '\0';
  593. }
  594. str += 2;
  595. tok = strtok (str, "\n");
  596. while (tok) {
  597. pp_string (pp, " --");
  598. pp_string (pp, tok);
  599. pp_newline (pp);
  600. tok = strtok (NULL, "\n");
  601. /* Leave a blank line after multi-line comments. */
  602. if (tok)
  603. extra_newline = true;
  604. }
  605. if (extra_newline)
  606. pp_newline (pp);
  607. }
  608. /* Print declaration DECL to PP in Ada syntax. The current source file being
  609. handled is SOURCE_FILE. */
  610. static void
  611. print_generic_ada_decl (pretty_printer *pp, tree decl, const char *source_file)
  612. {
  613. source_file_base = source_file;
  614. if (print_ada_declaration (pp, decl, 0, INDENT_INCR))
  615. {
  616. pp_newline (pp);
  617. pp_newline (pp);
  618. }
  619. }
  620. /* Dump a newline and indent BUFFER by SPC chars. */
  621. static void
  622. newline_and_indent (pretty_printer *buffer, int spc)
  623. {
  624. pp_newline (buffer);
  625. INDENT (spc);
  626. }
  627. struct with { char *s; const char *in_file; int limited; };
  628. static struct with *withs = NULL;
  629. static int withs_max = 4096;
  630. static int with_len = 0;
  631. /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
  632. true), if not already done. */
  633. static void
  634. append_withs (const char *s, int limited_access)
  635. {
  636. int i;
  637. if (withs == NULL)
  638. withs = XNEWVEC (struct with, withs_max);
  639. if (with_len == withs_max)
  640. {
  641. withs_max *= 2;
  642. withs = XRESIZEVEC (struct with, withs, withs_max);
  643. }
  644. for (i = 0; i < with_len; i++)
  645. if (!strcmp (s, withs[i].s)
  646. && source_file_base == withs[i].in_file)
  647. {
  648. withs[i].limited &= limited_access;
  649. return;
  650. }
  651. withs[with_len].s = xstrdup (s);
  652. withs[with_len].in_file = source_file_base;
  653. withs[with_len].limited = limited_access;
  654. with_len++;
  655. }
  656. /* Reset "with" clauses. */
  657. static void
  658. reset_ada_withs (void)
  659. {
  660. int i;
  661. if (!withs)
  662. return;
  663. for (i = 0; i < with_len; i++)
  664. free (withs[i].s);
  665. free (withs);
  666. withs = NULL;
  667. withs_max = 4096;
  668. with_len = 0;
  669. }
  670. /* Dump "with" clauses in F. */
  671. static void
  672. dump_ada_withs (FILE *f)
  673. {
  674. int i;
  675. fprintf (f, "with Interfaces.C; use Interfaces.C;\n");
  676. for (i = 0; i < with_len; i++)
  677. fprintf
  678. (f, "%swith %s;\n", withs[i].limited ? "limited " : "", withs[i].s);
  679. }
  680. /* Return suitable Ada package name from FILE. */
  681. static char *
  682. get_ada_package (const char *file)
  683. {
  684. const char *base;
  685. char *res;
  686. const char *s;
  687. int i;
  688. size_t plen;
  689. s = strstr (file, "/include/");
  690. if (s)
  691. base = s + 9;
  692. else
  693. base = lbasename (file);
  694. if (ada_specs_parent == NULL)
  695. plen = 0;
  696. else
  697. plen = strlen (ada_specs_parent) + 1;
  698. res = XNEWVEC (char, plen + strlen (base) + 1);
  699. if (ada_specs_parent != NULL) {
  700. strcpy (res, ada_specs_parent);
  701. res[plen - 1] = '.';
  702. }
  703. for (i = plen; *base; base++, i++)
  704. switch (*base)
  705. {
  706. case '+':
  707. res[i] = 'p';
  708. break;
  709. case '.':
  710. case '-':
  711. case '_':
  712. case '/':
  713. case '\\':
  714. res[i] = (i == 0 || res[i - 1] == '.' || res[i - 1] == '_') ? 'u' : '_';
  715. break;
  716. default:
  717. res[i] = *base;
  718. break;
  719. }
  720. res[i] = '\0';
  721. return res;
  722. }
  723. static const char *ada_reserved[] = {
  724. "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
  725. "array", "at", "begin", "body", "case", "constant", "declare", "delay",
  726. "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
  727. "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
  728. "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
  729. "overriding", "package", "pragma", "private", "procedure", "protected",
  730. "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
  731. "select", "separate", "subtype", "synchronized", "tagged", "task",
  732. "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
  733. NULL};
  734. /* ??? would be nice to specify this list via a config file, so that users
  735. can create their own dictionary of conflicts. */
  736. static const char *c_duplicates[] = {
  737. /* system will cause troubles with System.Address. */
  738. "system",
  739. /* The following values have other definitions with same name/other
  740. casing. */
  741. "funmap",
  742. "rl_vi_fWord",
  743. "rl_vi_bWord",
  744. "rl_vi_eWord",
  745. "rl_readline_version",
  746. "_Vx_ushort",
  747. "USHORT",
  748. "XLookupKeysym",
  749. NULL};
  750. /* Return a declaration tree corresponding to TYPE. */
  751. static tree
  752. get_underlying_decl (tree type)
  753. {
  754. tree decl = NULL_TREE;
  755. if (type == NULL_TREE)
  756. return NULL_TREE;
  757. /* type is a declaration. */
  758. if (DECL_P (type))
  759. decl = type;
  760. /* type is a typedef. */
  761. if (TYPE_P (type) && TYPE_NAME (type) && DECL_P (TYPE_NAME (type)))
  762. decl = TYPE_NAME (type);
  763. /* TYPE_STUB_DECL has been set for type. */
  764. if (TYPE_P (type) && TYPE_STUB_DECL (type) &&
  765. DECL_P (TYPE_STUB_DECL (type)))
  766. decl = TYPE_STUB_DECL (type);
  767. return decl;
  768. }
  769. /* Return whether TYPE has static fields. */
  770. static bool
  771. has_static_fields (const_tree type)
  772. {
  773. tree tmp;
  774. if (!type || !RECORD_OR_UNION_TYPE_P (type))
  775. return false;
  776. for (tmp = TYPE_FIELDS (type); tmp; tmp = TREE_CHAIN (tmp))
  777. if (DECL_NAME (tmp) && TREE_STATIC (tmp))
  778. return true;
  779. return false;
  780. }
  781. /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
  782. table). */
  783. static bool
  784. is_tagged_type (const_tree type)
  785. {
  786. tree tmp;
  787. if (!type || !RECORD_OR_UNION_TYPE_P (type))
  788. return false;
  789. for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
  790. if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_VINDEX (tmp))
  791. return true;
  792. return false;
  793. }
  794. /* Return whether TYPE has non-trivial methods, i.e. methods that do something
  795. for the objects of TYPE. In C++, all classes have implicit special methods,
  796. e.g. constructors and destructors, but they can be trivial if the type is
  797. sufficiently simple. */
  798. static bool
  799. has_nontrivial_methods (tree type)
  800. {
  801. tree tmp;
  802. if (!type || !RECORD_OR_UNION_TYPE_P (type))
  803. return false;
  804. /* Only C++ types can have methods. */
  805. if (!cpp_check)
  806. return false;
  807. /* A non-trivial type has non-trivial special methods. */
  808. if (!cpp_check (type, IS_TRIVIAL))
  809. return true;
  810. /* If there are user-defined methods, they are deemed non-trivial. */
  811. for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
  812. if (!DECL_ARTIFICIAL (tmp))
  813. return true;
  814. return false;
  815. }
  816. /* Generate a legal Ada name from a C NAME, returning a malloc'd string.
  817. SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
  818. NAME. */
  819. static char *
  820. to_ada_name (const char *name, int *space_found)
  821. {
  822. const char **names;
  823. int len = strlen (name);
  824. int j, len2 = 0;
  825. int found = false;
  826. char *s = XNEWVEC (char, len * 2 + 5);
  827. char c;
  828. if (space_found)
  829. *space_found = false;
  830. /* Add trailing "c_" if name is an Ada reserved word. */
  831. for (names = ada_reserved; *names; names++)
  832. if (!strcasecmp (name, *names))
  833. {
  834. s[len2++] = 'c';
  835. s[len2++] = '_';
  836. found = true;
  837. break;
  838. }
  839. if (!found)
  840. /* Add trailing "c_" if name is an potential case sensitive duplicate. */
  841. for (names = c_duplicates; *names; names++)
  842. if (!strcmp (name, *names))
  843. {
  844. s[len2++] = 'c';
  845. s[len2++] = '_';
  846. found = true;
  847. break;
  848. }
  849. for (j = 0; name[j] == '_'; j++)
  850. s[len2++] = 'u';
  851. if (j > 0)
  852. s[len2++] = '_';
  853. else if (*name == '.' || *name == '$')
  854. {
  855. s[0] = 'a';
  856. s[1] = 'n';
  857. s[2] = 'o';
  858. s[3] = 'n';
  859. len2 = 4;
  860. j++;
  861. }
  862. /* Replace unsuitable characters for Ada identifiers. */
  863. for (; j < len; j++)
  864. switch (name[j])
  865. {
  866. case ' ':
  867. if (space_found)
  868. *space_found = true;
  869. s[len2++] = '_';
  870. break;
  871. /* ??? missing some C++ operators. */
  872. case '=':
  873. s[len2++] = '_';
  874. if (name[j + 1] == '=')
  875. {
  876. j++;
  877. s[len2++] = 'e';
  878. s[len2++] = 'q';
  879. }
  880. else
  881. {
  882. s[len2++] = 'a';
  883. s[len2++] = 's';
  884. }
  885. break;
  886. case '!':
  887. s[len2++] = '_';
  888. if (name[j + 1] == '=')
  889. {
  890. j++;
  891. s[len2++] = 'n';
  892. s[len2++] = 'e';
  893. }
  894. break;
  895. case '~':
  896. s[len2++] = '_';
  897. s[len2++] = 't';
  898. s[len2++] = 'i';
  899. break;
  900. case '&':
  901. case '|':
  902. case '^':
  903. s[len2++] = '_';
  904. s[len2++] = name[j] == '&' ? 'a' : name[j] == '|' ? 'o' : 'x';
  905. if (name[j + 1] == '=')
  906. {
  907. j++;
  908. s[len2++] = 'e';
  909. }
  910. break;
  911. case '+':
  912. case '-':
  913. case '*':
  914. case '/':
  915. case '(':
  916. case '[':
  917. if (s[len2 - 1] != '_')
  918. s[len2++] = '_';
  919. switch (name[j + 1]) {
  920. case '\0':
  921. j++;
  922. switch (name[j - 1]) {
  923. case '+': s[len2++] = 'p'; break; /* + */
  924. case '-': s[len2++] = 'm'; break; /* - */
  925. case '*': s[len2++] = 't'; break; /* * */
  926. case '/': s[len2++] = 'd'; break; /* / */
  927. }
  928. break;
  929. case '=':
  930. j++;
  931. switch (name[j - 1]) {
  932. case '+': s[len2++] = 'p'; break; /* += */
  933. case '-': s[len2++] = 'm'; break; /* -= */
  934. case '*': s[len2++] = 't'; break; /* *= */
  935. case '/': s[len2++] = 'd'; break; /* /= */
  936. }
  937. s[len2++] = 'a';
  938. break;
  939. case '-': /* -- */
  940. j++;
  941. s[len2++] = 'm';
  942. s[len2++] = 'm';
  943. break;
  944. case '+': /* ++ */
  945. j++;
  946. s[len2++] = 'p';
  947. s[len2++] = 'p';
  948. break;
  949. case ')': /* () */
  950. j++;
  951. s[len2++] = 'o';
  952. s[len2++] = 'p';
  953. break;
  954. case ']': /* [] */
  955. j++;
  956. s[len2++] = 'o';
  957. s[len2++] = 'b';
  958. break;
  959. }
  960. break;
  961. case '<':
  962. case '>':
  963. c = name[j] == '<' ? 'l' : 'g';
  964. s[len2++] = '_';
  965. switch (name[j + 1]) {
  966. case '\0':
  967. s[len2++] = c;
  968. s[len2++] = 't';
  969. break;
  970. case '=':
  971. j++;
  972. s[len2++] = c;
  973. s[len2++] = 'e';
  974. break;
  975. case '>':
  976. j++;
  977. s[len2++] = 's';
  978. s[len2++] = 'r';
  979. break;
  980. case '<':
  981. j++;
  982. s[len2++] = 's';
  983. s[len2++] = 'l';
  984. break;
  985. default:
  986. break;
  987. }
  988. break;
  989. case '_':
  990. if (len2 && s[len2 - 1] == '_')
  991. s[len2++] = 'u';
  992. /* fall through */
  993. default:
  994. s[len2++] = name[j];
  995. }
  996. if (s[len2 - 1] == '_')
  997. s[len2++] = 'u';
  998. s[len2] = '\0';
  999. return s;
  1000. }
  1001. /* Return true if DECL refers to a C++ class type for which a
  1002. separate enclosing package has been or should be generated. */
  1003. static bool
  1004. separate_class_package (tree decl)
  1005. {
  1006. tree type = TREE_TYPE (decl);
  1007. return has_nontrivial_methods (type) || has_static_fields (type);
  1008. }
  1009. static bool package_prefix = true;
  1010. /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
  1011. syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
  1012. 'with' clause rather than a regular 'with' clause. */
  1013. static void
  1014. pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type,
  1015. int limited_access)
  1016. {
  1017. const char *name = IDENTIFIER_POINTER (node);
  1018. int space_found = false;
  1019. char *s = to_ada_name (name, &space_found);
  1020. tree decl;
  1021. /* If the entity is a type and comes from another file, generate "package"
  1022. prefix. */
  1023. decl = get_underlying_decl (type);
  1024. if (decl)
  1025. {
  1026. expanded_location xloc = expand_location (decl_sloc (decl, false));
  1027. if (xloc.file && xloc.line)
  1028. {
  1029. if (xloc.file != source_file_base)
  1030. {
  1031. switch (TREE_CODE (type))
  1032. {
  1033. case ENUMERAL_TYPE:
  1034. case INTEGER_TYPE:
  1035. case REAL_TYPE:
  1036. case FIXED_POINT_TYPE:
  1037. case BOOLEAN_TYPE:
  1038. case REFERENCE_TYPE:
  1039. case POINTER_TYPE:
  1040. case ARRAY_TYPE:
  1041. case RECORD_TYPE:
  1042. case UNION_TYPE:
  1043. case QUAL_UNION_TYPE:
  1044. case TYPE_DECL:
  1045. if (package_prefix)
  1046. {
  1047. char *s1 = get_ada_package (xloc.file);
  1048. append_withs (s1, limited_access);
  1049. pp_string (buffer, s1);
  1050. pp_dot (buffer);
  1051. free (s1);
  1052. }
  1053. break;
  1054. default:
  1055. break;
  1056. }
  1057. /* Generate the additional package prefix for C++ classes. */
  1058. if (separate_class_package (decl))
  1059. {
  1060. pp_string (buffer, "Class_");
  1061. pp_string (buffer, s);
  1062. pp_dot (buffer);
  1063. }
  1064. }
  1065. }
  1066. }
  1067. if (space_found)
  1068. if (!strcmp (s, "short_int"))
  1069. pp_string (buffer, "short");
  1070. else if (!strcmp (s, "short_unsigned_int"))
  1071. pp_string (buffer, "unsigned_short");
  1072. else if (!strcmp (s, "unsigned_int"))
  1073. pp_string (buffer, "unsigned");
  1074. else if (!strcmp (s, "long_int"))
  1075. pp_string (buffer, "long");
  1076. else if (!strcmp (s, "long_unsigned_int"))
  1077. pp_string (buffer, "unsigned_long");
  1078. else if (!strcmp (s, "long_long_int"))
  1079. pp_string (buffer, "Long_Long_Integer");
  1080. else if (!strcmp (s, "long_long_unsigned_int"))
  1081. {
  1082. if (package_prefix)
  1083. {
  1084. append_withs ("Interfaces.C.Extensions", false);
  1085. pp_string (buffer, "Extensions.unsigned_long_long");
  1086. }
  1087. else
  1088. pp_string (buffer, "unsigned_long_long");
  1089. }
  1090. else
  1091. pp_string(buffer, s);
  1092. else
  1093. if (!strcmp (s, "bool"))
  1094. {
  1095. if (package_prefix)
  1096. {
  1097. append_withs ("Interfaces.C.Extensions", false);
  1098. pp_string (buffer, "Extensions.bool");
  1099. }
  1100. else
  1101. pp_string (buffer, "bool");
  1102. }
  1103. else
  1104. pp_string(buffer, s);
  1105. free (s);
  1106. }
  1107. /* Dump in BUFFER the assembly name of T. */
  1108. static void
  1109. pp_asm_name (pretty_printer *buffer, tree t)
  1110. {
  1111. tree name = DECL_ASSEMBLER_NAME (t);
  1112. char *ada_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (name) + 1), *s;
  1113. const char *ident = IDENTIFIER_POINTER (name);
  1114. for (s = ada_name; *ident; ident++)
  1115. {
  1116. if (*ident == ' ')
  1117. break;
  1118. else if (*ident != '*')
  1119. *s++ = *ident;
  1120. }
  1121. *s = '\0';
  1122. pp_string (buffer, ada_name);
  1123. }
  1124. /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
  1125. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
  1126. 'with' clause rather than a regular 'with' clause. */
  1127. static void
  1128. dump_ada_decl_name (pretty_printer *buffer, tree decl, int limited_access)
  1129. {
  1130. if (DECL_NAME (decl))
  1131. pp_ada_tree_identifier (buffer, DECL_NAME (decl), decl, limited_access);
  1132. else
  1133. {
  1134. tree type_name = TYPE_NAME (TREE_TYPE (decl));
  1135. if (!type_name)
  1136. {
  1137. pp_string (buffer, "anon");
  1138. if (TREE_CODE (decl) == FIELD_DECL)
  1139. pp_scalar (buffer, "%d", DECL_UID (decl));
  1140. else
  1141. pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (decl)));
  1142. }
  1143. else if (TREE_CODE (type_name) == IDENTIFIER_NODE)
  1144. pp_ada_tree_identifier (buffer, type_name, decl, limited_access);
  1145. }
  1146. }
  1147. /* Dump in BUFFER a name based on both T1 and T2, followed by S. */
  1148. static void
  1149. dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2, const char *s)
  1150. {
  1151. if (DECL_NAME (t1))
  1152. pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, false);
  1153. else
  1154. {
  1155. pp_string (buffer, "anon");
  1156. pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1)));
  1157. }
  1158. pp_underscore (buffer);
  1159. if (DECL_NAME (t2))
  1160. pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false);
  1161. else
  1162. {
  1163. pp_string (buffer, "anon");
  1164. pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2)));
  1165. }
  1166. pp_string (buffer, s);
  1167. }
  1168. /* Dump in BUFFER pragma Import C/CPP on a given node T. */
  1169. static void
  1170. dump_ada_import (pretty_printer *buffer, tree t)
  1171. {
  1172. const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
  1173. int is_stdcall = TREE_CODE (t) == FUNCTION_DECL &&
  1174. lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t)));
  1175. if (is_stdcall)
  1176. pp_string (buffer, "pragma Import (Stdcall, ");
  1177. else if (name[0] == '_' && name[1] == 'Z')
  1178. pp_string (buffer, "pragma Import (CPP, ");
  1179. else
  1180. pp_string (buffer, "pragma Import (C, ");
  1181. dump_ada_decl_name (buffer, t, false);
  1182. pp_string (buffer, ", \"");
  1183. if (is_stdcall)
  1184. pp_string (buffer, IDENTIFIER_POINTER (DECL_NAME (t)));
  1185. else
  1186. pp_asm_name (buffer, t);
  1187. pp_string (buffer, "\");");
  1188. }
  1189. /* Check whether T and its type have different names, and append "the_"
  1190. otherwise in BUFFER. */
  1191. static void
  1192. check_name (pretty_printer *buffer, tree t)
  1193. {
  1194. const char *s;
  1195. tree tmp = TREE_TYPE (t);
  1196. while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
  1197. tmp = TREE_TYPE (tmp);
  1198. if (TREE_CODE (tmp) != FUNCTION_TYPE)
  1199. {
  1200. if (TREE_CODE (tmp) == IDENTIFIER_NODE)
  1201. s = IDENTIFIER_POINTER (tmp);
  1202. else if (!TYPE_NAME (tmp))
  1203. s = "";
  1204. else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE)
  1205. s = IDENTIFIER_POINTER (TYPE_NAME (tmp));
  1206. else
  1207. s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp)));
  1208. if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t)), s))
  1209. pp_string (buffer, "the_");
  1210. }
  1211. }
  1212. /* Dump in BUFFER a function declaration FUNC with Ada syntax.
  1213. IS_METHOD indicates whether FUNC is a C++ method.
  1214. IS_CONSTRUCTOR whether FUNC is a C++ constructor.
  1215. IS_DESTRUCTOR whether FUNC is a C++ destructor.
  1216. SPC is the current indentation level. */
  1217. static int
  1218. dump_ada_function_declaration (pretty_printer *buffer, tree func,
  1219. int is_method, int is_constructor,
  1220. int is_destructor, int spc)
  1221. {
  1222. tree arg;
  1223. const tree node = TREE_TYPE (func);
  1224. char buf[16];
  1225. int num = 0, num_args = 0, have_args = true, have_ellipsis = false;
  1226. /* Compute number of arguments. */
  1227. arg = TYPE_ARG_TYPES (node);
  1228. if (arg)
  1229. {
  1230. while (TREE_CHAIN (arg) && arg != error_mark_node)
  1231. {
  1232. num_args++;
  1233. arg = TREE_CHAIN (arg);
  1234. }
  1235. if (TREE_CODE (TREE_VALUE (arg)) != VOID_TYPE)
  1236. {
  1237. num_args++;
  1238. have_ellipsis = true;
  1239. }
  1240. }
  1241. if (is_constructor)
  1242. num_args--;
  1243. if (is_destructor)
  1244. num_args = 1;
  1245. if (num_args > 2)
  1246. newline_and_indent (buffer, spc + 1);
  1247. if (num_args > 0)
  1248. {
  1249. pp_space (buffer);
  1250. pp_left_paren (buffer);
  1251. }
  1252. if (TREE_CODE (func) == FUNCTION_DECL)
  1253. arg = DECL_ARGUMENTS (func);
  1254. else
  1255. arg = NULL_TREE;
  1256. if (arg == NULL_TREE)
  1257. {
  1258. have_args = false;
  1259. arg = TYPE_ARG_TYPES (node);
  1260. if (arg && TREE_CODE (TREE_VALUE (arg)) == VOID_TYPE)
  1261. arg = NULL_TREE;
  1262. }
  1263. if (is_constructor)
  1264. arg = TREE_CHAIN (arg);
  1265. /* Print the argument names (if available) & types. */
  1266. for (num = 1; num <= num_args; num++)
  1267. {
  1268. if (have_args)
  1269. {
  1270. if (DECL_NAME (arg))
  1271. {
  1272. check_name (buffer, arg);
  1273. pp_ada_tree_identifier (buffer, DECL_NAME (arg), 0, false);
  1274. pp_string (buffer, " : ");
  1275. }
  1276. else
  1277. {
  1278. sprintf (buf, "arg%d : ", num);
  1279. pp_string (buffer, buf);
  1280. }
  1281. dump_generic_ada_node (buffer, TREE_TYPE (arg), node, spc, 0, true);
  1282. }
  1283. else
  1284. {
  1285. sprintf (buf, "arg%d : ", num);
  1286. pp_string (buffer, buf);
  1287. dump_generic_ada_node (buffer, TREE_VALUE (arg), node, spc, 0, true);
  1288. }
  1289. if (TREE_TYPE (arg) && TREE_TYPE (TREE_TYPE (arg))
  1290. && is_tagged_type (TREE_TYPE (TREE_TYPE (arg))))
  1291. {
  1292. if (!is_method
  1293. || (num != 1 || (!DECL_VINDEX (func) && !is_constructor)))
  1294. pp_string (buffer, "'Class");
  1295. }
  1296. arg = TREE_CHAIN (arg);
  1297. if (num < num_args)
  1298. {
  1299. pp_semicolon (buffer);
  1300. if (num_args > 2)
  1301. newline_and_indent (buffer, spc + INDENT_INCR);
  1302. else
  1303. pp_space (buffer);
  1304. }
  1305. }
  1306. if (have_ellipsis)
  1307. {
  1308. pp_string (buffer, " -- , ...");
  1309. newline_and_indent (buffer, spc + INDENT_INCR);
  1310. }
  1311. if (num_args > 0)
  1312. pp_right_paren (buffer);
  1313. return num_args;
  1314. }
  1315. /* Dump in BUFFER all the domains associated with an array NODE,
  1316. using Ada syntax. SPC is the current indentation level. */
  1317. static void
  1318. dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
  1319. {
  1320. int first = 1;
  1321. pp_left_paren (buffer);
  1322. for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node))
  1323. {
  1324. tree domain = TYPE_DOMAIN (node);
  1325. if (domain)
  1326. {
  1327. tree min = TYPE_MIN_VALUE (domain);
  1328. tree max = TYPE_MAX_VALUE (domain);
  1329. if (!first)
  1330. pp_string (buffer, ", ");
  1331. first = 0;
  1332. if (min)
  1333. dump_generic_ada_node (buffer, min, NULL_TREE, spc, 0, true);
  1334. pp_string (buffer, " .. ");
  1335. /* If the upper bound is zero, gcc may generate a NULL_TREE
  1336. for TYPE_MAX_VALUE rather than an integer_cst. */
  1337. if (max)
  1338. dump_generic_ada_node (buffer, max, NULL_TREE, spc, 0, true);
  1339. else
  1340. pp_string (buffer, "0");
  1341. }
  1342. else
  1343. pp_string (buffer, "size_t");
  1344. }
  1345. pp_right_paren (buffer);
  1346. }
  1347. /* Dump in BUFFER file:line information related to NODE. */
  1348. static void
  1349. dump_sloc (pretty_printer *buffer, tree node)
  1350. {
  1351. expanded_location xloc;
  1352. xloc.file = NULL;
  1353. if (TREE_CODE_CLASS (TREE_CODE (node)) == tcc_declaration)
  1354. xloc = expand_location (DECL_SOURCE_LOCATION (node));
  1355. else if (EXPR_HAS_LOCATION (node))
  1356. xloc = expand_location (EXPR_LOCATION (node));
  1357. if (xloc.file)
  1358. {
  1359. pp_string (buffer, xloc.file);
  1360. pp_colon (buffer);
  1361. pp_decimal_int (buffer, xloc.line);
  1362. }
  1363. }
  1364. /* Return true if T designates a one dimension array of "char". */
  1365. static bool
  1366. is_char_array (tree t)
  1367. {
  1368. tree tmp;
  1369. int num_dim = 0;
  1370. /* Retrieve array's type. */
  1371. tmp = t;
  1372. while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
  1373. {
  1374. num_dim++;
  1375. tmp = TREE_TYPE (tmp);
  1376. }
  1377. tmp = TREE_TYPE (tmp);
  1378. return num_dim == 1 && TREE_CODE (tmp) == INTEGER_TYPE
  1379. && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp))), "char");
  1380. }
  1381. /* Dump in BUFFER an array type T in Ada syntax. Assume that the "type"
  1382. keyword and name have already been printed. SPC is the indentation
  1383. level. */
  1384. static void
  1385. dump_ada_array_type (pretty_printer *buffer, tree t, int spc)
  1386. {
  1387. tree tmp;
  1388. bool char_array = is_char_array (t);
  1389. /* Special case char arrays. */
  1390. if (char_array)
  1391. {
  1392. pp_string (buffer, "Interfaces.C.char_array ");
  1393. }
  1394. else
  1395. pp_string (buffer, "array ");
  1396. /* Print the dimensions. */
  1397. dump_ada_array_domains (buffer, TREE_TYPE (t), spc);
  1398. /* Retrieve array's type. */
  1399. tmp = TREE_TYPE (t);
  1400. while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
  1401. tmp = TREE_TYPE (tmp);
  1402. /* Print array's type. */
  1403. if (!char_array)
  1404. {
  1405. pp_string (buffer, " of ");
  1406. if (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE)
  1407. pp_string (buffer, "aliased ");
  1408. dump_generic_ada_node
  1409. (buffer, TREE_TYPE (tmp), TREE_TYPE (t), spc, false, true);
  1410. }
  1411. }
  1412. /* Dump in BUFFER type names associated with a template, each prepended with
  1413. '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS. SPC is
  1414. the indentation level. */
  1415. static void
  1416. dump_template_types (pretty_printer *buffer, tree types, int spc)
  1417. {
  1418. size_t i;
  1419. size_t len = TREE_VEC_LENGTH (types);
  1420. for (i = 0; i < len; i++)
  1421. {
  1422. tree elem = TREE_VEC_ELT (types, i);
  1423. pp_underscore (buffer);
  1424. if (!dump_generic_ada_node (buffer, elem, 0, spc, false, true))
  1425. {
  1426. pp_string (buffer, "unknown");
  1427. pp_scalar (buffer, "%lu", (unsigned long) TREE_HASH (elem));
  1428. }
  1429. }
  1430. }
  1431. /* Dump in BUFFER the contents of all class instantiations associated with
  1432. a given template T. SPC is the indentation level. */
  1433. static int
  1434. dump_ada_template (pretty_printer *buffer, tree t, int spc)
  1435. {
  1436. /* DECL_SIZE_UNIT is DECL_TEMPLATE_INSTANTIATIONS in this context. */
  1437. tree inst = DECL_SIZE_UNIT (t);
  1438. /* This emulates DECL_TEMPLATE_RESULT in this context. */
  1439. struct tree_template_decl {
  1440. struct tree_decl_common common;
  1441. tree arguments;
  1442. tree result;
  1443. };
  1444. tree result = ((struct tree_template_decl *) t)->result;
  1445. int num_inst = 0;
  1446. /* Don't look at template declarations declaring something coming from
  1447. another file. This can occur for template friend declarations. */
  1448. if (LOCATION_FILE (decl_sloc (result, false))
  1449. != LOCATION_FILE (decl_sloc (t, false)))
  1450. return 0;
  1451. while (inst && inst != error_mark_node)
  1452. {
  1453. tree types = TREE_PURPOSE (inst);
  1454. tree instance = TREE_VALUE (inst);
  1455. if (TREE_VEC_LENGTH (types) == 0)
  1456. break;
  1457. if (!RECORD_OR_UNION_TYPE_P (instance) || !TYPE_METHODS (instance))
  1458. break;
  1459. num_inst++;
  1460. INDENT (spc);
  1461. pp_string (buffer, "package ");
  1462. package_prefix = false;
  1463. dump_generic_ada_node (buffer, instance, t, spc, false, true);
  1464. dump_template_types (buffer, types, spc);
  1465. pp_string (buffer, " is");
  1466. spc += INDENT_INCR;
  1467. newline_and_indent (buffer, spc);
  1468. TREE_VISITED (get_underlying_decl (instance)) = 1;
  1469. pp_string (buffer, "type ");
  1470. dump_generic_ada_node (buffer, instance, t, spc, false, true);
  1471. package_prefix = true;
  1472. if (is_tagged_type (instance))
  1473. pp_string (buffer, " is tagged limited ");
  1474. else
  1475. pp_string (buffer, " is limited ");
  1476. dump_generic_ada_node (buffer, instance, t, spc, false, false);
  1477. pp_newline (buffer);
  1478. spc -= INDENT_INCR;
  1479. newline_and_indent (buffer, spc);
  1480. pp_string (buffer, "end;");
  1481. newline_and_indent (buffer, spc);
  1482. pp_string (buffer, "use ");
  1483. package_prefix = false;
  1484. dump_generic_ada_node (buffer, instance, t, spc, false, true);
  1485. dump_template_types (buffer, types, spc);
  1486. package_prefix = true;
  1487. pp_semicolon (buffer);
  1488. pp_newline (buffer);
  1489. pp_newline (buffer);
  1490. inst = TREE_CHAIN (inst);
  1491. }
  1492. return num_inst > 0;
  1493. }
  1494. /* Return true if NODE is a simple enum types, that can be mapped to an
  1495. Ada enum type directly. */
  1496. static bool
  1497. is_simple_enum (tree node)
  1498. {
  1499. HOST_WIDE_INT count = 0;
  1500. tree value;
  1501. for (value = TYPE_VALUES (node); value; value = TREE_CHAIN (value))
  1502. {
  1503. tree int_val = TREE_VALUE (value);
  1504. if (TREE_CODE (int_val) != INTEGER_CST)
  1505. int_val = DECL_INITIAL (int_val);
  1506. if (!tree_fits_shwi_p (int_val))
  1507. return false;
  1508. else if (tree_to_shwi (int_val) != count)
  1509. return false;
  1510. count++;
  1511. }
  1512. return true;
  1513. }
  1514. static bool bitfield_used = false;
  1515. /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
  1516. TYPE. SPC is the indentation level. LIMITED_ACCESS indicates whether NODE
  1517. can be referenced via a "limited with" clause. NAME_ONLY indicates whether
  1518. we should only dump the name of NODE, instead of its full declaration. */
  1519. static int
  1520. dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
  1521. int limited_access, bool name_only)
  1522. {
  1523. if (node == NULL_TREE)
  1524. return 0;
  1525. switch (TREE_CODE (node))
  1526. {
  1527. case ERROR_MARK:
  1528. pp_string (buffer, "<<< error >>>");
  1529. return 0;
  1530. case IDENTIFIER_NODE:
  1531. pp_ada_tree_identifier (buffer, node, type, limited_access);
  1532. break;
  1533. case TREE_LIST:
  1534. pp_string (buffer, "--- unexpected node: TREE_LIST");
  1535. return 0;
  1536. case TREE_BINFO:
  1537. dump_generic_ada_node
  1538. (buffer, BINFO_TYPE (node), type, spc, limited_access, name_only);
  1539. case TREE_VEC:
  1540. pp_string (buffer, "--- unexpected node: TREE_VEC");
  1541. return 0;
  1542. case VOID_TYPE:
  1543. if (package_prefix)
  1544. {
  1545. append_withs ("System", false);
  1546. pp_string (buffer, "System.Address");
  1547. }
  1548. else
  1549. pp_string (buffer, "address");
  1550. break;
  1551. case VECTOR_TYPE:
  1552. pp_string (buffer, "<vector>");
  1553. break;
  1554. case COMPLEX_TYPE:
  1555. pp_string (buffer, "<complex>");
  1556. break;
  1557. case ENUMERAL_TYPE:
  1558. if (name_only)
  1559. dump_generic_ada_node
  1560. (buffer, TYPE_NAME (node), node, spc, 0, true);
  1561. else
  1562. {
  1563. tree value = TYPE_VALUES (node);
  1564. if (is_simple_enum (node))
  1565. {
  1566. bool first = true;
  1567. spc += INDENT_INCR;
  1568. newline_and_indent (buffer, spc - 1);
  1569. pp_left_paren (buffer);
  1570. for (; value; value = TREE_CHAIN (value))
  1571. {
  1572. if (first)
  1573. first = false;
  1574. else
  1575. {
  1576. pp_comma (buffer);
  1577. newline_and_indent (buffer, spc);
  1578. }
  1579. pp_ada_tree_identifier
  1580. (buffer, TREE_PURPOSE (value), node, false);
  1581. }
  1582. pp_string (buffer, ");");
  1583. spc -= INDENT_INCR;
  1584. newline_and_indent (buffer, spc);
  1585. pp_string (buffer, "pragma Convention (C, ");
  1586. dump_generic_ada_node
  1587. (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type,
  1588. spc, 0, true);
  1589. pp_right_paren (buffer);
  1590. }
  1591. else
  1592. {
  1593. pp_string (buffer, "unsigned");
  1594. for (; value; value = TREE_CHAIN (value))
  1595. {
  1596. pp_semicolon (buffer);
  1597. newline_and_indent (buffer, spc);
  1598. pp_ada_tree_identifier
  1599. (buffer, TREE_PURPOSE (value), node, false);
  1600. pp_string (buffer, " : constant ");
  1601. dump_generic_ada_node
  1602. (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type,
  1603. spc, 0, true);
  1604. pp_string (buffer, " := ");
  1605. dump_generic_ada_node
  1606. (buffer,
  1607. TREE_CODE (TREE_VALUE (value)) == INTEGER_CST ?
  1608. TREE_VALUE (value) : DECL_INITIAL (TREE_VALUE (value)),
  1609. node, spc, false, true);
  1610. }
  1611. }
  1612. }
  1613. break;
  1614. case INTEGER_TYPE:
  1615. case REAL_TYPE:
  1616. case FIXED_POINT_TYPE:
  1617. case BOOLEAN_TYPE:
  1618. {
  1619. enum tree_code_class tclass;
  1620. tclass = TREE_CODE_CLASS (TREE_CODE (node));
  1621. if (tclass == tcc_declaration)
  1622. {
  1623. if (DECL_NAME (node))
  1624. pp_ada_tree_identifier
  1625. (buffer, DECL_NAME (node), 0, limited_access);
  1626. else
  1627. pp_string (buffer, "<unnamed type decl>");
  1628. }
  1629. else if (tclass == tcc_type)
  1630. {
  1631. if (TYPE_NAME (node))
  1632. {
  1633. if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
  1634. pp_ada_tree_identifier (buffer, TYPE_NAME (node),
  1635. node, limited_access);
  1636. else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
  1637. && DECL_NAME (TYPE_NAME (node)))
  1638. dump_ada_decl_name (buffer, TYPE_NAME (node), limited_access);
  1639. else
  1640. pp_string (buffer, "<unnamed type>");
  1641. }
  1642. else if (TREE_CODE (node) == INTEGER_TYPE)
  1643. {
  1644. append_withs ("Interfaces.C.Extensions", false);
  1645. bitfield_used = true;
  1646. if (TYPE_PRECISION (node) == 1)
  1647. pp_string (buffer, "Extensions.Unsigned_1");
  1648. else
  1649. {
  1650. pp_string (buffer, (TYPE_UNSIGNED (node)
  1651. ? "Extensions.Unsigned_"
  1652. : "Extensions.Signed_"));
  1653. pp_decimal_int (buffer, TYPE_PRECISION (node));
  1654. }
  1655. }
  1656. else
  1657. pp_string (buffer, "<unnamed type>");
  1658. }
  1659. break;
  1660. }
  1661. case POINTER_TYPE:
  1662. case REFERENCE_TYPE:
  1663. if (name_only && TYPE_NAME (node))
  1664. dump_generic_ada_node
  1665. (buffer, TYPE_NAME (node), node, spc, limited_access, true);
  1666. else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
  1667. {
  1668. tree fnode = TREE_TYPE (node);
  1669. bool is_function;
  1670. if (VOID_TYPE_P (TREE_TYPE (fnode)))
  1671. {
  1672. is_function = false;
  1673. pp_string (buffer, "access procedure");
  1674. }
  1675. else
  1676. {
  1677. is_function = true;
  1678. pp_string (buffer, "access function");
  1679. }
  1680. dump_ada_function_declaration
  1681. (buffer, node, false, false, false, spc + INDENT_INCR);
  1682. if (is_function)
  1683. {
  1684. pp_string (buffer, " return ");
  1685. dump_generic_ada_node
  1686. (buffer, TREE_TYPE (fnode), type, spc, 0, true);
  1687. }
  1688. /* If we are dumping the full type, it means we are part of a
  1689. type definition and need also a Convention C pragma. */
  1690. if (!name_only)
  1691. {
  1692. pp_semicolon (buffer);
  1693. newline_and_indent (buffer, spc);
  1694. pp_string (buffer, "pragma Convention (C, ");
  1695. dump_generic_ada_node
  1696. (buffer, type, 0, spc, false, true);
  1697. pp_right_paren (buffer);
  1698. }
  1699. }
  1700. else
  1701. {
  1702. int is_access = false;
  1703. unsigned int quals = TYPE_QUALS (TREE_TYPE (node));
  1704. if (VOID_TYPE_P (TREE_TYPE (node)))
  1705. {
  1706. if (!name_only)
  1707. pp_string (buffer, "new ");
  1708. if (package_prefix)
  1709. {
  1710. append_withs ("System", false);
  1711. pp_string (buffer, "System.Address");
  1712. }
  1713. else
  1714. pp_string (buffer, "address");
  1715. }
  1716. else
  1717. {
  1718. if (TREE_CODE (node) == POINTER_TYPE
  1719. && TREE_CODE (TREE_TYPE (node)) == INTEGER_TYPE
  1720. && !strcmp
  1721. (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
  1722. (TREE_TYPE (node)))), "char"))
  1723. {
  1724. if (!name_only)
  1725. pp_string (buffer, "new ");
  1726. if (package_prefix)
  1727. {
  1728. pp_string (buffer, "Interfaces.C.Strings.chars_ptr");
  1729. append_withs ("Interfaces.C.Strings", false);
  1730. }
  1731. else
  1732. pp_string (buffer, "chars_ptr");
  1733. }
  1734. else
  1735. {
  1736. /* For now, handle all access-to-access or
  1737. access-to-unknown-structs as opaque system.address. */
  1738. tree type_name = TYPE_NAME (TREE_TYPE (node));
  1739. const_tree typ2 = !type ||
  1740. DECL_P (type) ? type : TYPE_NAME (type);
  1741. const_tree underlying_type =
  1742. get_underlying_decl (TREE_TYPE (node));
  1743. if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
  1744. /* Pointer to pointer. */
  1745. || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node))
  1746. && (!underlying_type
  1747. || !TYPE_FIELDS (TREE_TYPE (underlying_type))))
  1748. /* Pointer to opaque structure. */
  1749. || underlying_type == NULL_TREE
  1750. || (!typ2
  1751. && !TREE_VISITED (underlying_type)
  1752. && !TREE_VISITED (type_name)
  1753. && !is_tagged_type (TREE_TYPE (node))
  1754. && DECL_SOURCE_FILE (underlying_type)
  1755. == source_file_base)
  1756. || (type_name && typ2
  1757. && DECL_P (underlying_type)
  1758. && DECL_P (typ2)
  1759. && decl_sloc (underlying_type, true)
  1760. > decl_sloc (typ2, true)
  1761. && DECL_SOURCE_FILE (underlying_type)
  1762. == DECL_SOURCE_FILE (typ2)))
  1763. {
  1764. if (package_prefix)
  1765. {
  1766. append_withs ("System", false);
  1767. if (!name_only)
  1768. pp_string (buffer, "new ");
  1769. pp_string (buffer, "System.Address");
  1770. }
  1771. else
  1772. pp_string (buffer, "address");
  1773. return spc;
  1774. }
  1775. if (!package_prefix)
  1776. pp_string (buffer, "access");
  1777. else if (AGGREGATE_TYPE_P (TREE_TYPE (node)))
  1778. {
  1779. if (!type || TREE_CODE (type) != FUNCTION_DECL)
  1780. {
  1781. pp_string (buffer, "access ");
  1782. is_access = true;
  1783. if (quals & TYPE_QUAL_CONST)
  1784. pp_string (buffer, "constant ");
  1785. else if (!name_only)
  1786. pp_string (buffer, "all ");
  1787. }
  1788. else if (quals & TYPE_QUAL_CONST)
  1789. pp_string (buffer, "in ");
  1790. else
  1791. {
  1792. is_access = true;
  1793. pp_string (buffer, "access ");
  1794. /* ??? should be configurable: access or in out. */
  1795. }
  1796. }
  1797. else
  1798. {
  1799. is_access = true;
  1800. pp_string (buffer, "access ");
  1801. if (!name_only)
  1802. pp_string (buffer, "all ");
  1803. }
  1804. if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node))
  1805. && type_name != NULL_TREE)
  1806. dump_generic_ada_node
  1807. (buffer, type_name,
  1808. TREE_TYPE (node), spc, is_access, true);
  1809. else
  1810. dump_generic_ada_node
  1811. (buffer, TREE_TYPE (node), TREE_TYPE (node),
  1812. spc, 0, true);
  1813. }
  1814. }
  1815. }
  1816. break;
  1817. case ARRAY_TYPE:
  1818. if (name_only)
  1819. dump_generic_ada_node
  1820. (buffer, TYPE_NAME (node), node, spc, limited_access, true);
  1821. else
  1822. dump_ada_array_type (buffer, node, spc);
  1823. break;
  1824. case RECORD_TYPE:
  1825. case UNION_TYPE:
  1826. case QUAL_UNION_TYPE:
  1827. if (name_only)
  1828. {
  1829. if (TYPE_NAME (node))
  1830. dump_generic_ada_node
  1831. (buffer, TYPE_NAME (node), node, spc, limited_access, true);
  1832. else
  1833. {
  1834. pp_string (buffer, "anon_");
  1835. pp_scalar (buffer, "%d", TYPE_UID (node));
  1836. }
  1837. }
  1838. else
  1839. print_ada_struct_decl (buffer, node, type, spc, true);
  1840. break;
  1841. case INTEGER_CST:
  1842. /* We treat the upper half of the sizetype range as negative. This
  1843. is consistent with the internal treatment and makes it possible
  1844. to generate the (0 .. -1) range for flexible array members. */
  1845. if (TREE_TYPE (node) == sizetype)
  1846. node = fold_convert (ssizetype, node);
  1847. if (tree_fits_shwi_p (node))
  1848. pp_wide_integer (buffer, tree_to_shwi (node));
  1849. else if (tree_fits_uhwi_p (node))
  1850. pp_unsigned_wide_integer (buffer, tree_to_uhwi (node));
  1851. else
  1852. {
  1853. wide_int val = node;
  1854. int i;
  1855. if (wi::neg_p (val))
  1856. {
  1857. pp_minus (buffer);
  1858. val = -val;
  1859. }
  1860. sprintf (pp_buffer (buffer)->digit_buffer,
  1861. "16#%" HOST_WIDE_INT_PRINT "x",
  1862. val.elt (val.get_len () - 1));
  1863. for (i = val.get_len () - 2; i >= 0; i--)
  1864. sprintf (pp_buffer (buffer)->digit_buffer,
  1865. HOST_WIDE_INT_PRINT_PADDED_HEX, val.elt (i));
  1866. pp_string (buffer, pp_buffer (buffer)->digit_buffer);
  1867. }
  1868. break;
  1869. case REAL_CST:
  1870. case FIXED_CST:
  1871. case COMPLEX_CST:
  1872. case STRING_CST:
  1873. case VECTOR_CST:
  1874. return 0;
  1875. case FUNCTION_DECL:
  1876. case CONST_DECL:
  1877. dump_ada_decl_name (buffer, node, limited_access);
  1878. break;
  1879. case TYPE_DECL:
  1880. if (DECL_IS_BUILTIN (node))
  1881. {
  1882. /* Don't print the declaration of built-in types. */
  1883. if (name_only)
  1884. {
  1885. /* If we're in the middle of a declaration, defaults to
  1886. System.Address. */
  1887. if (package_prefix)
  1888. {
  1889. append_withs ("System", false);
  1890. pp_string (buffer, "System.Address");
  1891. }
  1892. else
  1893. pp_string (buffer, "address");
  1894. }
  1895. break;
  1896. }
  1897. if (name_only)
  1898. dump_ada_decl_name (buffer, node, limited_access);
  1899. else
  1900. {
  1901. if (is_tagged_type (TREE_TYPE (node)))
  1902. {
  1903. tree tmp = TYPE_FIELDS (TREE_TYPE (node));
  1904. int first = 1;
  1905. /* Look for ancestors. */
  1906. for (; tmp; tmp = TREE_CHAIN (tmp))
  1907. {
  1908. if (!DECL_NAME (tmp) && is_tagged_type (TREE_TYPE (tmp)))
  1909. {
  1910. if (first)
  1911. {
  1912. pp_string (buffer, "limited new ");
  1913. first = 0;
  1914. }
  1915. else
  1916. pp_string (buffer, " and ");
  1917. dump_ada_decl_name
  1918. (buffer, TYPE_NAME (TREE_TYPE (tmp)), false);
  1919. }
  1920. }
  1921. pp_string (buffer, first ? "tagged limited " : " with ");
  1922. }
  1923. else if (has_nontrivial_methods (TREE_TYPE (node)))
  1924. pp_string (buffer, "limited ");
  1925. dump_generic_ada_node
  1926. (buffer, TREE_TYPE (node), type, spc, false, false);
  1927. }
  1928. break;
  1929. case VAR_DECL:
  1930. case PARM_DECL:
  1931. case FIELD_DECL:
  1932. case NAMESPACE_DECL:
  1933. dump_ada_decl_name (buffer, node, false);
  1934. break;
  1935. default:
  1936. /* Ignore other nodes (e.g. expressions). */
  1937. return 0;
  1938. }
  1939. return 1;
  1940. }
  1941. /* Dump in BUFFER NODE's methods. SPC is the indentation level. Return 1 if
  1942. methods were printed, 0 otherwise.
  1943. We do it in 2 passes: first, the regular methods, i.e. non-static member
  1944. functions, are output immediately within the package created for the class
  1945. so that they are considered as primitive operations in Ada; second, the
  1946. static member functions are output in a nested package so that they are
  1947. _not_ considered as primitive operations in Ada.
  1948. This approach is necessary because the formers have the implicit 'this'
  1949. pointer whereas the latters don't and, on 32-bit x86/Windows, the calling
  1950. conventions for the 'this' pointer are special. Therefore, the compiler
  1951. needs to be able to differentiate regular methods (with 'this' pointer)
  1952. from static member functions that take a pointer to the class as first
  1953. parameter. */
  1954. static int
  1955. print_ada_methods (pretty_printer *buffer, tree node, int spc)
  1956. {
  1957. bool has_static_methods = false;
  1958. tree t;
  1959. int res;
  1960. if (!has_nontrivial_methods (node))
  1961. return 0;
  1962. pp_semicolon (buffer);
  1963. /* First pass: the regular methods. */
  1964. res = 1;
  1965. for (t = TYPE_METHODS (node); t; t = TREE_CHAIN (t))
  1966. {
  1967. if (TREE_CODE (TREE_TYPE (t)) != METHOD_TYPE)
  1968. {
  1969. has_static_methods = true;
  1970. continue;
  1971. }
  1972. if (res)
  1973. {
  1974. pp_newline (buffer);
  1975. pp_newline (buffer);
  1976. }
  1977. res = print_ada_declaration (buffer, t, node, spc);
  1978. }
  1979. if (!has_static_methods)
  1980. return 1;
  1981. pp_newline (buffer);
  1982. newline_and_indent (buffer, spc);
  1983. /* Second pass: the static member functions. */
  1984. pp_string (buffer, "package Static is");
  1985. pp_newline (buffer);
  1986. spc += INDENT_INCR;
  1987. res = 0;
  1988. for (t = TYPE_METHODS (node); t; t = TREE_CHAIN (t))
  1989. {
  1990. if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)
  1991. continue;
  1992. if (res)
  1993. {
  1994. pp_newline (buffer);
  1995. pp_newline (buffer);
  1996. }
  1997. res = print_ada_declaration (buffer, t, node, spc);
  1998. }
  1999. spc -= INDENT_INCR;
  2000. newline_and_indent (buffer, spc);
  2001. pp_string (buffer, "end;");
  2002. /* In order to save the clients from adding a second use clause for the
  2003. nested package, we generate renamings for the static member functions
  2004. in the package created for the class. */
  2005. for (t = TYPE_METHODS (node); t; t = TREE_CHAIN (t))
  2006. {
  2007. bool is_function;
  2008. if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)
  2009. continue;
  2010. pp_newline (buffer);
  2011. newline_and_indent (buffer, spc);
  2012. if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
  2013. {
  2014. pp_string (buffer, "procedure ");
  2015. is_function = false;
  2016. }
  2017. else
  2018. {
  2019. pp_string (buffer, "function ");
  2020. is_function = true;
  2021. }
  2022. dump_ada_decl_name (buffer, t, false);
  2023. dump_ada_function_declaration (buffer, t, false, false, false, spc);
  2024. if (is_function)
  2025. {
  2026. pp_string (buffer, " return ");
  2027. dump_generic_ada_node (buffer, TREE_TYPE (TREE_TYPE (t)), node,
  2028. spc, false, true);
  2029. }
  2030. pp_string (buffer, " renames Static.");
  2031. dump_ada_decl_name (buffer, t, false);
  2032. pp_semicolon (buffer);
  2033. }
  2034. return 1;
  2035. }
  2036. /* Dump in BUFFER anonymous types nested inside T's definition.
  2037. PARENT is the parent node of T.
  2038. FORWARD indicates whether a forward declaration of T should be generated.
  2039. SPC is the indentation level. */
  2040. static void
  2041. dump_nested_types (pretty_printer *buffer, tree t, tree parent, bool forward,
  2042. int spc)
  2043. {
  2044. tree field, outer, decl;
  2045. /* Avoid recursing over the same tree. */
  2046. if (TREE_VISITED (t))
  2047. return;
  2048. /* Find possible anonymous arrays/unions/structs recursively. */
  2049. outer = TREE_TYPE (t);
  2050. if (outer == NULL_TREE)
  2051. return;
  2052. if (forward)
  2053. {
  2054. pp_string (buffer, "type ");
  2055. dump_generic_ada_node (buffer, t, t, spc, false, true);
  2056. pp_semicolon (buffer);
  2057. newline_and_indent (buffer, spc);
  2058. TREE_VISITED (t) = 1;
  2059. }
  2060. field = TYPE_FIELDS (outer);
  2061. while (field)
  2062. {
  2063. if ((TREE_TYPE (field) != outer
  2064. || (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
  2065. && TREE_TYPE (TREE_TYPE (field)) != outer))
  2066. && (!TYPE_NAME (TREE_TYPE (field))
  2067. || (TREE_CODE (field) == TYPE_DECL
  2068. && DECL_NAME (field) != DECL_NAME (t)
  2069. && TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (outer))))
  2070. {
  2071. switch (TREE_CODE (TREE_TYPE (field)))
  2072. {
  2073. case POINTER_TYPE:
  2074. decl = TREE_TYPE (TREE_TYPE (field));
  2075. if (TREE_CODE (decl) == FUNCTION_TYPE)
  2076. for (decl = TREE_TYPE (decl);
  2077. decl && TREE_CODE (decl) == POINTER_TYPE;
  2078. decl = TREE_TYPE (decl))
  2079. ;
  2080. decl = get_underlying_decl (decl);
  2081. if (decl
  2082. && DECL_P (decl)
  2083. && decl_sloc (decl, true) > decl_sloc (t, true)
  2084. && DECL_SOURCE_FILE (decl) == DECL_SOURCE_FILE (t)
  2085. && !TREE_VISITED (decl)
  2086. && !DECL_IS_BUILTIN (decl)
  2087. && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
  2088. || TYPE_FIELDS (TREE_TYPE (decl))))
  2089. {
  2090. /* Generate forward declaration. */
  2091. pp_string (buffer, "type ");
  2092. dump_generic_ada_node (buffer, decl, 0, spc, false, true);
  2093. pp_semicolon (buffer);
  2094. newline_and_indent (buffer, spc);
  2095. /* Ensure we do not generate duplicate forward
  2096. declarations for this type. */
  2097. TREE_VISITED (decl) = 1;
  2098. }
  2099. break;
  2100. case ARRAY_TYPE:
  2101. /* Special case char arrays. */
  2102. if (is_char_array (field))
  2103. pp_string (buffer, "sub");
  2104. pp_string (buffer, "type ");
  2105. dump_ada_double_name (buffer, parent, field, "_array is ");
  2106. dump_ada_array_type (buffer, field, spc);
  2107. pp_semicolon (buffer);
  2108. newline_and_indent (buffer, spc);
  2109. break;
  2110. case UNION_TYPE:
  2111. TREE_VISITED (t) = 1;
  2112. dump_nested_types (buffer, field, t, false, spc);
  2113. pp_string (buffer, "type ");
  2114. if (TYPE_NAME (TREE_TYPE (field)))
  2115. {
  2116. dump_generic_ada_node
  2117. (buffer, TYPE_NAME (TREE_TYPE (field)), 0, spc, false,
  2118. true);
  2119. pp_string (buffer, " (discr : unsigned := 0) is ");
  2120. print_ada_struct_decl
  2121. (buffer, TREE_TYPE (field), t, spc, false);
  2122. pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
  2123. dump_generic_ada_node
  2124. (buffer, TREE_TYPE (field), 0, spc, false, true);
  2125. pp_string (buffer, ");");
  2126. newline_and_indent (buffer, spc);
  2127. pp_string (buffer, "pragma Unchecked_Union (");
  2128. dump_generic_ada_node
  2129. (buffer, TREE_TYPE (field), 0, spc, false, true);
  2130. pp_string (buffer, ");");
  2131. }
  2132. else
  2133. {
  2134. dump_ada_double_name
  2135. (buffer, parent, field,
  2136. "_union (discr : unsigned := 0) is ");
  2137. print_ada_struct_decl
  2138. (buffer, TREE_TYPE (field), t, spc, false);
  2139. pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
  2140. dump_ada_double_name (buffer, parent, field, "_union);");
  2141. newline_and_indent (buffer, spc);
  2142. pp_string (buffer, "pragma Unchecked_Union (");
  2143. dump_ada_double_name (buffer, parent, field, "_union);");
  2144. }
  2145. newline_and_indent (buffer, spc);
  2146. break;
  2147. case RECORD_TYPE:
  2148. if (TYPE_NAME (TREE_TYPE (t)) && !TREE_VISITED (t))
  2149. {
  2150. pp_string (buffer, "type ");
  2151. dump_generic_ada_node
  2152. (buffer, t, parent, spc, false, true);
  2153. pp_semicolon (buffer);
  2154. newline_and_indent (buffer, spc);
  2155. }
  2156. TREE_VISITED (t) = 1;
  2157. dump_nested_types (buffer, field, t, false, spc);
  2158. pp_string (buffer, "type ");
  2159. if (TYPE_NAME (TREE_TYPE (field)))
  2160. {
  2161. dump_generic_ada_node
  2162. (buffer, TREE_TYPE (field), 0, spc, false, true);
  2163. pp_string (buffer, " is ");
  2164. print_ada_struct_decl
  2165. (buffer, TREE_TYPE (field), t, spc, false);
  2166. pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
  2167. dump_generic_ada_node
  2168. (buffer, TREE_TYPE (field), 0, spc, false, true);
  2169. pp_string (buffer, ");");
  2170. }
  2171. else
  2172. {
  2173. dump_ada_double_name
  2174. (buffer, parent, field, "_struct is ");
  2175. print_ada_struct_decl
  2176. (buffer, TREE_TYPE (field), t, spc, false);
  2177. pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
  2178. dump_ada_double_name (buffer, parent, field, "_struct);");
  2179. }
  2180. newline_and_indent (buffer, spc);
  2181. break;
  2182. default:
  2183. break;
  2184. }
  2185. }
  2186. field = TREE_CHAIN (field);
  2187. }
  2188. TREE_VISITED (t) = 1;
  2189. }
  2190. /* Dump in BUFFER constructor spec corresponding to T. */
  2191. static void
  2192. print_constructor (pretty_printer *buffer, tree t)
  2193. {
  2194. tree decl_name = DECL_NAME (DECL_ORIGIN (t));
  2195. pp_string (buffer, "New_");
  2196. pp_ada_tree_identifier (buffer, decl_name, t, false);
  2197. }
  2198. /* Dump in BUFFER destructor spec corresponding to T. */
  2199. static void
  2200. print_destructor (pretty_printer *buffer, tree t)
  2201. {
  2202. tree decl_name = DECL_NAME (DECL_ORIGIN (t));
  2203. pp_string (buffer, "Delete_");
  2204. pp_ada_tree_identifier (buffer, decl_name, t, false);
  2205. }
  2206. /* Return the name of type T. */
  2207. static const char *
  2208. type_name (tree t)
  2209. {
  2210. tree n = TYPE_NAME (t);
  2211. if (TREE_CODE (n) == IDENTIFIER_NODE)
  2212. return IDENTIFIER_POINTER (n);
  2213. else
  2214. return IDENTIFIER_POINTER (DECL_NAME (n));
  2215. }
  2216. /* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
  2217. SPC is the indentation level. Return 1 if a declaration was printed,
  2218. 0 otherwise. */
  2219. static int
  2220. print_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
  2221. {
  2222. int is_var = 0, need_indent = 0;
  2223. int is_class = false;
  2224. tree name = TYPE_NAME (TREE_TYPE (t));
  2225. tree decl_name = DECL_NAME (t);
  2226. tree orig = NULL_TREE;
  2227. if (cpp_check && cpp_check (t, IS_TEMPLATE))
  2228. return dump_ada_template (buffer, t, spc);
  2229. if (TREE_CODE (t) == CONST_DECL && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
  2230. /* Skip enumeral values: will be handled as part of the type itself. */
  2231. return 0;
  2232. if (TREE_CODE (t) == TYPE_DECL)
  2233. {
  2234. orig = DECL_ORIGINAL_TYPE (t);
  2235. if (orig && TYPE_STUB_DECL (orig))
  2236. {
  2237. tree stub = TYPE_STUB_DECL (orig);
  2238. tree typ = TREE_TYPE (stub);
  2239. if (TYPE_NAME (typ))
  2240. {
  2241. /* If types have same representation, and same name (ignoring
  2242. casing), then ignore the second type. */
  2243. if (type_name (typ) == type_name (TREE_TYPE (t))
  2244. || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t))))
  2245. return 0;
  2246. INDENT (spc);
  2247. if (RECORD_OR_UNION_TYPE_P (typ) && !TYPE_FIELDS (typ))
  2248. {
  2249. pp_string (buffer, "-- skipped empty struct ");
  2250. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2251. }
  2252. else
  2253. {
  2254. if (!TREE_VISITED (stub)
  2255. && DECL_SOURCE_FILE (stub) == source_file_base)
  2256. dump_nested_types (buffer, stub, stub, true, spc);
  2257. pp_string (buffer, "subtype ");
  2258. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2259. pp_string (buffer, " is ");
  2260. dump_generic_ada_node (buffer, typ, type, spc, false, true);
  2261. pp_semicolon (buffer);
  2262. }
  2263. return 1;
  2264. }
  2265. }
  2266. /* Skip unnamed or anonymous structs/unions/enum types. */
  2267. if (!orig && !decl_name && !name)
  2268. {
  2269. tree tmp;
  2270. location_t sloc;
  2271. if (cpp_check || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
  2272. return 0;
  2273. if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
  2274. {
  2275. /* Search next items until finding a named type decl. */
  2276. sloc = decl_sloc_common (t, true, true);
  2277. for (tmp = TREE_CHAIN (t); tmp; tmp = TREE_CHAIN (tmp))
  2278. {
  2279. if (TREE_CODE (tmp) == TYPE_DECL
  2280. && (DECL_NAME (tmp) || TYPE_NAME (TREE_TYPE (tmp))))
  2281. {
  2282. /* If same sloc, it means we can ignore the anonymous
  2283. struct. */
  2284. if (decl_sloc_common (tmp, true, true) == sloc)
  2285. return 0;
  2286. else
  2287. break;
  2288. }
  2289. }
  2290. if (tmp == NULL)
  2291. return 0;
  2292. }
  2293. }
  2294. if (!orig
  2295. && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE
  2296. && decl_name
  2297. && (*IDENTIFIER_POINTER (decl_name) == '.'
  2298. || *IDENTIFIER_POINTER (decl_name) == '$'))
  2299. /* Skip anonymous enum types (duplicates of real types). */
  2300. return 0;
  2301. INDENT (spc);
  2302. switch (TREE_CODE (TREE_TYPE (t)))
  2303. {
  2304. case RECORD_TYPE:
  2305. case UNION_TYPE:
  2306. case QUAL_UNION_TYPE:
  2307. /* Skip empty structs (typically forward references to real
  2308. structs). */
  2309. if (!TYPE_FIELDS (TREE_TYPE (t)))
  2310. {
  2311. pp_string (buffer, "-- skipped empty struct ");
  2312. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2313. return 1;
  2314. }
  2315. if (decl_name
  2316. && (*IDENTIFIER_POINTER (decl_name) == '.'
  2317. || *IDENTIFIER_POINTER (decl_name) == '$'))
  2318. {
  2319. pp_string (buffer, "-- skipped anonymous struct ");
  2320. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2321. TREE_VISITED (t) = 1;
  2322. return 1;
  2323. }
  2324. if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
  2325. pp_string (buffer, "subtype ");
  2326. else
  2327. {
  2328. dump_nested_types (buffer, t, t, false, spc);
  2329. if (separate_class_package (t))
  2330. {
  2331. is_class = true;
  2332. pp_string (buffer, "package Class_");
  2333. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2334. pp_string (buffer, " is");
  2335. spc += INDENT_INCR;
  2336. newline_and_indent (buffer, spc);
  2337. }
  2338. pp_string (buffer, "type ");
  2339. }
  2340. break;
  2341. case ARRAY_TYPE:
  2342. case POINTER_TYPE:
  2343. case REFERENCE_TYPE:
  2344. if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
  2345. || is_char_array (t))
  2346. pp_string (buffer, "subtype ");
  2347. else
  2348. pp_string (buffer, "type ");
  2349. break;
  2350. case FUNCTION_TYPE:
  2351. pp_string (buffer, "-- skipped function type ");
  2352. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2353. return 1;
  2354. break;
  2355. case ENUMERAL_TYPE:
  2356. if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
  2357. || !is_simple_enum (TREE_TYPE (t)))
  2358. pp_string (buffer, "subtype ");
  2359. else
  2360. pp_string (buffer, "type ");
  2361. break;
  2362. default:
  2363. pp_string (buffer, "subtype ");
  2364. }
  2365. TREE_VISITED (t) = 1;
  2366. }
  2367. else
  2368. {
  2369. if (TREE_CODE (t) == VAR_DECL
  2370. && decl_name
  2371. && *IDENTIFIER_POINTER (decl_name) == '_')
  2372. return 0;
  2373. need_indent = 1;
  2374. }
  2375. /* Print the type and name. */
  2376. if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
  2377. {
  2378. if (need_indent)
  2379. INDENT (spc);
  2380. /* Print variable's name. */
  2381. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2382. if (TREE_CODE (t) == TYPE_DECL)
  2383. {
  2384. pp_string (buffer, " is ");
  2385. if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
  2386. dump_generic_ada_node
  2387. (buffer, TYPE_NAME (orig), type, spc, false, true);
  2388. else
  2389. dump_ada_array_type (buffer, t, spc);
  2390. }
  2391. else
  2392. {
  2393. tree tmp = TYPE_NAME (TREE_TYPE (t));
  2394. if (spc == INDENT_INCR || TREE_STATIC (t))
  2395. is_var = 1;
  2396. pp_string (buffer, " : ");
  2397. if (tmp)
  2398. {
  2399. if (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
  2400. && TREE_CODE (tmp) != INTEGER_TYPE)
  2401. pp_string (buffer, "aliased ");
  2402. dump_generic_ada_node (buffer, tmp, type, spc, false, true);
  2403. }
  2404. else
  2405. {
  2406. pp_string (buffer, "aliased ");
  2407. if (!type)
  2408. dump_ada_array_type (buffer, t, spc);
  2409. else
  2410. dump_ada_double_name (buffer, type, t, "_array");
  2411. }
  2412. }
  2413. }
  2414. else if (TREE_CODE (t) == FUNCTION_DECL)
  2415. {
  2416. bool is_function, is_abstract_class = false;
  2417. bool is_method = TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE;
  2418. tree decl_name = DECL_NAME (t);
  2419. bool is_abstract = false;
  2420. bool is_constructor = false;
  2421. bool is_destructor = false;
  2422. bool is_copy_constructor = false;
  2423. if (!decl_name)
  2424. return 0;
  2425. if (cpp_check)
  2426. {
  2427. is_abstract = cpp_check (t, IS_ABSTRACT);
  2428. is_constructor = cpp_check (t, IS_CONSTRUCTOR);
  2429. is_destructor = cpp_check (t, IS_DESTRUCTOR);
  2430. is_copy_constructor = cpp_check (t, IS_COPY_CONSTRUCTOR);
  2431. }
  2432. /* Skip copy constructors: some are internal only, and those that are
  2433. not cannot be called easily from Ada anyway. */
  2434. if (is_copy_constructor)
  2435. return 0;
  2436. if (is_constructor || is_destructor)
  2437. {
  2438. /* Only consider constructors/destructors for complete objects. */
  2439. if (strncmp (IDENTIFIER_POINTER (decl_name), "__comp", 6) != 0)
  2440. return 0;
  2441. }
  2442. /* If this function has an entry in the vtable, we cannot omit it. */
  2443. else if (!DECL_VINDEX (t) && *IDENTIFIER_POINTER (decl_name) == '_')
  2444. {
  2445. INDENT (spc);
  2446. pp_string (buffer, "-- skipped func ");
  2447. pp_string (buffer, IDENTIFIER_POINTER (decl_name));
  2448. return 1;
  2449. }
  2450. if (need_indent)
  2451. INDENT (spc);
  2452. if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && !is_constructor)
  2453. {
  2454. pp_string (buffer, "procedure ");
  2455. is_function = false;
  2456. }
  2457. else
  2458. {
  2459. pp_string (buffer, "function ");
  2460. is_function = true;
  2461. }
  2462. if (is_constructor)
  2463. print_constructor (buffer, t);
  2464. else if (is_destructor)
  2465. print_destructor (buffer, t);
  2466. else
  2467. dump_ada_decl_name (buffer, t, false);
  2468. dump_ada_function_declaration
  2469. (buffer, t, is_method, is_constructor, is_destructor, spc);
  2470. if (is_function)
  2471. {
  2472. pp_string (buffer, " return ");
  2473. tree ret_type
  2474. = is_constructor ? DECL_CONTEXT (t) : TREE_TYPE (TREE_TYPE (t));
  2475. dump_generic_ada_node (buffer, ret_type, type, spc, false, true);
  2476. }
  2477. if (is_constructor
  2478. && RECORD_OR_UNION_TYPE_P (type)
  2479. && TYPE_METHODS (type))
  2480. {
  2481. tree tmp;
  2482. for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
  2483. if (cpp_check (tmp, IS_ABSTRACT))
  2484. {
  2485. is_abstract_class = true;
  2486. break;
  2487. }
  2488. }
  2489. if (is_abstract || is_abstract_class)
  2490. pp_string (buffer, " is abstract");
  2491. pp_semicolon (buffer);
  2492. pp_string (buffer, " -- ");
  2493. dump_sloc (buffer, t);
  2494. if (is_abstract || !DECL_ASSEMBLER_NAME (t))
  2495. return 1;
  2496. newline_and_indent (buffer, spc);
  2497. if (is_constructor)
  2498. {
  2499. pp_string (buffer, "pragma CPP_Constructor (");
  2500. print_constructor (buffer, t);
  2501. pp_string (buffer, ", \"");
  2502. pp_asm_name (buffer, t);
  2503. pp_string (buffer, "\");");
  2504. }
  2505. else if (is_destructor)
  2506. {
  2507. pp_string (buffer, "pragma Import (CPP, ");
  2508. print_destructor (buffer, t);
  2509. pp_string (buffer, ", \"");
  2510. pp_asm_name (buffer, t);
  2511. pp_string (buffer, "\");");
  2512. }
  2513. else
  2514. {
  2515. dump_ada_import (buffer, t);
  2516. }
  2517. return 1;
  2518. }
  2519. else if (TREE_CODE (t) == TYPE_DECL && !DECL_ORIGINAL_TYPE (t))
  2520. {
  2521. int is_interface = 0;
  2522. int is_abstract_record = 0;
  2523. if (need_indent)
  2524. INDENT (spc);
  2525. /* Anonymous structs/unions */
  2526. dump_generic_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
  2527. if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE
  2528. || TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE)
  2529. {
  2530. pp_string (buffer, " (discr : unsigned := 0)");
  2531. }
  2532. pp_string (buffer, " is ");
  2533. /* Check whether we have an Ada interface compatible class. */
  2534. if (cpp_check
  2535. && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
  2536. && TYPE_METHODS (TREE_TYPE (t)))
  2537. {
  2538. int num_fields = 0;
  2539. tree tmp;
  2540. /* Check that there are no fields other than the virtual table. */
  2541. for (tmp = TYPE_FIELDS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp))
  2542. {
  2543. if (TREE_CODE (tmp) == TYPE_DECL)
  2544. continue;
  2545. num_fields++;
  2546. }
  2547. if (num_fields == 1)
  2548. is_interface = 1;
  2549. /* Also check that there are only virtual methods. */
  2550. for (tmp = TYPE_METHODS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp))
  2551. {
  2552. if (cpp_check (tmp, IS_ABSTRACT))
  2553. is_abstract_record = 1;
  2554. else
  2555. is_interface = 0;
  2556. }
  2557. }
  2558. TREE_VISITED (t) = 1;
  2559. if (is_interface)
  2560. {
  2561. pp_string (buffer, "limited interface; -- ");
  2562. dump_sloc (buffer, t);
  2563. newline_and_indent (buffer, spc);
  2564. pp_string (buffer, "pragma Import (CPP, ");
  2565. dump_generic_ada_node
  2566. (buffer, TYPE_NAME (TREE_TYPE (t)), type, spc, false, true);
  2567. pp_right_paren (buffer);
  2568. print_ada_methods (buffer, TREE_TYPE (t), spc);
  2569. }
  2570. else
  2571. {
  2572. if (is_abstract_record)
  2573. pp_string (buffer, "abstract ");
  2574. dump_generic_ada_node (buffer, t, t, spc, false, false);
  2575. }
  2576. }
  2577. else
  2578. {
  2579. if (need_indent)
  2580. INDENT (spc);
  2581. if (TREE_CODE (t) == FIELD_DECL && DECL_NAME (t))
  2582. check_name (buffer, t);
  2583. /* Print variable/type's name. */
  2584. dump_generic_ada_node (buffer, t, t, spc, false, true);
  2585. if (TREE_CODE (t) == TYPE_DECL)
  2586. {
  2587. tree orig = DECL_ORIGINAL_TYPE (t);
  2588. int is_subtype = orig && TYPE_NAME (orig) && orig != TREE_TYPE (t);
  2589. if (!is_subtype
  2590. && (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE
  2591. || TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE))
  2592. pp_string (buffer, " (discr : unsigned := 0)");
  2593. pp_string (buffer, " is ");
  2594. dump_generic_ada_node (buffer, orig, t, spc, false, is_subtype);
  2595. }
  2596. else
  2597. {
  2598. if (spc == INDENT_INCR || TREE_STATIC (t))
  2599. is_var = 1;
  2600. pp_string (buffer, " : ");
  2601. /* Print type declaration. */
  2602. if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE
  2603. && !TYPE_NAME (TREE_TYPE (t)))
  2604. {
  2605. dump_ada_double_name (buffer, type, t, "_union");
  2606. }
  2607. else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
  2608. {
  2609. if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
  2610. pp_string (buffer, "aliased ");
  2611. dump_generic_ada_node
  2612. (buffer, TREE_TYPE (t), t, spc, false, true);
  2613. }
  2614. else
  2615. {
  2616. if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
  2617. && (TYPE_NAME (TREE_TYPE (t))
  2618. || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE))
  2619. pp_string (buffer, "aliased ");
  2620. dump_generic_ada_node
  2621. (buffer, TREE_TYPE (t), TREE_TYPE (t), spc, false, true);
  2622. }
  2623. }
  2624. }
  2625. if (is_class)
  2626. {
  2627. spc -= INDENT_INCR;
  2628. newline_and_indent (buffer, spc);
  2629. pp_string (buffer, "end;");
  2630. newline_and_indent (buffer, spc);
  2631. pp_string (buffer, "use Class_");
  2632. dump_generic_ada_node (buffer, t, type, spc, false, true);
  2633. pp_semicolon (buffer);
  2634. pp_newline (buffer);
  2635. /* All needed indentation/newline performed already, so return 0. */
  2636. return 0;
  2637. }
  2638. else
  2639. {
  2640. pp_string (buffer, "; -- ");
  2641. dump_sloc (buffer, t);
  2642. }
  2643. if (is_var)
  2644. {
  2645. newline_and_indent (buffer, spc);
  2646. dump_ada_import (buffer, t);
  2647. }
  2648. return 1;
  2649. }
  2650. /* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods
  2651. with Ada syntax. SPC is the indentation level. If DISPLAY_CONVENTION is
  2652. true, also print the pragma Convention for NODE. */
  2653. static void
  2654. print_ada_struct_decl (pretty_printer *buffer, tree node, tree type, int spc,
  2655. bool display_convention)
  2656. {
  2657. tree tmp;
  2658. const bool is_union
  2659. = TREE_CODE (node) == UNION_TYPE || TREE_CODE (node) == QUAL_UNION_TYPE;
  2660. char buf[32];
  2661. int field_num = 0;
  2662. int field_spc = spc + INDENT_INCR;
  2663. int need_semicolon;
  2664. bitfield_used = false;
  2665. if (!TYPE_FIELDS (node))
  2666. pp_string (buffer, "null record;");
  2667. else
  2668. {
  2669. pp_string (buffer, "record");
  2670. /* Print the contents of the structure. */
  2671. if (is_union)
  2672. {
  2673. newline_and_indent (buffer, spc + INDENT_INCR);
  2674. pp_string (buffer, "case discr is");
  2675. field_spc = spc + INDENT_INCR * 3;
  2676. }
  2677. pp_newline (buffer);
  2678. /* Print the non-static fields of the structure. */
  2679. for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
  2680. {
  2681. /* Add parent field if needed. */
  2682. if (!DECL_NAME (tmp))
  2683. {
  2684. if (!is_tagged_type (TREE_TYPE (tmp)))
  2685. {
  2686. if (!TYPE_NAME (TREE_TYPE (tmp)))
  2687. print_ada_declaration (buffer, tmp, type, field_spc);
  2688. else
  2689. {
  2690. INDENT (field_spc);
  2691. if (field_num == 0)
  2692. pp_string (buffer, "parent : aliased ");
  2693. else
  2694. {
  2695. sprintf (buf, "field_%d : aliased ", field_num + 1);
  2696. pp_string (buffer, buf);
  2697. }
  2698. dump_ada_decl_name
  2699. (buffer, TYPE_NAME (TREE_TYPE (tmp)), false);
  2700. pp_semicolon (buffer);
  2701. }
  2702. pp_newline (buffer);
  2703. field_num++;
  2704. }
  2705. }
  2706. /* Avoid printing the structure recursively. */
  2707. else if ((TREE_TYPE (tmp) != node
  2708. || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
  2709. && TREE_TYPE (TREE_TYPE (tmp)) != node))
  2710. && TREE_CODE (tmp) != TYPE_DECL
  2711. && !TREE_STATIC (tmp))
  2712. {
  2713. /* Skip internal virtual table field. */
  2714. if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp)), "_vptr", 5))
  2715. {
  2716. if (is_union)
  2717. {
  2718. if (TREE_CHAIN (tmp)
  2719. && TREE_TYPE (TREE_CHAIN (tmp)) != node
  2720. && TREE_CODE (TREE_CHAIN (tmp)) != TYPE_DECL)
  2721. sprintf (buf, "when %d =>", field_num);
  2722. else
  2723. sprintf (buf, "when others =>");
  2724. INDENT (spc + INDENT_INCR * 2);
  2725. pp_string (buffer, buf);
  2726. pp_newline (buffer);
  2727. }
  2728. if (print_ada_declaration (buffer, tmp, type, field_spc))
  2729. {
  2730. pp_newline (buffer);
  2731. field_num++;
  2732. }
  2733. }
  2734. }
  2735. }
  2736. if (is_union)
  2737. {
  2738. INDENT (spc + INDENT_INCR);
  2739. pp_string (buffer, "end case;");
  2740. pp_newline (buffer);
  2741. }
  2742. if (field_num == 0)
  2743. {
  2744. INDENT (spc + INDENT_INCR);
  2745. pp_string (buffer, "null;");
  2746. pp_newline (buffer);
  2747. }
  2748. INDENT (spc);
  2749. pp_string (buffer, "end record;");
  2750. }
  2751. newline_and_indent (buffer, spc);
  2752. if (!display_convention)
  2753. return;
  2754. if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
  2755. {
  2756. if (has_nontrivial_methods (TREE_TYPE (type)))
  2757. pp_string (buffer, "pragma Import (CPP, ");
  2758. else
  2759. pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
  2760. }
  2761. else
  2762. pp_string (buffer, "pragma Convention (C, ");
  2763. package_prefix = false;
  2764. dump_generic_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
  2765. package_prefix = true;
  2766. pp_right_paren (buffer);
  2767. if (is_union)
  2768. {
  2769. pp_semicolon (buffer);
  2770. newline_and_indent (buffer, spc);
  2771. pp_string (buffer, "pragma Unchecked_Union (");
  2772. dump_generic_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
  2773. pp_right_paren (buffer);
  2774. }
  2775. if (bitfield_used)
  2776. {
  2777. pp_semicolon (buffer);
  2778. newline_and_indent (buffer, spc);
  2779. pp_string (buffer, "pragma Pack (");
  2780. dump_generic_ada_node
  2781. (buffer, TREE_TYPE (type), type, spc, false, true);
  2782. pp_right_paren (buffer);
  2783. bitfield_used = false;
  2784. }
  2785. need_semicolon = !print_ada_methods (buffer, node, spc);
  2786. /* Print the static fields of the structure, if any. */
  2787. for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
  2788. {
  2789. if (DECL_NAME (tmp) && TREE_STATIC (tmp))
  2790. {
  2791. if (need_semicolon)
  2792. {
  2793. need_semicolon = false;
  2794. pp_semicolon (buffer);
  2795. }
  2796. pp_newline (buffer);
  2797. pp_newline (buffer);
  2798. print_ada_declaration (buffer, tmp, type, spc);
  2799. }
  2800. }
  2801. }
  2802. /* Dump all the declarations in SOURCE_FILE to an Ada spec.
  2803. COLLECT_ALL_REFS is a front-end callback used to collect all relevant
  2804. nodes for SOURCE_FILE. CHECK is used to perform C++ queries on nodes. */
  2805. static void
  2806. dump_ads (const char *source_file,
  2807. void (*collect_all_refs)(const char *),
  2808. int (*check)(tree, cpp_operation))
  2809. {
  2810. char *ads_name;
  2811. char *pkg_name;
  2812. char *s;
  2813. FILE *f;
  2814. pkg_name = get_ada_package (source_file);
  2815. /* Construct the .ads filename and package name. */
  2816. ads_name = xstrdup (pkg_name);
  2817. for (s = ads_name; *s; s++)
  2818. if (*s == '.')
  2819. *s = '-';
  2820. else
  2821. *s = TOLOWER (*s);
  2822. ads_name = reconcat (ads_name, ads_name, ".ads", NULL);
  2823. /* Write out the .ads file. */
  2824. f = fopen (ads_name, "w");
  2825. if (f)
  2826. {
  2827. pretty_printer pp;
  2828. pp_needs_newline (&pp) = true;
  2829. pp.buffer->stream = f;
  2830. /* Dump all relevant macros. */
  2831. dump_ada_macros (&pp, source_file);
  2832. /* Reset the table of withs for this file. */
  2833. reset_ada_withs ();
  2834. (*collect_all_refs) (source_file);
  2835. /* Dump all references. */
  2836. cpp_check = check;
  2837. dump_ada_nodes (&pp, source_file);
  2838. /* Requires Ada 2005 syntax, so generate corresponding pragma.
  2839. Also, disable style checks since this file is auto-generated. */
  2840. fprintf (f, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n");
  2841. /* Dump withs. */
  2842. dump_ada_withs (f);
  2843. fprintf (f, "\npackage %s is\n\n", pkg_name);
  2844. pp_write_text_to_stream (&pp);
  2845. /* ??? need to free pp */
  2846. fprintf (f, "end %s;\n", pkg_name);
  2847. fclose (f);
  2848. }
  2849. free (ads_name);
  2850. free (pkg_name);
  2851. }
  2852. static const char **source_refs = NULL;
  2853. static int source_refs_used = 0;
  2854. static int source_refs_allocd = 0;
  2855. /* Add an entry for FILENAME to the table SOURCE_REFS. */
  2856. void
  2857. collect_source_ref (const char *filename)
  2858. {
  2859. int i;
  2860. if (!filename)
  2861. return;
  2862. if (source_refs_allocd == 0)
  2863. {
  2864. source_refs_allocd = 1024;
  2865. source_refs = XNEWVEC (const char *, source_refs_allocd);
  2866. }
  2867. for (i = 0; i < source_refs_used; i++)
  2868. if (filename == source_refs[i])
  2869. return;
  2870. if (source_refs_used == source_refs_allocd)
  2871. {
  2872. source_refs_allocd *= 2;
  2873. source_refs = XRESIZEVEC (const char *, source_refs, source_refs_allocd);
  2874. }
  2875. source_refs[source_refs_used++] = filename;
  2876. }
  2877. /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
  2878. using callbacks COLLECT_ALL_REFS and CHECK.
  2879. COLLECT_ALL_REFS is a front-end callback used to collect all relevant
  2880. nodes for a given source file.
  2881. CHECK is used to perform C++ queries on nodes, or NULL for the C
  2882. front-end. */
  2883. void
  2884. dump_ada_specs (void (*collect_all_refs)(const char *),
  2885. int (*check)(tree, cpp_operation))
  2886. {
  2887. int i;
  2888. /* Iterate over the list of files to dump specs for */
  2889. for (i = 0; i < source_refs_used; i++)
  2890. dump_ads (source_refs[i], collect_all_refs, check);
  2891. /* Free files table. */
  2892. free (source_refs);
  2893. }