PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/cparse.awk

https://bitbucket.org/pjotr/lime
AWK | 1512 lines | 1213 code | 188 blank | 111 comment | 0 complexity | 7eb5869c2a1070b8bc2cae9962ee7838 MD5 | raw file
Possible License(s): GPL-2.0
  1. #!/usr/bin/awk -f
  2. ##################################################################
  3. # This AWK script performs parsing of trees generated by
  4. # gcc -fdump-translation-unit as well as generation of .types, .mod
  5. # and other files
  6. #
  7. #Copyright (C) 2008 NXP Semiconductors B.V.
  8. #
  9. #This file is part of LIME.
  10. #
  11. #LIME is free software: you can redistribute it and/or modify
  12. #it under the terms of the GNU General Public License version 2
  13. #as published by the Free Software Foundation; either version 2
  14. #of the License, or (at your option) any later version.
  15. #
  16. #LIME is distributed in the hope that it will be useful,
  17. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. #GNU General Public License for more details.
  20. #
  21. #You should have received a copy of the GNU General Public License
  22. #along with LIME. If not, see <http://www.gnu.org/licenses/>.
  23. ##################################################################
  24. BEGIN { node=0
  25. FS="[ \t:]+"
  26. if (!SCHED) SCHED="sched"
  27. if (!EDGES) EDGES="edges"
  28. modifiers["undefined"]=modifiers["volatile"]=\
  29. modifiers["static"]=modifiers["extern"]=\
  30. modifiers["struct"]=modifiers["union"]=\
  31. modifiers["begn"]=modifiers["clnp"]=modifiers["end"]=\
  32. modifiers["null"]=modifiers["register"]=\
  33. modifiers["unsigned"]=modifiers["int"]=modifiers["char"]=\
  34. modifiers["float"]=modifiers["double"]=modifiers["long"]=\
  35. modifiers["short"]=modifiers["bitfield"]=1
  36. modifiers["artificial"]=modifiers["C"]=modifiers["operator"]=\
  37. modifiers["new"]=modifiers["delete"]=\
  38. modifiers["vecnew"]=modifiers["vecdelete"]=1
  39. MODE=""
  40. gsub("/+$","",DIR)
  41. if (DIR==".") DIR=""
  42. Out="from"
  43. In="to"
  44. }
  45. MODE=="" { start=1 }
  46. func finalize() { if (!node) return
  47. # do this stuff only after all tags of identifier_node
  48. # have been processed
  49. if (cur=="identifier_node")
  50. {
  51. # identifier_node gives a name to nodes
  52. if (name[num])
  53. # don't waste time for this iteration!
  54. #for (n in name) if (name[n]==num) name[n]=name[num]
  55. n=split(todo[num],el," ")
  56. for (i=1; i<=n; i++)
  57. name[el[i]]=name[num]
  58. }
  59. # tag is initialized on the next iteration due to
  60. # the taglist spanning several lines
  61. tag[num]=cur
  62. if (0) {}
  63. else if (cur=="statement_list") {
  64. stmts[num]=flatten(List)
  65. delete List
  66. }
  67. else if (cur=="constructor") {
  68. cons[num]=Flatten(List)
  69. delete List
  70. }
  71. }
  72. MODE=="" && /^@/ {
  73. finalize()
  74. node=1
  75. num=substr($1,2)
  76. cur=$2
  77. start=3
  78. }
  79. MODE=="" {
  80. if (DEBUG>1) printf "loop: %s ",num,cur > STDERR
  81. for (i=start; i<=NF; i++)
  82. {
  83. if (DEBUG>1) printf " %s",$i >STDERR
  84. if (0) {}
  85. else if ($i=="name") {
  86. ref=substr($(++i),2)
  87. if (ref in name) name[num]=name[ref]
  88. else {
  89. name[num]=ref
  90. todo[ref]=append(todo[ref],num)
  91. }
  92. }
  93. else if ($i=="srcp") {
  94. file[num]=$(++i)
  95. line[num]=$(++i)
  96. srcp[num]=sprintf("%s:%04i",file[num],line[num])
  97. # if (DEBUG) print file[num],line[num] > STDERR
  98. }
  99. else if ($i=="op") {
  100. opno=$(++i)
  101. op[num,opno]=substr($(++i),2)
  102. }
  103. else if (cur=="case_label" && $i=="low") low[num]=substr($(++i),2)
  104. else if ($i=="scpe") scpe[num]=substr($(++i),2)
  105. else if ($i=="fn") Func[num]=substr($(++i),2)
  106. else if ($i=="init") init[num]=substr($(++i),2)
  107. else if ($i=="decl") decl[num]=substr($(++i),2)
  108. else if ($i=="args") args[num]=substr($(++i),2)
  109. else if ($i=="valu") valu[num]=substr($(++i),2)
  110. else if ($i=="expr") expr[num]=substr($(++i),2)
  111. else if ($i=="cond") cond[num]=substr($(++i),2)
  112. else if ($i=="then") then[num]=substr($(++i),2)
  113. else if ($i=="else") Else[num]=substr($(++i),2)
  114. else if ($i=="next") Next[num]=substr($(++i),2)
  115. else if ($i=="chan") chan[num]=substr($(++i),2)
  116. else if ($i=="body") body[num]=substr($(++i),2)
  117. else if ($i=="type") type[num]=substr($(++i),2)
  118. else if ($i=="retn") retn[num]=substr($(++i),2)
  119. else if ($i=="size") size[num]=substr($(++i),2)
  120. else if ($i=="prms") prms[num]=substr($(++i),2)
  121. else if ($i=="mngl") mngl[num]=substr($(++i),2)
  122. else if ($i=="unql") unql[num]=substr($(++i),2)
  123. else if ($i=="refd") refd[num]=substr($(++i),2)
  124. else if ($i=="elts") elts[num]=substr($(++i),2)
  125. else if ($i=="bpos") bpos[num]=substr($(++i),2)
  126. else if ($i=="flds") flds[num]=substr($(++i),2)
  127. else if ($i=="domn") domn[num]=substr($(++i),2)
  128. else if ($i=="argt") argt[num]=substr($(++i),2)
  129. else if ($i=="dest") dest[num]=substr($(++i),2)
  130. else if ($i=="labl") labl[num]=substr($(++i),2)
  131. else if ($i=="ptd") ptrd[num]=substr($(++i),2)
  132. else if ($i=="min") mini[num]=substr($(++i),2)
  133. else if ($i=="max") maxi[num]=substr($(++i),2)
  134. else if ($i=="cnst") cnst[num]=substr($(++i),2)
  135. else if ($i=="clbr") clbr[num]=substr($(++i),2)
  136. else if ($i=="csts") csts[num]=substr($(++i),2)
  137. else if ($i=="outs") outs[num]=substr($(++i),2)
  138. else if ($i=="purp") purp[num]=substr($(++i),2)
  139. else if ($i=="stmt") stmt[num]=substr($(++i),2)
  140. else if ($i=="ins") ins[num]=substr($(++i),2)
  141. else if ($i=="dcls") dcls[num]=substr($(++i),2)
  142. else if ($i=="vars") vars[num]=substr($(++i),2)
  143. else if ($i=="idx") idx[num]=substr($(++i),2)
  144. else if ($i=="val") {
  145. val[num]=substr($(++i),2)
  146. List[idx[num]]=val[num]
  147. #if (DEBUG) print "@",idx[num],List[idx[num]] >STDERR
  148. }
  149. else if ($i ~ /^[0-9]+$/) {
  150. #if (DEBUG) print $i,$(i+1) >STDERR
  151. #stmts[num]=append(stmts[num],substr($(++i),2))
  152. List[$i]=substr($(i+1),2)
  153. i++
  154. }
  155. else if ($i=="strg" && cur=="asm_stmt") {
  156. strg[num]=substr($(++i),2)
  157. }
  158. else if ($i=="strg" && cur=="identifier_node") {
  159. IN_STRG=1
  160. name[num]=append(name[num],$(++i))
  161. }
  162. else if ($i=="lngt") { IN_STRG=0
  163. lngt[num]=$(++i)
  164. if (lngt[num]!=length(name[num]) && 0)
  165. printf "Consistency '%s' %d!=%d\n",
  166. name[num],lngt[num],
  167. length(name[num]) > STDERR
  168. }
  169. else if ($i=="strg") {
  170. if (match($0,
  171. /strg: (.*) lngt: [0-9]+[:space:]*$/,
  172. a))
  173. name[num]=a[1]
  174. else {
  175. MODE="string"
  176. string=""
  177. $0=substr($0,index($0,"strg: ")+6)
  178. }
  179. break
  180. }
  181. else if ($i=="sign") sign[num]=$(++i)
  182. else if ($i=="link") link[num]=$(++i)
  183. else if ($i=="tag") Tag[num]=$(++i)
  184. else if ($i=="line") line[num]=$(++i)
  185. else if ($i=="high") high[num]=$(++i)
  186. else if ($i=="algn") algn[num]=$(++i)
  187. else if ($i=="prec") prec[num]=$(++i)
  188. else if ($i=="qual") qual[num]=$(++i)
  189. else if ($i=="used") used[num]=$(++i)
  190. else if ($i=="packet") pack[num]=$(++i)
  191. else if (cur!="case_label" && $i=="low") low[num]=$(++i)
  192. else if ($i=="segment") seg[num]=$(++i)
  193. else if ($i=="note") note[num]=$(++i)
  194. else if ($i=="lang") note[num]=$(++i)
  195. else if ($i ~ /^@/)
  196. printf "Unknown ref: %s\n",$i > STDERR
  197. else if ($i in modifiers) {
  198. if (IN_STRG)
  199. name[num]=append(name[num],$i)
  200. else
  201. modi[num]=append(modi[num],$i)
  202. }
  203. else if ($i)
  204. printf "Unknown tag: '%s'\n",$i > STDERR
  205. }
  206. if (DEBUG>1) printf "\n" >STDERR
  207. }
  208. # nasty bit covering strg spanning several lines
  209. MODE=="string" && match($0,/[ \t]*lngt: ([0-9]+)[ \t]*$/,a) {
  210. string=string substr($0,1,RSTART-1)
  211. if (0 && a[1]!=length(string)+1)
  212. printf "Consistency '%s' %d!=%d\n",
  213. string,a[1],length(string) > STDERR
  214. name[num]=string
  215. lngt[num]=a[1]
  216. MODE=""
  217. }
  218. MODE=="string" { string=string $0 "\n" }
  219. END { finalize()
  220. if (!OP) OP="cutpoints"
  221. if (!ORDER) ORDER="lex"
  222. if (ORDER=="lex") {
  223. for (i in name) un[name[i]]=append(un[name[i]],i)
  224. nr=asort(name,sorted)
  225. }
  226. if (ORDER=="src") {
  227. for (i in srcp) un[srcp[i]]=append(un[srcp[i]],i)
  228. nr=asort(srcp,sorted)
  229. }
  230. nops=split(OP,ops,",")
  231. for (o=1; o<=nops; o++)
  232. {
  233. OP=ops[o]
  234. delete cnt
  235. if (OP=="comps") pragma_map(FNAME)
  236. if (OP ~ "^" EDGES) for (ix=1; ix<=nr; ix++) {
  237. split(un[sorted[ix]],el," ")
  238. n=el[++cnt[un[sorted[ix]]]]
  239. if (modi[n] ~ /undefined/ ||
  240. file[n] ~ /<built-in>/ ||
  241. file[n] ~ /<internal>/) continue
  242. if (tag[n] !~ /var_decl/) continue
  243. # gcc-3.4 specifics
  244. if (scpe[n] && tag[scpe[n]]!="translation_unit_decl" ) continue
  245. if (FNAME && file[n]!=FNAME) continue
  246. if (name[n] !~ OP "$") continue
  247. if (DEBUG) printf "%s:%05d %s %s %s\n",
  248. file[n],line[n],
  249. (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
  250. name[n],modi[n] >STDERR
  251. dump_edges(n)
  252. # generate just one edges array
  253. break
  254. }
  255. if (OP ~ "^" SCHED) {
  256. for (ix=1; ix<=nr; ix++) {
  257. split(un[sorted[ix]],el," ")
  258. n=el[++cnt[un[sorted[ix]]]]
  259. if (modi[n] ~ /undefined/ ||
  260. file[n] ~ /<built-in>/ ||
  261. file[n] ~ /<internal>/) continue
  262. if (tag[n] !~ /var_decl/) continue
  263. # gcc-3.4 specifics
  264. if (scpe[n] && tag[scpe[n]]!="translation_unit_decl" ) continue
  265. if (FNAME && file[n]!=FNAME) continue
  266. if (name[n] !~ "^" OP) continue
  267. if (DEBUG) printf "%s:%05d %s %s %s\n",
  268. file[n],line[n],
  269. (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
  270. name[n],modi[n] >STDERR
  271. dump_sched(n)
  272. # generate just one schedule
  273. break
  274. }
  275. # no schedule array was found
  276. if (ix>nr && nedges) {
  277. # generate schedule with all comps
  278. # in order derived from the local graph
  279. # for this to work, edges must already be processed
  280. printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",FNAME)
  281. # find roots
  282. delete visited
  283. for (i=1; i<=ncomps; i++) {
  284. n=comps[i];
  285. if (fan[n,In]) continue
  286. recurse(n)
  287. }
  288. # nodes with only self-edges
  289. for (i=1; i<=ncomps; i++) {
  290. n=comps[i];
  291. recurse(n)
  292. }
  293. print "</" OP ">"
  294. break
  295. }
  296. if (ix>nr) {
  297. # generate schedule with all comps
  298. # in order currently selected {lex,src}
  299. # for this to work, nodes must already be processed
  300. if (ncomps<1) fail("Module " FNAME " has no components, probably due to a syntax error!")
  301. printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",FNAME)
  302. # controller comes first
  303. for (i=1; i<=ncomps; i++) if (node_ret[comps[i]] ~ /controller/)
  304. printf space(2) "<node id='%s'/>\n",comps[i]
  305. for (i=1; i<=ncomps; i++) if (node_ret[comps[i]] !~ /controller/)
  306. printf space(2) "<node id='%s' %s/>\n",comps[i],attwrap("mode",mode[comps[i]])
  307. print "</" OP ">"
  308. break
  309. }
  310. }
  311. if (OP=="comps") for (ix=1; ix<=nr; ix++) {
  312. split(un[sorted[ix]],el," ")
  313. n=el[++cnt[un[sorted[ix]]]]
  314. if (file[n] ~ /<built-in>/ ||
  315. file[n] ~ /<internal>/) continue
  316. if (!link[n] && modi[n] ~ /extern/) link[n]="extern"
  317. if (tag[n] !~ /function_decl/ ||
  318. link[n] != "extern" ) continue
  319. if (modi[n] ~ /undefined/ &&
  320. name[n] ~ /_shell$/)
  321. {
  322. printf "<callout id='%s'/>\n",gensub(/_shell$/,"","g",name[n])
  323. continue
  324. }
  325. if (!(name[retn[type[n]]] ~ /actor/ ||
  326. name[name[retn[type[n]]]] ~ /actor/ ||
  327. is_ddf_actor(n)))
  328. {
  329. #print "skipped",name[n],name[retn[type[n]]] >STDERR
  330. continue
  331. }
  332. if (FNAME && file[n]!=FNAME) continue
  333. #if (name[n] ~ "^" CONS || name[n] ~ "^" DEST) continue
  334. if (DEBUG) printf "%s:%05d %s %s\n",
  335. file[n],line[n],
  336. name[n],modi[n] >STDERR
  337. dump_comp(n)
  338. }
  339. if (OP=="typedefs") for (ix=1; ix<=nr; ix++) {
  340. split(un[sorted[ix]],el," ")
  341. n=el[++cnt[un[sorted[ix]]]]
  342. if (modi[n] ~ /undefined/ ||
  343. file[n] ~ /<built-in>/ ||
  344. file[n] ~ /<internal>/) continue
  345. if (tag[n] !~ /type_decl/) continue
  346. if (FNAME && file[n]!=FNAME) continue
  347. if (DEBUG) printf "%s:%05d %s %s\n",
  348. file[n],line[n],
  349. name[n],modi[n] >STDERR
  350. if (name[n] ~ /^[[:digit:]]*$/) continue
  351. if (name[n] in typedef) continue
  352. printf "<typedef id='%s'>\n",name[n]
  353. if (size[n]) print space(2) "<size>" low[size[n]] "</size>"
  354. if (prec[n]) print space(2) "<prec>" prec[n] "</prec>"
  355. print space(2) "<type>" _Type(type[n]) "</type>"
  356. print space(2) "</typedef>"
  357. typedef[name[n]]=1
  358. }
  359. if (OP=="types") for (ix=1; ix<=nr; ix++) {
  360. split(un[sorted[ix]],el," ")
  361. n=el[++cnt[un[sorted[ix]]]]
  362. if (modi[n] ~ /undefined/ ||
  363. file[n] ~ /<built-in>/ ||
  364. file[n] ~ /<internal>/) continue
  365. if (tag[n] !~ /void_type/ &&
  366. tag[n] !~ /integer_type/ &&
  367. tag[n] !~ /real_type/ &&
  368. tag[n] !~ /record_type/ &&
  369. tag[n] !~ /enumeral_type/ &&
  370. tag[n] !~ /array_type/ &&
  371. tag[n] !~ /union_type/ &&
  372. tag[n] !~ /pointer_type/ &&
  373. tag[n] !~ /reference_type/ &&
  374. tag[n] !~ /function_type/) continue
  375. #print tag[n],name[n]
  376. #no origin info for types
  377. #if (FNAME && file[n]!=FNAME) continue
  378. if (DEBUG) printf "%s:%05d %s %s\n",
  379. file[n],line[n],
  380. name[n],modi[n] >STDERR
  381. if (name[n] ~ /^[[:digit:]]*$/) continue
  382. if (name[n] in typedef) continue
  383. printf "<typedecl id='%s'>\n",_name(n)
  384. if (size[n]) print space(2) "<size>" low[size[n]] "</size>"
  385. if (prec[n]) print space(2) "<prec>" prec[n] "</prec>"
  386. print space(2) "<type>" _Type(n) "</type>"
  387. # recognize a discriminated union type
  388. handle_variants(n)
  389. print space(2) "</typedecl>"
  390. typedef[_name(n)]=1
  391. }
  392. if (OP=="idents") for (ix=1; ix<=nr; ix++) {
  393. split(un[sorted[ix]],el," ")
  394. n=el[++cnt[un[sorted[ix]]]]
  395. if (modi[n] ~ /undefined/ ||
  396. file[n] ~ /<built-in>/ ||
  397. file[n] ~ /<internal>/) continue
  398. if (tag[n] !~ /.*_decl/) continue
  399. if (FNAME && file[n]!=FNAME) continue
  400. if (!(name[retn[type[n]]] ~ /actor/ ||
  401. name[name[retn[type[n]]]] ~ /actor/ ||
  402. is_ddf_actor(n)))
  403. continue
  404. printf "%s:%05d %s %s %s\n",
  405. file[n],line[n],
  406. (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
  407. name[n],modi[n]
  408. }
  409. if (OP=="funcs") for (ix=1; ix<=nr; ix++) {
  410. split(un[sorted[ix]],el," ")
  411. n=el[++cnt[un[sorted[ix]]]]
  412. if (modi[n] ~ /undefined/ ||
  413. file[n] ~ /<built-in>/ ||
  414. file[n] ~ /<internal>/) continue
  415. if (tag[n] !~ /function_decl/) continue
  416. if (FNAME && file[n]!=FNAME) continue
  417. printf "%s:%05d %s %s %s\n",
  418. file[n],line[n],
  419. (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
  420. name[n],modi[n]
  421. }
  422. }
  423. }
  424. ###################################################################################3
  425. func is_ddf_actor(n, m) {
  426. m=retn[type[n]]
  427. if (tag[m] == "record_type") {
  428. if (name[m] ~ /continuation/) return 1
  429. return 0
  430. }
  431. if (tag[m] == "pointer_type") {
  432. if (tag[ptrd[m]] != "function_type") return 0
  433. m=retn[ptrd[m]]
  434. if (tag[m] != "void_type") return 0
  435. if (name[name[m]] ~ /void/ || name[m] ~ /void/) return 1
  436. return 0
  437. }
  438. return 0
  439. }
  440. func handle_variants(n, m,e, sel,uni,i,port,select,nport,v,nsel,values,j,sname)
  441. {
  442. if (tag[n] != "record_type") {
  443. m=name[n]
  444. e=n
  445. n=ptrd[type[n]]
  446. if (tag[n] != "record_type") {
  447. return 0
  448. }
  449. }
  450. # first field must be an enumeration
  451. sel=flds[n]
  452. if (tag[type[sel]] != "enumeral_type") return 0
  453. # next field must be a union
  454. uni=chan[sel]
  455. if (tag[type[uni]] != "union_type") return 0
  456. # there shall be no further fields
  457. if (chan[uni]) return 0
  458. # OK, we've found one:
  459. if (!m) {
  460. print space(2) "<variant>"
  461. printf space(3) "<selector id='%s' type='%s'/>\n",name[sel],_type(type[sel])
  462. printf space(3) "<ports id='%s'/>\n",name[uni]
  463. } else {
  464. printf space(2) "<port id='%s'>\n",m
  465. derive_typeinfo(e)
  466. #print m,Size >STDERR
  467. for (i in Modi) printf space(4) "<%s>%s</%s>\n",i,Modi[i],i
  468. ns=split(Size,size,SUBSEP)
  469. for (i=1; i<=ns; i++)
  470. print space(4) "<size>" size[i] "</size>"
  471. printf space(2) "<metatype id='%s'/>\n","variant_type"
  472. sname="_" m "_" name[sel]
  473. printf space(3) "<port id='%s' type='%s' calltype='%s' size=1/>\n",
  474. sname, _type(type[sel]),"enumeral_type"
  475. }
  476. # iterate on all union fields
  477. i=flds[type[uni]]
  478. do port[nport++]=i; while(i=chan[i])
  479. # iterate on all tag values
  480. i=csts[type[sel]]
  481. do {
  482. n=name[purp[i]]
  483. v=low[valu[i]]
  484. if (v<0 || v>=nport) fail("tag value has no matching union field")
  485. select[v]=n
  486. #select[nsel++]=n
  487. } while(i=chan[i])
  488. for (i=0; i<nport; i++) {
  489. if (!select[i]) fail("port has no selector")
  490. # this port is a normal port
  491. if (tag[swizzle(type[port[i]])] !~ /^record_type$/ || name[swizzle(type[port[i]])]) {
  492. dump_port(port[i],select[i],m ? "mode" : "tag", sname)
  493. continue
  494. }
  495. #print port[i],name[port[i]],tag[swizzle(type[port[i]])],name[swizzle(type[port[i]])],select[i] >STDERR
  496. # this port is a multiport
  497. dump_port(port[i],select[i],m ? "mode" : "tag", sname)
  498. #for (j=flds[type[port[i]]]; j; j=chan[j]) {
  499. # print name[j],tag[j] >STDERR
  500. # dump_port(j,select[i],m ? "mode" : "tag")
  501. #}
  502. }
  503. if (!m) {
  504. print space(2) "</variant>"
  505. } else {
  506. print space(2) "</port>"
  507. }
  508. return 1
  509. }
  510. func check_edges_type(n, t,fr,to,et,nd,pd) {
  511. if (tag[n] != "array_type") return 0
  512. n=elts[n]
  513. if (tag[n] != "record_type") return 0
  514. t=flds[n]
  515. if (tag[type[t]] != "pointer_type" || name[ptrd[type[t]]] != "char") return 0
  516. fr=chan[t]; et=type[fr]
  517. # check the type of the from structure
  518. if (tag[et] != "record_type") return 0
  519. nd=flds[et]
  520. if (tag[type[nd]] != "pointer_type" || tag[ptrd[type[nd]]] != "function_type") return 0
  521. pd=chan[nd]
  522. if (tag[type[pd]] != "pointer_type" || name[ptrd[type[pd]]] != "char") return 0
  523. # no more fields
  524. if (chan[pd]) return 0
  525. to=chan[fr]
  526. # the type fo the to structure is the same, just check the tag
  527. if (type[to] != et) return 0
  528. if (chan[to]) return 0
  529. return 1
  530. }
  531. func dump_edges(n) {
  532. if (GCC < 40100)
  533. return dump_edges3(n)
  534. return dump_edges4(n)
  535. }
  536. func dump_edges3(n, i,nel,j,ep,st,iv,k,a,node,port,dir) {
  537. if (DEBUG) print tag[n],n > STDERR
  538. if (!check_edges_type(type[n])) return
  539. for (i=elts[init[n]]; i; i=chan[i]) {
  540. print "<edge>"
  541. ++nedges
  542. for (j=elts[valu[i]]; j; j=chan[j])
  543. {
  544. dir=name[purp[j]]
  545. if (dir=="type")
  546. {
  547. edge_type[nedges]=name[op[op[valu[j],0],0]]
  548. print "<type>" edge_type[nedges] "</type>"
  549. }
  550. if (dir==Out || dir==In)
  551. {
  552. print "<" dir ">"
  553. for (k=elts[valu[j]]; k; k=chan[k]) if (name[purp[k]]=="node") {
  554. node=name[op[valu[k],0]]
  555. if (!node) node=name[op[op[valu[k],0],0]]
  556. }
  557. for (k=elts[valu[j]]; k; k=chan[k]) if (name[purp[k]]=="port") {
  558. port=name[op[op[valu[k],0],0]]
  559. }
  560. edges[nedges,dir]=node SUBSEP port
  561. econn[node,dir,node_idx[node,dir,nedges]=++fan[node,dir]]=nedges
  562. printf "<node id='%s'>\n"\
  563. "<port id='%s'/></node>\n",node, port
  564. print "</" dir ">"
  565. }
  566. }
  567. print "</edge>"
  568. }
  569. }
  570. func dump_edges4(n, i,nel,j,ep,st,iv,k,a,node,port,dir) {
  571. if (DEBUG) print tag[n],n > STDERR
  572. if (!check_edges_type(type[n])) return
  573. nel=split(cons[init[n]],el," ")
  574. for (i=1; i<=nel; i++) { split(el[i],iv,SUBSEP)
  575. if (split(cons[iv[2]],st," ")!=3) continue
  576. print "<edge>"
  577. ++nedges
  578. for (j=1; j<=3; j++) { split(st[j],iv,SUBSEP)
  579. dir=name[iv[1]]
  580. if (dir=="type")
  581. {
  582. edge_type[nedges]=name[op[op[iv[2],0],0]]
  583. print "<type>" edge_type[nedges] "</type>"
  584. }
  585. if (dir==Out || dir==In)
  586. {
  587. print "<" dir ">"
  588. if (split(cons[iv[2]],ep," ")!=2) continue
  589. for (k=1; k<=2; k++) { split(ep[k],a,SUBSEP); if (name[a[1]]!="node") continue
  590. node=name[op[op[a[2],0],0]]
  591. }
  592. for (k=1; k<=2; k++) { split(ep[k],a,SUBSEP); if (name[a[1]]!="port") continue
  593. port=name[op[op[a[2],0],0]]
  594. }
  595. edges[nedges,dir]=node SUBSEP port
  596. econn[node,dir,node_idx[node,dir,nedges]=++fan[node,dir]]=nedges
  597. printf "<node id='%s'>\n"\
  598. "<port id='%s'/></node>\n",node, port
  599. print "</" dir ">"
  600. }
  601. }
  602. print "</edge>"
  603. }
  604. }
  605. func recurse(n, i,np) {
  606. if (visited[n]) return
  607. printf space(2) "<node id='%s' %s/>\n",n,attwrap("mode",mode[n])
  608. visited[n]=1
  609. for (i=1; i<=fan[n,Out]; i++) {
  610. split(edges[econn[n,Out,i],In],np,SUBSEP)
  611. #print np[1],np[2]
  612. recurse(np[1])
  613. }
  614. }
  615. func dump_sched(n) {
  616. if (GCC < 40100)
  617. return dump_sched3(n)
  618. return dump_sched4(n)
  619. }
  620. func dump_sched3(n, e,el,nel,i,a,ar,iv,c) {
  621. if (DEBUG) print tag[n],lngt[init[n]],cons[init[n]] > STDERR
  622. printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",file[n])
  623. nel=split(cons[init[n]],el," ")
  624. # resolve index ptrs in cons
  625. if (nel) for (i=1; i<=nel; i++) {
  626. split(el[i],iv,SUBSEP)
  627. a[low[iv[1]]]=op[iv[2],0]
  628. } else for (i=elts[init[n]]; i; i=chan[i])
  629. a[low[purp[i]]]=valu[i]
  630. nel=asorti(a,ar)
  631. # iterate on all (increasing) indexes
  632. for (i=1; i<=nel;i++) {
  633. if (DEBUG) print i,ar[i],a[ar[i]] > STDERR
  634. e=a[ar[i]]
  635. c=name[op[op[e,0],0]]
  636. printf space(2) "<node id='%s' %s/>\n",c,attwrap("mode",mode[c])
  637. }
  638. print "</" OP ">"
  639. }
  640. func dump_sched4(n, e,el,nel,i,a,ar,iv,c) {
  641. if (DEBUG) print tag[n],lngt[init[n]],cons[init[n]] > STDERR
  642. printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",file[n])
  643. nel=split(cons[init[n]],el," ")
  644. # resolve index ptrs in cons
  645. if (nel) for (i=1; i<=nel; i++) {
  646. split(el[i],iv,SUBSEP)
  647. a[low[iv[1]]]=op[iv[2],0]
  648. } else for (i=elts[init[n]]; i; i=chan[i])
  649. a[low[purp[i]]]=valu[i]
  650. nel=asorti(a,ar)
  651. # iterate on all (increasing) indexes
  652. for (i=1; i<=nel;i++) {
  653. if (DEBUG) print i,ar[i],a[ar[i]] > STDERR
  654. e=a[ar[i]]
  655. c=name[op[e,0]]
  656. printf space(2) "<node id='%s' %s/>\n",c,attwrap("mode",mode[c])
  657. }
  658. print "</" OP ">"
  659. }
  660. # parse pragma's from pre-processed source, since these are not there in
  661. # the parse tree...
  662. func pragma_map(file, nr,i,nt,op,t,fs,m) {
  663. if (DEBUG) print SRC,DIR > STDERR
  664. if (!SRC) fail("no pre-processed source specified!")
  665. fs=FS
  666. FS="[ \t]+"
  667. for (nr=-1; getline < SRC; nr+=(nr>=0))
  668. {
  669. if (DEBUG) print nr, $0 > STDERR
  670. if ($0 ~ /^# [0-9]/) {
  671. if ($3 ~ "^\"(\\./)?" (DIR ? DIR "/" : "") file "\"$") {
  672. nr=$2-1
  673. if (DEBUG) print "nr set to",nr > STDERR
  674. } else nr=-1
  675. }
  676. if (m) Lime[m,nr]=t
  677. if ($1 !~ "#[[:space:]]*pragma") continue
  678. if ($2 != "lime:") continue
  679. op=nt=""
  680. for (i=3; i<=NF; i++) {
  681. if ($i=="push" || $i=="pop") { op=$i; continue }
  682. if ($i=="type") { m=$i; continue }
  683. nt=append(nt,$i)
  684. }
  685. if (op=="push" && nt) {
  686. t=add_node_type(t,nt)
  687. continue
  688. }
  689. if (op=="pop") {
  690. t=del_node_type(t,nt)
  691. continue
  692. }
  693. if (nt) t=nt
  694. }
  695. close(SRC)
  696. FS=fs
  697. }
  698. func swizzle(n) {
  699. if (ptrd[n]) return ptrd[n]
  700. if (elts[n]) return elts[n]
  701. return n
  702. }
  703. func dump_port(n,sel,stag,sname) {
  704. #print n,type[n],ptrd[type[n]],tag[ptrd[type[n]]],name[ptrd[type[n]]] >STDERR
  705. if (!name[swizzle(type[n])]) if (handle_variants(n)) return
  706. if (tag[swizzle(type[n])]=="record_type" && !name[swizzle(type[n])])
  707. return dump_multiport(n,sel,stag,sname)
  708. if (tag[swizzle(type[n])]=="union_type" && !name[swizzle(type[n])])
  709. return dump_multiport(n,sel,stag,sname)
  710. return dump_port_simple(n,sel,stag,sname)
  711. }
  712. func dump_multiport(n,sel,stag,sname, f,ns,size,i)
  713. {
  714. if (tag[swizzle(type[n])] != "record_type" &&
  715. tag[swizzle(type[n])] != "union_type")
  716. fail("multiport has to be either a record or a union")
  717. printf space(2) "<port id='%s' %s>\n",name[n],
  718. attwrap("metatag",sname)
  719. if (sel) printf space(2) "<%s>%s</%s>\n",stag,sel,stag
  720. derive_typeinfo(n)
  721. for (i in Modi) printf space(4) "<%s>%s</%s>\n",i,Modi[i],i
  722. ns=split(Size,size,SUBSEP)
  723. for (i=1; i<=ns; i++)
  724. print space(4) "<size>" size[i] "</size>"
  725. printf space(2) "<metatype id='%s'/>\n",tag[swizzle(type[n])]
  726. for (f=flds[swizzle(type[n])]; f; f=chan[f]) {
  727. #print name[f] >STDERR
  728. dump_port_simple(f,sel,stag,sname)
  729. }
  730. print space(2) "</port>"
  731. }
  732. # eat up the C array spec
  733. func eat(inp,name, ns, s,bal,str,len)
  734. {
  735. if (!match(inp,"\\<" name "\\>[^\\[]*\\["))
  736. return 0
  737. ns=RSTART
  738. T=substr(inp,1,RSTART-1)
  739. S1=substr(inp,RSTART+RLENGTH-1)
  740. S2=""
  741. s=index(inp,"(")
  742. #print "==",ns,s,inp >STDERR
  743. if (s>0 && s<ns)
  744. {
  745. T=substr(inp,1,s-1)
  746. inp=substr(inp,s+1)
  747. str=inp
  748. len=0
  749. for (bal=1; bal; inp=substr(inp,RSTART+RLENGTH))
  750. {
  751. if (!match(inp,"[()]"))
  752. break
  753. bal+=(substr(inp,RSTART,RLENGTH)=="(")
  754. bal-=(substr(inp,RSTART,RLENGTH)==")")
  755. len+=RSTART-(bal==0)
  756. }
  757. str=substr(str,1,len)
  758. match(str,"\\<" name "\\>")
  759. S1=substr(str,RSTART+RLENGTH)
  760. S2=inp
  761. }
  762. #print "T:",T,"S1:",S1,"S2:",S2 >STDERR
  763. return 1
  764. }
  765. # array info (size, restrict) is missing from .tu
  766. # query the pre-processed source file given the linenr
  767. # assume the whole spec takes just one line
  768. func derive_typeinfo(n, nr,ns,size,el,spec,narg,arg,i,j,a)
  769. {
  770. delete Modi
  771. if (tag[type[n]] == "integer_type" ||
  772. tag[type[n]] == "enumeral_type")
  773. {
  774. if (qual[type[n]]=="c") Modi["const"]=1
  775. Size=1
  776. Type=_type(type[n])
  777. return
  778. }
  779. Type=Size=""
  780. #pfile=gensub(/\.[ch]/,".E","g",file[n])
  781. if (DEBUG) print "here:",tag[n],name[n],_type(type[n]),SRC,DIR,file[n],line[n] > STDERR
  782. if (!SRC) fail("no pre-processed source specified!")
  783. for (nr=-1; getline < SRC; nr+=(nr>=0))
  784. {
  785. if ($0 ~ /^# [0-9]/) {
  786. if (DEBUG) print nr, DIR, $3 > STDERR
  787. if ($3 ~ "^\"(\\./)?" (DIR ? DIR "/" : "") file[n] "\"$") {
  788. nr=$2
  789. if (DEBUG) print "nr set to",nr > STDERR
  790. } else
  791. nr=-1
  792. }
  793. if (nr<line[n]) continue
  794. if (DEBUG) print "found line:",line[n],$0 > STDERR
  795. if (match($0,/^.*[[:space:]]+([a-z$A-Z_][a-z$A-Z_0-9]*)[[:space:]]*\(([^*].*)\)(.*[^;])$/,el) ||
  796. match($0,/^[[:space:]]*([a-z$A-Z_][a-z$A-Z_0-9]*)[[:space:]]*\(([^*].*)\)(.*[^;])$/,el) ||
  797. match($0,/^.*[[:space:]]+([a-z$A-Z_][a-z$A-Z_0-9]*)[[:space:]]*\(([^*].*[^;])$/,el))
  798. {
  799. # new style
  800. if (el[2] ~ /^[a-z$A-Z_][a-z$A-Z_0-9]*$/)
  801. spec=el[3]
  802. else
  803. spec=el[2]
  804. } else {
  805. # KR style
  806. spec=$0
  807. }
  808. if (DEBUG) print "spec:",spec,"el","'" el[1] "'","'" el[2] "'","'" el[3] "'" > STDERR
  809. narg=split(spec,arg,",")
  810. for (i=1; i<=narg; i++)
  811. {
  812. if (DEBUG) print arg[i] > STDERR
  813. if (!eat(arg[i],name[n])) continue
  814. if (DEBUG) print "HERE","'" T "'", "'" S1 "'","'" S2 "'" >STDERR
  815. Type=gensub(/[[:space:]]*$/,"","g",T)
  816. size=S1 #el[3]
  817. if (S2) while (match(S2,"^[[:space:]]*\\[([^]]*)\\]",a)) {
  818. Modi["packetsize"]=append(Modi["packetsize"],a[1],SUBSEP)
  819. S2=substr(S2,RSTART+RLENGTH)
  820. }
  821. if (!size) {
  822. #warn("\n" file[n] ":" line[n] ": unspecified size - 1 assumed!")
  823. size="[1]"
  824. }
  825. while (match(size,"^[[:space:]]*\\[([^]]*)\\]",el)) {
  826. Size=append(Size,el[1],SUBSEP)
  827. size=substr(size,RSTART+RLENGTH)
  828. }
  829. if (!Size) fail("could not find any sizes for " name[n] "!")
  830. for (j=1; j<=2; j++)
  831. {
  832. gsub(/^[[:space:]]*/,"",Type)
  833. if (gsub(/^__inout__/,"",Type))
  834. Modi["inout"]=1
  835. if (gsub(/^volatile/,"",Type))
  836. Modi["volatile"]=1
  837. if (gsub(/^const/,"",Type) || qual[ptrd[type[n]]]=="c")
  838. Modi["const"]=1
  839. }
  840. for(j=1; j<=4; j++)
  841. {
  842. gsub(/^[[:space:]]*/,"",Size)
  843. if (gsub(/^volatile/,"",Size))
  844. Modi["volatilep"]=1
  845. if (gsub(/^const/,"",Size))
  846. Modi["constp"]=1
  847. if (gsub(/^static/,"",Size))
  848. Modi["static"]=1
  849. if (gsub(/^restrict/,"",Size))
  850. Modi["restrict"]=1
  851. }
  852. break
  853. }
  854. if (i<=narg) break
  855. if (nr-line[n]>1) fail("no typeinfo can be derived for " name[n])
  856. }
  857. close(SRC)
  858. }
  859. # array info (size, restrict) is missing from .tu
  860. # query the pre-processed source file given the linenr
  861. # assume the whole spec takes just one line
  862. func dump_port_simple(n,sel,stag,sname, ns,size,i) {
  863. if (!stag) stag="tag"
  864. printf space(2) "<port id='%s' calltype='%s' %s>\n",name[n],tag[type[n]],
  865. attwrap("metatag",sname)
  866. if (sel) printf space(2) "<%s>%s</%s>\n",stag,sel,stag
  867. derive_typeinfo(n)
  868. for (i in Modi) printf space(4) "<%s>%s</%s>\n",i,Modi[i],i
  869. print space(4) "<type>" Type "</type>"
  870. ns=split(Size,size,SUBSEP)
  871. #print ns,Size >STDERR
  872. for (i=1; i<=ns; i++)
  873. print space(4) "<size>" size[i] "</size>"
  874. print space(2) "</port>"
  875. }
  876. # switch must be in a tail position
  877. func handle_metamorph(n, e,mod,t,i) {
  878. for (n=body[n]; n && tag[n] != "switch_stmt"; n=Next[n]) {
  879. if (tag[n]=="compound_stmt") n=body[n]
  880. }
  881. if (!n) fail("misformed metamorph 1")
  882. t=op[cond[n],0]
  883. if (tag[t] == "component_ref") t=type[op[t,1]]
  884. else t=ptrd[type[op[t,0]]]
  885. #print t,type[t],tag[t] >STDERR
  886. if (tag[t] != "enumeral_type") fail("misformed metamorph 2.1")
  887. for(i=csts[t]; i; i=chan[i]) select[low[valu[i]]]=name[purp[i]]
  888. if (!(n=Next[body[Next[body[body[n]]]]])) fail("misformed metamorph 3")
  889. do {
  890. if (tag[n] != "case_label") fail("misformed metamorph 4")
  891. #print tag[n],low[n],low[low[n]] >STDERR
  892. mod=low[low[n]]
  893. if (!(n=Next[n])) fail("misformed metamorph 5")
  894. if (tag[n] != "return_stmt") fail("misformed metamorph 6")
  895. #print tag[n],expr[n] >STDERR
  896. if (!(e=expr[n])) fail("misformed metamorph 6.0")
  897. if (tag[e] != "modify_expr") fail("misformed metamorph 6.1")
  898. for (e=op[e,1];tag[e]=="nop_expr";e=op[e,0]);
  899. if (tag[e]=="integer_cst" && low[e]=="0"); else
  900. {
  901. if (tag[e]!="addr_expr") fail("misformed metamorph 6.2:" e "," tag[e])
  902. if (tag[e=op[e,0]]!="function_decl") fail("misformed metamorph 6.3")
  903. }
  904. # TODO For now...
  905. mode[name[e]]=append(mode[name[e]],select[mod],"|")
  906. #print name[e],mode[name[e]],mod >STDERR
  907. if (!(n=Next[n])) fail("misformed metamorph 7")
  908. } while(tag[n] == "case_label")
  909. if (tag[n] != "scope_stmt" || modi[n] !~ /end/) fail("misformed metamorph 8")
  910. }
  911. func dump_comp(n, comp) {
  912. if (DEBUG) print file[n],name[n],tag[n],retn[type[n]],args[n] > STDERR
  913. comp=name[n]
  914. comps[++ncomps]=comp
  915. printf "<node id='%s'>\n",comp
  916. if (Lime["type",line[n]]) print "<type>" Lime["type",line[n]] "</type>"
  917. node_ret[comp]=name[name[retn[type[n]]]]
  918. if (!node_ret[comp]) node_ret[comp]=name[retn[type[n]]]
  919. if (tag[retn[type[n]]]=="record_type")
  920. node_ret[comp]=append("struct",node_ret[comp])
  921. print space(2) "<ret>" node_ret[comp] "</ret>"
  922. if (node_ret[comp] ~ /controller/) handle_metamorph(body[n])
  923. for (n=args[n]; n; n=chan[n]) {
  924. if (tag[type[n]]=="pointer_type" ||
  925. tag[type[n]]=="integer_type" ||
  926. tag[type[n]]=="enumeral_type")
  927. {
  928. dump_port(n)
  929. continue
  930. }
  931. fail("\n" file[n] ":" line[n] ":unsupported parameter type:" tag[type[n]])
  932. }
  933. print "</node>"
  934. }
  935. func domn2size(t) {
  936. return _expr(maxi[domn[t]])+1
  937. }
  938. func elts2type(t, s) {
  939. s=_expr(elts[t])
  940. return substr(s,2,length(s)-2)
  941. }
  942. ###################################################################################3
  943. func __Type(t,des) {
  944. if (tag[name[t]]=="type_decl") return name[name[t]]
  945. if (unql[t]) return append(des,name[unql[t]])
  946. return des
  947. }
  948. func _Type(t) {
  949. m=(modi[t] ? modi[t] " " : "")
  950. if (tag[t]=="pointer_type") return m _Type(ptrd[t]) "*"
  951. else if (tag[t]=="reference_type") return m _Type(refd[t]) "&"
  952. else if (tag[t]=="record_type") return __Type(t,"struct")
  953. else if (tag[t]=="enumeral_type") return __Type(t,"enum")
  954. else if (tag[t]=="union_type") return __Type(t,"union")
  955. else if (tag[t]=="void_type") return m "void"
  956. else if (tag[t]=="real_type") return m "float"
  957. else if (tag[t]=="integer_type") return __Type(t,m)
  958. else if (tag[t]=="array_type")
  959. return m elts2type(t) "[" domn2size(t) "]"
  960. else if (tag[t]=="function_type")
  961. return m _Type(retn[t]) "(*)(" _params(prms[t]) ")"
  962. else if (VERBOSE) printf "Unknown type: %s %s\n",t,tag[t] >STDERR
  963. }
  964. func _name(n,t) {
  965. t=_Type(n)
  966. if (t ~ /^struct[[:space:]]*$/) return append(t,name[n])
  967. if (t ~ /^enum[[:space:]]*$/) return append(t,name[n])
  968. return name[n]
  969. }
  970. func __type(t,des) {
  971. if (tag[name[t]]=="type_decl") return name[name[t]]
  972. #if (unql[t]) return append(append(des,name[unql[t]]),name[t])
  973. if (unql[t])
  974. if (name[unql[t]] ~ /^[0-9]/)
  975. return name[name[unql[t]]]
  976. else
  977. return append(des,name[unql[t]])
  978. return append(des,name[t])
  979. }
  980. func _type(t) {
  981. m=(modi[t] ? modi[t] " " : "")
  982. if (tag[t]=="pointer_type") return m _type(ptrd[t]) "*"
  983. else if (tag[t]=="reference_type") return m _type(refd[t]) "&"
  984. else if (tag[t]=="record_type") return __type(t,"struct")
  985. else if (tag[t]=="enumeral_type") return __type(t,"enum")
  986. else if (tag[t]=="union_type") return __type(t,"union")
  987. else if (tag[t]=="void_type") return m "void"
  988. else if (tag[t]=="real_type") return m "float"
  989. else if (tag[t]=="integer_type") return __type(t,m)
  990. else if (tag[t]=="array_type")
  991. return m elts2type(t) "[" domn2size(t) "]"
  992. else if (tag[t]=="function_type")
  993. return m _type(retn[t]) "(*)(" _params(prms[t]) ")"
  994. else if (VERBOSE) printf "Unknown type: %s %s\n",t,tag[t] >STDERR
  995. }
  996. func _return_type(t) {
  997. if (tag[t]=="function_type")
  998. return _type(retn[t])
  999. }
  1000. func _const(c) {
  1001. #t=( type[c] ? "(" _type(type[c]) ")" : "")
  1002. if (tag[c]=="integer_cst") return t low[c]
  1003. else if (tag[c]=="string_cst") return t name[c]
  1004. else if (tag[c]=="real_cst") return t "0"
  1005. else printf "Unknown const: %s %s\n",c,tag[c] >STDERR
  1006. }
  1007. func _decl(t) {
  1008. i=init[t]
  1009. if (i) return (modi[t] ? modi[t] " " : "")\
  1010. sprintf("%s %s = %s",_type(type[t]),
  1011. name[t],
  1012. _expr(i))
  1013. return sprintf("%s %s",_type(type[t]),name[t])
  1014. }
  1015. func _params(t) { r=""
  1016. for (first=1; t; t=chan[t]) {
  1017. r=r sprintf("%s%s %s",
  1018. (first ? "" : ", "),
  1019. _type(type[t]),name[t])
  1020. first=0
  1021. }
  1022. return r
  1023. }
  1024. func _elems(t) { r=""
  1025. for (first=1; t; t=chan[t]) {
  1026. r=r sprintf("%s%s",(first ? "" : ", "),
  1027. _expr(valu[t]))
  1028. first=0
  1029. }
  1030. return r
  1031. }
  1032. func _cons(t) { r=""
  1033. for (first=1; t; t=chan[t]) {
  1034. r=r (first ? "" : ", ")
  1035. if (purp[t]) r=r name[purp[t]] ": "
  1036. r=r _expr(valu[t])
  1037. first=0
  1038. }
  1039. return r
  1040. }
  1041. func escape(s) {
  1042. gsub(/\n/,"\\n",s)
  1043. gsub(/\t/,"\\t",s)
  1044. gsub(/\r/,"\\r",s)
  1045. gsub(/\a/,"\\a",s)
  1046. gsub(/\b/,"\\b",s)
  1047. return s
  1048. }
  1049. func _expr(c) {
  1050. if (!c) return ""
  1051. #t=( type[c] ? "(" _type(type[c]) ")" : "")
  1052. if (DEBUG) print c,tag[c],qual[c] >STDERR
  1053. if (0) {}
  1054. else if (tag[c]=="bit_not_expr")
  1055. return sprintf(t "( !%s )",_expr(op[c,0]))
  1056. else if (tag[c]=="negate_expr")
  1057. return sprintf(t "( ~%s )",_expr(op[c,0]))
  1058. else if (tag[c]=="ne_expr")
  1059. return sprintf(t "( %s != %s )",_expr(op[c,0]),_expr(op[c,1]))
  1060. else if (tag[c]=="eq_expr")
  1061. return sprintf(t "( %s == %s )",_expr(op[c,0]),_expr(op[c,1]))
  1062. else if (tag[c]=="le_expr")
  1063. return sprintf(t "( %s <= %s )",_expr(op[c,0]),_expr(op[c,1]))
  1064. else if (tag[c]=="ge_expr")
  1065. return sprintf(t "( %s >= %s )",_expr(op[c,0]),_expr(op[c,1]))
  1066. else if (tag[c]=="lt_expr")
  1067. return sprintf(t "( %s < %s )",_expr(op[c,0]),_expr(op[c,1]))
  1068. else if (tag[c]=="gt_expr")
  1069. return sprintf(t "( %s > %s )",_expr(op[c,0]),_expr(op[c,1]))
  1070. else if (tag[c]=="preincrement_expr")
  1071. return sprintf(t "( +%s = %s )",_expr(op[c,0]),_expr(op[c,1]))
  1072. else if (tag[c]=="predecrement_expr")
  1073. return sprintf(t "( -%s = %s )",_expr(op[c,0]),_expr(op[c,1]))
  1074. else if (tag[c]=="postincrement_expr")
  1075. return sprintf(t "( %s += %s )",_expr(op[c,0]),_expr(op[c,1]))
  1076. else if (tag[c]=="postdecrement_expr")
  1077. return sprintf(t "( %s -= %s )",_expr(op[c,0]),_expr(op[c,1]))
  1078. else if (tag[c]=="rshift_expr")
  1079. return sprintf(t "( %s >> %s )",_expr(op[c,0]),_expr(op[c,1]))
  1080. else if (tag[c]=="lshift_expr")
  1081. return sprintf(t "( %s @<< %s )",_expr(op[c,0]),_expr(op[c,1]))
  1082. else if (tag[c]=="truth_andif_expr")
  1083. return sprintf(t "( %s && %s )",_expr(op[c,0]),_expr(op[c,1]))
  1084. else if (tag[c]=="truth_orif_expr")
  1085. return sprintf(t "( %s || %s )",_expr(op[c,0]),_expr(op[c,1]))
  1086. else if (tag[c]=="bit_ior_expr")
  1087. return sprintf(t "( %s | %s )",_expr(op[c,0]),_expr(op[c,1]))
  1088. else if (tag[c]=="bit_and_expr")
  1089. return sprintf(t "( %s & %s )",_expr(op[c,0]),_expr(op[c,1]))
  1090. else if (tag[c]=="bit_xor_expr")
  1091. return sprintf(t "( %s ^ %s )",_expr(op[c,0]),_expr(op[c,1]))
  1092. else if (tag[c]=="mult_expr")
  1093. return sprintf(t "( %s * %s )",_expr(op[c,0]),_expr(op[c,1]))
  1094. else if (tag[c]=="plus_expr")
  1095. return sprintf(t "( %s + %s )",_expr(op[c,0]),_expr(op[c,1]))
  1096. else if (tag[c]=="minus_expr")
  1097. return sprintf(t "( %s - %s )",_expr(op[c,0]),_expr(op[c,1]))
  1098. else if (tag[c]=="trunc_div_expr")
  1099. return sprintf(t "( %s / %s )",_expr(op[c,0]),_expr(op[c,1]))
  1100. else if (tag[c]=="exact_div_expr")
  1101. return sprintf(t "( %s / %s )",_expr(op[c,0]),_expr(op[c,1]))
  1102. else if (tag[c]=="trunc_mod_expr")
  1103. return sprintf(t "( %s %% %s )",_expr(op[c,0]),_expr(op[c,1]))
  1104. else if (tag[c]=="compound_expr")
  1105. return sprintf(t "( %s , %s )",_expr(op[c,0]),_expr(op[c,1]))
  1106. else if (tag[c]=="cond_expr")
  1107. return sprintf(t "( %s ? %s : %s )",
  1108. _expr(op[c,0]),
  1109. _expr(op[c,1]),_expr(op[c,2]))
  1110. else if (tag[c]=="min_expr")
  1111. return sprintf(t "( %s < %s ? %s : %s )",
  1112. _expr(op[c,0]),_expr(op[c,1]),
  1113. _expr(op[c,0]),_expr(op[c,1]))
  1114. else if (tag[c]=="max_expr")
  1115. return sprintf(t "( %s > %s ? %s : %s )",
  1116. _expr(op[c,0]),_expr(op[c,1]),
  1117. _expr(op[c,0]),_expr(op[c,1]))
  1118. else if (tag[c]=="modify_expr") {
  1119. if (tag[op[c,0]]=="result_decl")
  1120. return sprintf(t "( %s )",_expr(op[c,1]))
  1121. else
  1122. return sprintf(t "%s = %s",_expr(op[c,0]),
  1123. _expr(op[c,1]))
  1124. }
  1125. else if (tag[c]=="addr_expr") {
  1126. if (DEBUG) print "!!",c,tag[c],tag[op[c,0]] > STDERR
  1127. if (tag[op[c,0]]=="function_decl")
  1128. return sprintf("%s",name[op[c,0]])
  1129. else if (tag[op[c,0]]=="string_cst")
  1130. return sprintf("\"%s\"",escape(name[op[c,0]]))
  1131. else
  1132. return sprintf("&%s",name[op[c,0]])
  1133. }
  1134. else if (tag[c]=="call_expr") return sprintf(t "%s ( %s )",
  1135. _expr(Func[c]),_elems(args[c]))
  1136. else if (tag[c]=="float_expr")
  1137. return sprintf(t "( %s )",_expr(op[c,0]))
  1138. else if (tag[c]=="convert_expr")
  1139. return sprintf(t "%s",_expr(op[c,0]))
  1140. else if (tag[c]=="nop_expr")
  1141. return sprintf(t "( %s )",_expr(op[c,0]))
  1142. else if (tag[c]=="expr_stmt") return t _expr(expr[c])
  1143. else if (tag[c]=="expr_with_file_location")
  1144. return t _expr(op[c,0])
  1145. else if (tag[c]=="save_expr") return t _expr(op[c,0])
  1146. else if (tag[c]=="non_lvalue_expr") return t _expr(expr[c])
  1147. else if (tag[c]=="integer_type") return "("\
  1148. (qual[c]=="c" ? "const ": "")\
  1149. name[c] ")"
  1150. else if (tag[c]=="compound_literal_expr") return t
  1151. else if (tag[c]=="constructor") {
  1152. level++
  1153. bb=_cons(elts[c])
  1154. level--
  1155. return "{" bb "}"
  1156. }
  1157. else if (tag[c]=="stmt_expr") {
  1158. level++
  1159. bb=esrap(stmt[c])
  1160. level--
  1161. return t bb
  1162. }
  1163. else if (tag[c]=="array_ref")
  1164. return _expr(op[c,0]) "[" _expr(op[c,1]) "]"
  1165. else if (tag[c]=="indirect_ref") return name[op[c,0]]
  1166. else if (tag[c]=="component_ref") return _expr(op[c,0])\
  1167. (tag[op[c,0]]=="indirect_ref" ? "->" : ".")\
  1168. _expr(op[c,1])
  1169. else if (tag[c] ~ /_decl/) return name[c]
  1170. else if (tag[c] ~ /_cst/) return _const(c)
  1171. else if (tag[c]=="bit_field_ref") return "/*bit_field_ref*/"
  1172. else if (tag[c]=="array_type") return "TODO"
  1173. else if (tag[c]=="record_type") return "TODO"
  1174. else if (tag[c]=="error_mark") return "ERROR"
  1175. else printf "Unknown expr: %s %s %s\n",c,tag[c],name[c] >STDERR
  1176. }
  1177. func esrap(b, i,n) {
  1178. o=""
  1179. # for (; b; b=Next[b])
  1180. # {
  1181. if (DEBUG) print "!!",b,tag[b] > STDERR
  1182. if (LINE_NO && tag[b] != "compound_stmt" &&\
  1183. (line[b] || file[b]))
  1184. o=o put(sprintf("#line %d \"%s\"",
  1185. line[b],file[b]))
  1186. if (0) {}
  1187. else if (tag[b]=="function_decl") {
  1188. o=o put(sprintf("%s %s %s(%s)",
  1189. modi[b],
  1190. _return_type(type[b]),
  1191. name[b],
  1192. _params(args[b])))
  1193. o=o esrap(body[b])
  1194. }
  1195. else if (tag[b]=="statement_list") {
  1196. if (DEBUG) print "!!",stmts[b] > STDERR
  1197. n=split(stmts[b],el," ")
  1198. for (i=1; i<=n; i++) o=o esrap(el[i])
  1199. }
  1200. else if (tag[b]=="label_stmt")
  1201. o=o put(sprintf("%s:",name[labl[b]]),-1)
  1202. else if (tag[b]=="goto_stmt")
  1203. o=o put(sprintf("goto %s;",name[dest[b]]))
  1204. else if (tag[b]=="asm_stmt")
  1205. o=o put(sprintf("__asm__ %s (%s)\n",
  1206. name[strg[b]],_cons(ins[b])))
  1207. else if (tag[b]=="compound_stmt") {
  1208. #o=o put(sprintf("/* compound till %d */", line[b]))
  1209. if (body[b]) o=o esrap(body[b])
  1210. else o=o put(";")
  1211. }
  1212. else if (tag[b]=="scope_stmt") {
  1213. if(modi[b] ~ /begn/) {
  1214. o=o put("{")
  1215. level++
  1216. } else {
  1217. level--
  1218. o=o put("}")
  1219. }
  1220. }
  1221. else if (tag[b]=="decl_stmt") {
  1222. o=o put(sprintf("%s;",_decl(decl[b])))
  1223. }
  1224. else if (tag[b]=="if_stmt") {
  1225. o=o put(sprintf("if %s",_expr(cond[b])))
  1226. level++
  1227. o=o esrap(then[b])
  1228. level--
  1229. if (Else[b]) {
  1230. o=o put("else")
  1231. level++
  1232. o=o esrap(Else[b])
  1233. level--
  1234. }
  1235. }
  1236. else if (tag[b]=="expr_stmt") {
  1237. o=o put(sprintf("%s;",_expr(expr[b])))
  1238. }
  1239. else if (tag[b]=="return_stmt") {
  1240. o=o put(sprintf("return %s;",_expr(expr[b])))
  1241. }
  1242. else if (tag[b]=="for_stmt") {
  1243. o=o put(sprintf("for (%s; %s; %s)",
  1244. _expr(init[b]),
  1245. _expr(cond[b]),
  1246. _expr(expr[b])))
  1247. level++
  1248. if (body[b]) o=o esrap(body[b])
  1249. else o=o put(";")
  1250. level--
  1251. }
  1252. else if (tag[b]=="switch_stmt") {
  1253. o=o put(sprintf("switch (%s)",_expr(cond[b])))
  1254. level++
  1255. if (body[b]) o=o esrap(body[b])
  1256. else o=o put(";")
  1257. level--
  1258. }
  1259. else if (tag[b]=="case_label") {
  1260. if (low[b]) o=o put(sprintf("case %s:",
  1261. _const(substr(low[b],2))),
  1262. -1)
  1263. else o=o put("default:",-1)
  1264. }
  1265. else if (tag[b]=="do_stmt") {
  1266. o=o put("do")
  1267. level++
  1268. if (body[b]) o=o esrap(body[b])
  1269. else o=o put(";")
  1270. level--
  1271. o=o put(sprintf("while (%s);",_expr(cond[b])))
  1272. }
  1273. else if (tag[b]=="while_stmt") {
  1274. o=o put(sprintf("while (%s)",_expr(cond[b])))
  1275. level++
  1276. if (body[b]) o=o esrap(body[b])
  1277. else o=o put(";")
  1278. level--
  1279. }
  1280. else if (tag[b]=="continue_stmt")
  1281. o=o put("continue;")
  1282. else if (tag[b]=="break_stmt")
  1283. o=o put("break;")
  1284. else if (tag[b]=="namespace_decl") {
  1285. o=o put(sprintf("namespace %s {",name[b]))
  1286. level++
  1287. if (dcls[b]) o=o esrap(dcls[b])
  1288. o=o put("}")
  1289. level--
  1290. }
  1291. else
  1292. printf "Unexpected tag: %s %s\n",b,tag[b] >STDERR
  1293. # }
  1294. level-=inc
  1295. return o
  1296. }
  1297. func quote(s) { return gensub(/"/,"\\\\\"","g",s) }
  1298. func pexpr(e) { return quote(_expr(e)) }
  1299. func put(x,incr) {
  1300. y=""
  1301. for (i=0; i<level+incr; i++) y=y "\t"
  1302. y=y x "\n"
  1303. return y
  1304. }
  1305. func Flatten(a,sep,len, i, ret) {
  1306. for (i in a) ret=append(ret,i SUBSEP a[i],sep)
  1307. return ret
  1308. }
  1309. func flatten(a,sep,len, ret) {
  1310. if (!len) for(i in a) len++
  1311. for (i=0; i<len; i++) ret=append(ret,a[i],sep)
  1312. return ret
  1313. }
  1314. func flatten1(a,sep,len, ret) {
  1315. if (!len) for(i in a) len++
  1316. for (i=1; i<=len; i++) ret=append(ret,a[i],sep)
  1317. return ret
  1318. }
  1319. @include pragmas.awk
  1320. @include common.awk