/lib/cparse.awk
AWK | 1512 lines | 1213 code | 188 blank | 111 comment | 0 complexity | 7eb5869c2a1070b8bc2cae9962ee7838 MD5 | raw file
Possible License(s): GPL-2.0
- #!/usr/bin/awk -f
- ##################################################################
- # This AWK script performs parsing of trees generated by
- # gcc -fdump-translation-unit as well as generation of .types, .mod
- # and other files
- #
- #Copyright (C) 2008 NXP Semiconductors B.V.
- #
- #This file is part of LIME.
- #
- #LIME is free software: you can redistribute it and/or modify
- #it under the terms of the GNU General Public License version 2
- #as published by the Free Software Foundation; either version 2
- #of the License, or (at your option) any later version.
- #
- #LIME is distributed in the hope that it will be useful,
- #but WITHOUT ANY WARRANTY; without even the implied warranty of
- #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- #GNU General Public License for more details.
- #
- #You should have received a copy of the GNU General Public License
- #along with LIME. If not, see <http://www.gnu.org/licenses/>.
- ##################################################################
- BEGIN { node=0
- FS="[ \t:]+"
- if (!SCHED) SCHED="sched"
- if (!EDGES) EDGES="edges"
- modifiers["undefined"]=modifiers["volatile"]=\
- modifiers["static"]=modifiers["extern"]=\
- modifiers["struct"]=modifiers["union"]=\
- modifiers["begn"]=modifiers["clnp"]=modifiers["end"]=\
- modifiers["null"]=modifiers["register"]=\
- modifiers["unsigned"]=modifiers["int"]=modifiers["char"]=\
- modifiers["float"]=modifiers["double"]=modifiers["long"]=\
- modifiers["short"]=modifiers["bitfield"]=1
- modifiers["artificial"]=modifiers["C"]=modifiers["operator"]=\
- modifiers["new"]=modifiers["delete"]=\
- modifiers["vecnew"]=modifiers["vecdelete"]=1
- MODE=""
- gsub("/+$","",DIR)
- if (DIR==".") DIR=""
- Out="from"
- In="to"
- }
- MODE=="" { start=1 }
- func finalize() { if (!node) return
- # do this stuff only after all tags of identifier_node
- # have been processed
- if (cur=="identifier_node")
- {
- # identifier_node gives a name to nodes
- if (name[num])
- # don't waste time for this iteration!
- #for (n in name) if (name[n]==num) name[n]=name[num]
- n=split(todo[num],el," ")
- for (i=1; i<=n; i++)
- name[el[i]]=name[num]
- }
- # tag is initialized on the next iteration due to
- # the taglist spanning several lines
- tag[num]=cur
- if (0) {}
- else if (cur=="statement_list") {
- stmts[num]=flatten(List)
- delete List
- }
- else if (cur=="constructor") {
- cons[num]=Flatten(List)
- delete List
- }
- }
- MODE=="" && /^@/ {
- finalize()
- node=1
- num=substr($1,2)
- cur=$2
- start=3
- }
- MODE=="" {
- if (DEBUG>1) printf "loop: %s ",num,cur > STDERR
- for (i=start; i<=NF; i++)
- {
- if (DEBUG>1) printf " %s",$i >STDERR
- if (0) {}
- else if ($i=="name") {
- ref=substr($(++i),2)
- if (ref in name) name[num]=name[ref]
- else {
- name[num]=ref
- todo[ref]=append(todo[ref],num)
- }
- }
- else if ($i=="srcp") {
- file[num]=$(++i)
- line[num]=$(++i)
- srcp[num]=sprintf("%s:%04i",file[num],line[num])
- # if (DEBUG) print file[num],line[num] > STDERR
- }
- else if ($i=="op") {
- opno=$(++i)
- op[num,opno]=substr($(++i),2)
- }
- else if (cur=="case_label" && $i=="low") low[num]=substr($(++i),2)
- else if ($i=="scpe") scpe[num]=substr($(++i),2)
- else if ($i=="fn") Func[num]=substr($(++i),2)
- else if ($i=="init") init[num]=substr($(++i),2)
- else if ($i=="decl") decl[num]=substr($(++i),2)
- else if ($i=="args") args[num]=substr($(++i),2)
- else if ($i=="valu") valu[num]=substr($(++i),2)
- else if ($i=="expr") expr[num]=substr($(++i),2)
- else if ($i=="cond") cond[num]=substr($(++i),2)
- else if ($i=="then") then[num]=substr($(++i),2)
- else if ($i=="else") Else[num]=substr($(++i),2)
- else if ($i=="next") Next[num]=substr($(++i),2)
- else if ($i=="chan") chan[num]=substr($(++i),2)
- else if ($i=="body") body[num]=substr($(++i),2)
- else if ($i=="type") type[num]=substr($(++i),2)
- else if ($i=="retn") retn[num]=substr($(++i),2)
- else if ($i=="size") size[num]=substr($(++i),2)
- else if ($i=="prms") prms[num]=substr($(++i),2)
- else if ($i=="mngl") mngl[num]=substr($(++i),2)
- else if ($i=="unql") unql[num]=substr($(++i),2)
- else if ($i=="refd") refd[num]=substr($(++i),2)
- else if ($i=="elts") elts[num]=substr($(++i),2)
- else if ($i=="bpos") bpos[num]=substr($(++i),2)
- else if ($i=="flds") flds[num]=substr($(++i),2)
- else if ($i=="domn") domn[num]=substr($(++i),2)
- else if ($i=="argt") argt[num]=substr($(++i),2)
- else if ($i=="dest") dest[num]=substr($(++i),2)
- else if ($i=="labl") labl[num]=substr($(++i),2)
- else if ($i=="ptd") ptrd[num]=substr($(++i),2)
- else if ($i=="min") mini[num]=substr($(++i),2)
- else if ($i=="max") maxi[num]=substr($(++i),2)
- else if ($i=="cnst") cnst[num]=substr($(++i),2)
- else if ($i=="clbr") clbr[num]=substr($(++i),2)
- else if ($i=="csts") csts[num]=substr($(++i),2)
- else if ($i=="outs") outs[num]=substr($(++i),2)
- else if ($i=="purp") purp[num]=substr($(++i),2)
- else if ($i=="stmt") stmt[num]=substr($(++i),2)
- else if ($i=="ins") ins[num]=substr($(++i),2)
- else if ($i=="dcls") dcls[num]=substr($(++i),2)
- else if ($i=="vars") vars[num]=substr($(++i),2)
- else if ($i=="idx") idx[num]=substr($(++i),2)
- else if ($i=="val") {
- val[num]=substr($(++i),2)
- List[idx[num]]=val[num]
- #if (DEBUG) print "@",idx[num],List[idx[num]] >STDERR
- }
- else if ($i ~ /^[0-9]+$/) {
- #if (DEBUG) print $i,$(i+1) >STDERR
- #stmts[num]=append(stmts[num],substr($(++i),2))
- List[$i]=substr($(i+1),2)
- i++
- }
- else if ($i=="strg" && cur=="asm_stmt") {
- strg[num]=substr($(++i),2)
- }
- else if ($i=="strg" && cur=="identifier_node") {
- IN_STRG=1
- name[num]=append(name[num],$(++i))
- }
- else if ($i=="lngt") { IN_STRG=0
- lngt[num]=$(++i)
- if (lngt[num]!=length(name[num]) && 0)
- printf "Consistency '%s' %d!=%d\n",
- name[num],lngt[num],
- length(name[num]) > STDERR
- }
- else if ($i=="strg") {
- if (match($0,
- /strg: (.*) lngt: [0-9]+[:space:]*$/,
- a))
- name[num]=a[1]
- else {
- MODE="string"
- string=""
- $0=substr($0,index($0,"strg: ")+6)
- }
- break
- }
- else if ($i=="sign") sign[num]=$(++i)
- else if ($i=="link") link[num]=$(++i)
- else if ($i=="tag") Tag[num]=$(++i)
- else if ($i=="line") line[num]=$(++i)
- else if ($i=="high") high[num]=$(++i)
- else if ($i=="algn") algn[num]=$(++i)
- else if ($i=="prec") prec[num]=$(++i)
- else if ($i=="qual") qual[num]=$(++i)
- else if ($i=="used") used[num]=$(++i)
- else if ($i=="packet") pack[num]=$(++i)
- else if (cur!="case_label" && $i=="low") low[num]=$(++i)
- else if ($i=="segment") seg[num]=$(++i)
- else if ($i=="note") note[num]=$(++i)
- else if ($i=="lang") note[num]=$(++i)
-
- else if ($i ~ /^@/)
- printf "Unknown ref: %s\n",$i > STDERR
- else if ($i in modifiers) {
- if (IN_STRG)
- name[num]=append(name[num],$i)
- else
- modi[num]=append(modi[num],$i)
- }
- else if ($i)
- printf "Unknown tag: '%s'\n",$i > STDERR
- }
- if (DEBUG>1) printf "\n" >STDERR
- }
- # nasty bit covering strg spanning several lines
- MODE=="string" && match($0,/[ \t]*lngt: ([0-9]+)[ \t]*$/,a) {
- string=string substr($0,1,RSTART-1)
- if (0 && a[1]!=length(string)+1)
- printf "Consistency '%s' %d!=%d\n",
- string,a[1],length(string) > STDERR
- name[num]=string
- lngt[num]=a[1]
- MODE=""
- }
- MODE=="string" { string=string $0 "\n" }
- END { finalize()
- if (!OP) OP="cutpoints"
- if (!ORDER) ORDER="lex"
- if (ORDER=="lex") {
- for (i in name) un[name[i]]=append(un[name[i]],i)
- nr=asort(name,sorted)
- }
- if (ORDER=="src") {
- for (i in srcp) un[srcp[i]]=append(un[srcp[i]],i)
- nr=asort(srcp,sorted)
- }
- nops=split(OP,ops,",")
- for (o=1; o<=nops; o++)
- {
- OP=ops[o]
- delete cnt
- if (OP=="comps") pragma_map(FNAME)
- if (OP ~ "^" EDGES) for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (modi[n] ~ /undefined/ ||
- file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (tag[n] !~ /var_decl/) continue
- # gcc-3.4 specifics
- if (scpe[n] && tag[scpe[n]]!="translation_unit_decl" ) continue
- if (FNAME && file[n]!=FNAME) continue
- if (name[n] !~ OP "$") continue
- if (DEBUG) printf "%s:%05d %s %s %s\n",
- file[n],line[n],
- (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
- name[n],modi[n] >STDERR
- dump_edges(n)
- # generate just one edges array
- break
- }
- if (OP ~ "^" SCHED) {
- for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (modi[n] ~ /undefined/ ||
- file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (tag[n] !~ /var_decl/) continue
- # gcc-3.4 specifics
- if (scpe[n] && tag[scpe[n]]!="translation_unit_decl" ) continue
- if (FNAME && file[n]!=FNAME) continue
- if (name[n] !~ "^" OP) continue
- if (DEBUG) printf "%s:%05d %s %s %s\n",
- file[n],line[n],
- (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
- name[n],modi[n] >STDERR
- dump_sched(n)
- # generate just one schedule
- break
- }
- # no schedule array was found
- if (ix>nr && nedges) {
- # generate schedule with all comps
- # in order derived from the local graph
- # for this to work, edges must already be processed
- printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",FNAME)
- # find roots
- delete visited
- for (i=1; i<=ncomps; i++) {
- n=comps[i];
- if (fan[n,In]) continue
- recurse(n)
- }
- # nodes with only self-edges
- for (i=1; i<=ncomps; i++) {
- n=comps[i];
- recurse(n)
- }
- print "</" OP ">"
- break
- }
- if (ix>nr) {
- # generate schedule with all comps
- # in order currently selected {lex,src}
- # for this to work, nodes must already be processed
- if (ncomps<1) fail("Module " FNAME " has no components, probably due to a syntax error!")
- printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",FNAME)
- # controller comes first
- for (i=1; i<=ncomps; i++) if (node_ret[comps[i]] ~ /controller/)
- printf space(2) "<node id='%s'/>\n",comps[i]
- for (i=1; i<=ncomps; i++) if (node_ret[comps[i]] !~ /controller/)
- printf space(2) "<node id='%s' %s/>\n",comps[i],attwrap("mode",mode[comps[i]])
- print "</" OP ">"
- break
- }
- }
- if (OP=="comps") for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (!link[n] && modi[n] ~ /extern/) link[n]="extern"
- if (tag[n] !~ /function_decl/ ||
- link[n] != "extern" ) continue
- if (modi[n] ~ /undefined/ &&
- name[n] ~ /_shell$/)
- {
- printf "<callout id='%s'/>\n",gensub(/_shell$/,"","g",name[n])
- continue
- }
- if (!(name[retn[type[n]]] ~ /actor/ ||
- name[name[retn[type[n]]]] ~ /actor/ ||
- is_ddf_actor(n)))
- {
- #print "skipped",name[n],name[retn[type[n]]] >STDERR
- continue
- }
- if (FNAME && file[n]!=FNAME) continue
- #if (name[n] ~ "^" CONS || name[n] ~ "^" DEST) continue
- if (DEBUG) printf "%s:%05d %s %s\n",
- file[n],line[n],
- name[n],modi[n] >STDERR
- dump_comp(n)
- }
- if (OP=="typedefs") for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (modi[n] ~ /undefined/ ||
- file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (tag[n] !~ /type_decl/) continue
- if (FNAME && file[n]!=FNAME) continue
- if (DEBUG) printf "%s:%05d %s %s\n",
- file[n],line[n],
- name[n],modi[n] >STDERR
- if (name[n] ~ /^[[:digit:]]*$/) continue
- if (name[n] in typedef) continue
- printf "<typedef id='%s'>\n",name[n]
- if (size[n]) print space(2) "<size>" low[size[n]] "</size>"
- if (prec[n]) print space(2) "<prec>" prec[n] "</prec>"
- print space(2) "<type>" _Type(type[n]) "</type>"
- print space(2) "</typedef>"
- typedef[name[n]]=1
- }
- if (OP=="types") for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (modi[n] ~ /undefined/ ||
- file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (tag[n] !~ /void_type/ &&
- tag[n] !~ /integer_type/ &&
- tag[n] !~ /real_type/ &&
- tag[n] !~ /record_type/ &&
- tag[n] !~ /enumeral_type/ &&
- tag[n] !~ /array_type/ &&
- tag[n] !~ /union_type/ &&
- tag[n] !~ /pointer_type/ &&
- tag[n] !~ /reference_type/ &&
- tag[n] !~ /function_type/) continue
- #print tag[n],name[n]
- #no origin info for types
- #if (FNAME && file[n]!=FNAME) continue
- if (DEBUG) printf "%s:%05d %s %s\n",
- file[n],line[n],
- name[n],modi[n] >STDERR
- if (name[n] ~ /^[[:digit:]]*$/) continue
- if (name[n] in typedef) continue
- printf "<typedecl id='%s'>\n",_name(n)
- if (size[n]) print space(2) "<size>" low[size[n]] "</size>"
- if (prec[n]) print space(2) "<prec>" prec[n] "</prec>"
- print space(2) "<type>" _Type(n) "</type>"
- # recognize a discriminated union type
- handle_variants(n)
- print space(2) "</typedecl>"
- typedef[_name(n)]=1
- }
- if (OP=="idents") for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (modi[n] ~ /undefined/ ||
- file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (tag[n] !~ /.*_decl/) continue
- if (FNAME && file[n]!=FNAME) continue
- if (!(name[retn[type[n]]] ~ /actor/ ||
- name[name[retn[type[n]]]] ~ /actor/ ||
- is_ddf_actor(n)))
- continue
- printf "%s:%05d %s %s %s\n",
- file[n],line[n],
- (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
- name[n],modi[n]
- }
- if (OP=="funcs") for (ix=1; ix<=nr; ix++) {
- split(un[sorted[ix]],el," ")
- n=el[++cnt[un[sorted[ix]]]]
- if (modi[n] ~ /undefined/ ||
- file[n] ~ /<built-in>/ ||
- file[n] ~ /<internal>/) continue
- if (tag[n] !~ /function_decl/) continue
- if (FNAME && file[n]!=FNAME) continue
- printf "%s:%05d %s %s %s\n",
- file[n],line[n],
- (link[n] ? link[n] : (scpe[n] ? "scoped" : "extern")),
- name[n],modi[n]
- }
- }
- }
- ###################################################################################3
- func is_ddf_actor(n, m) {
- m=retn[type[n]]
- if (tag[m] == "record_type") {
- if (name[m] ~ /continuation/) return 1
- return 0
- }
- if (tag[m] == "pointer_type") {
- if (tag[ptrd[m]] != "function_type") return 0
- m=retn[ptrd[m]]
- if (tag[m] != "void_type") return 0
- if (name[name[m]] ~ /void/ || name[m] ~ /void/) return 1
- return 0
- }
- return 0
- }
- func handle_variants(n, m,e, sel,uni,i,port,select,nport,v,nsel,values,j,sname)
- {
- if (tag[n] != "record_type") {
- m=name[n]
- e=n
- n=ptrd[type[n]]
- if (tag[n] != "record_type") {
- return 0
- }
- }
- # first field must be an enumeration
- sel=flds[n]
- if (tag[type[sel]] != "enumeral_type") return 0
- # next field must be a union
- uni=chan[sel]
- if (tag[type[uni]] != "union_type") return 0
- # there shall be no further fields
- if (chan[uni]) return 0
- # OK, we've found one:
- if (!m) {
- print space(2) "<variant>"
- printf space(3) "<selector id='%s' type='%s'/>\n",name[sel],_type(type[sel])
- printf space(3) "<ports id='%s'/>\n",name[uni]
- } else {
- printf space(2) "<port id='%s'>\n",m
- derive_typeinfo(e)
- #print m,Size >STDERR
- for (i in Modi) printf space(4) "<%s>%s</%s>\n",i,Modi[i],i
- ns=split(Size,size,SUBSEP)
- for (i=1; i<=ns; i++)
- print space(4) "<size>" size[i] "</size>"
- printf space(2) "<metatype id='%s'/>\n","variant_type"
- sname="_" m "_" name[sel]
- printf space(3) "<port id='%s' type='%s' calltype='%s' size=1/>\n",
- sname, _type(type[sel]),"enumeral_type"
- }
- # iterate on all union fields
- i=flds[type[uni]]
- do port[nport++]=i; while(i=chan[i])
- # iterate on all tag values
- i=csts[type[sel]]
- do {
- n=name[purp[i]]
- v=low[valu[i]]
- if (v<0 || v>=nport) fail("tag value has no matching union field")
- select[v]=n
- #select[nsel++]=n
- } while(i=chan[i])
- for (i=0; i<nport; i++) {
- if (!select[i]) fail("port has no selector")
- # this port is a normal port
- if (tag[swizzle(type[port[i]])] !~ /^record_type$/ || name[swizzle(type[port[i]])]) {
- dump_port(port[i],select[i],m ? "mode" : "tag", sname)
- continue
- }
- #print port[i],name[port[i]],tag[swizzle(type[port[i]])],name[swizzle(type[port[i]])],select[i] >STDERR
- # this port is a multiport
- dump_port(port[i],select[i],m ? "mode" : "tag", sname)
- #for (j=flds[type[port[i]]]; j; j=chan[j]) {
- # print name[j],tag[j] >STDERR
- # dump_port(j,select[i],m ? "mode" : "tag")
- #}
- }
- if (!m) {
- print space(2) "</variant>"
- } else {
- print space(2) "</port>"
- }
- return 1
- }
- func check_edges_type(n, t,fr,to,et,nd,pd) {
- if (tag[n] != "array_type") return 0
- n=elts[n]
- if (tag[n] != "record_type") return 0
- t=flds[n]
- if (tag[type[t]] != "pointer_type" || name[ptrd[type[t]]] != "char") return 0
- fr=chan[t]; et=type[fr]
- # check the type of the from structure
- if (tag[et] != "record_type") return 0
- nd=flds[et]
- if (tag[type[nd]] != "pointer_type" || tag[ptrd[type[nd]]] != "function_type") return 0
- pd=chan[nd]
- if (tag[type[pd]] != "pointer_type" || name[ptrd[type[pd]]] != "char") return 0
- # no more fields
- if (chan[pd]) return 0
- to=chan[fr]
- # the type fo the to structure is the same, just check the tag
- if (type[to] != et) return 0
- if (chan[to]) return 0
- return 1
- }
- func dump_edges(n) {
- if (GCC < 40100)
- return dump_edges3(n)
- return dump_edges4(n)
- }
- func dump_edges3(n, i,nel,j,ep,st,iv,k,a,node,port,dir) {
- if (DEBUG) print tag[n],n > STDERR
- if (!check_edges_type(type[n])) return
- for (i=elts[init[n]]; i; i=chan[i]) {
- print "<edge>"
- ++nedges
- for (j=elts[valu[i]]; j; j=chan[j])
- {
- dir=name[purp[j]]
- if (dir=="type")
- {
- edge_type[nedges]=name[op[op[valu[j],0],0]]
- print "<type>" edge_type[nedges] "</type>"
- }
- if (dir==Out || dir==In)
- {
- print "<" dir ">"
- for (k=elts[valu[j]]; k; k=chan[k]) if (name[purp[k]]=="node") {
- node=name[op[valu[k],0]]
- if (!node) node=name[op[op[valu[k],0],0]]
- }
- for (k=elts[valu[j]]; k; k=chan[k]) if (name[purp[k]]=="port") {
- port=name[op[op[valu[k],0],0]]
- }
- edges[nedges,dir]=node SUBSEP port
- econn[node,dir,node_idx[node,dir,nedges]=++fan[node,dir]]=nedges
- printf "<node id='%s'>\n"\
- "<port id='%s'/></node>\n",node, port
- print "</" dir ">"
- }
- }
- print "</edge>"
- }
- }
- func dump_edges4(n, i,nel,j,ep,st,iv,k,a,node,port,dir) {
- if (DEBUG) print tag[n],n > STDERR
- if (!check_edges_type(type[n])) return
-
- nel=split(cons[init[n]],el," ")
- for (i=1; i<=nel; i++) { split(el[i],iv,SUBSEP)
- if (split(cons[iv[2]],st," ")!=3) continue
- print "<edge>"
- ++nedges
- for (j=1; j<=3; j++) { split(st[j],iv,SUBSEP)
- dir=name[iv[1]]
- if (dir=="type")
- {
- edge_type[nedges]=name[op[op[iv[2],0],0]]
- print "<type>" edge_type[nedges] "</type>"
- }
- if (dir==Out || dir==In)
- {
- print "<" dir ">"
- if (split(cons[iv[2]],ep," ")!=2) continue
- for (k=1; k<=2; k++) { split(ep[k],a,SUBSEP); if (name[a[1]]!="node") continue
- node=name[op[op[a[2],0],0]]
- }
- for (k=1; k<=2; k++) { split(ep[k],a,SUBSEP); if (name[a[1]]!="port") continue
- port=name[op[op[a[2],0],0]]
- }
- edges[nedges,dir]=node SUBSEP port
- econn[node,dir,node_idx[node,dir,nedges]=++fan[node,dir]]=nedges
- printf "<node id='%s'>\n"\
- "<port id='%s'/></node>\n",node, port
- print "</" dir ">"
- }
- }
- print "</edge>"
- }
- }
- func recurse(n, i,np) {
- if (visited[n]) return
- printf space(2) "<node id='%s' %s/>\n",n,attwrap("mode",mode[n])
- visited[n]=1
- for (i=1; i<=fan[n,Out]; i++) {
- split(edges[econn[n,Out,i],In],np,SUBSEP)
- #print np[1],np[2]
- recurse(np[1])
- }
- }
- func dump_sched(n) {
- if (GCC < 40100)
- return dump_sched3(n)
- return dump_sched4(n)
- }
- func dump_sched3(n, e,el,nel,i,a,ar,iv,c) {
- if (DEBUG) print tag[n],lngt[init[n]],cons[init[n]] > STDERR
- printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",file[n])
- nel=split(cons[init[n]],el," ")
- # resolve index ptrs in cons
- if (nel) for (i=1; i<=nel; i++) {
- split(el[i],iv,SUBSEP)
- a[low[iv[1]]]=op[iv[2],0]
- } else for (i=elts[init[n]]; i; i=chan[i])
- a[low[purp[i]]]=valu[i]
- nel=asorti(a,ar)
- # iterate on all (increasing) indexes
- for (i=1; i<=nel;i++) {
- if (DEBUG) print i,ar[i],a[ar[i]] > STDERR
- e=a[ar[i]]
- c=name[op[op[e,0],0]]
- printf space(2) "<node id='%s' %s/>\n",c,attwrap("mode",mode[c])
- }
- print "</" OP ">"
- }
- func dump_sched4(n, e,el,nel,i,a,ar,iv,c) {
- if (DEBUG) print tag[n],lngt[init[n]],cons[init[n]] > STDERR
- printf "<%s id='%s'>\n",OP,gensub(/\.c$/,"","g",file[n])
- nel=split(cons[init[n]],el," ")
- # resolve index ptrs in cons
- if (nel) for (i=1; i<=nel; i++) {
- split(el[i],iv,SUBSEP)
- a[low[iv[1]]]=op[iv[2],0]
- } else for (i=elts[init[n]]; i; i=chan[i])
- a[low[purp[i]]]=valu[i]
- nel=asorti(a,ar)
- # iterate on all (increasing) indexes
- for (i=1; i<=nel;i++) {
- if (DEBUG) print i,ar[i],a[ar[i]] > STDERR
- e=a[ar[i]]
- c=name[op[e,0]]
- printf space(2) "<node id='%s' %s/>\n",c,attwrap("mode",mode[c])
- }
- print "</" OP ">"
- }
- # parse pragma's from pre-processed source, since these are not there in
- # the parse tree...
- func pragma_map(file, nr,i,nt,op,t,fs,m) {
- if (DEBUG) print SRC,DIR > STDERR
- if (!SRC) fail("no pre-processed source specified!")
- fs=FS
- FS="[ \t]+"
- for (nr=-1; getline < SRC; nr+=(nr>=0))
- {
- if (DEBUG) print nr, $0 > STDERR
- if ($0 ~ /^# [0-9]/) {
- if ($3 ~ "^\"(\\./)?" (DIR ? DIR "/" : "") file "\"$") {
- nr=$2-1
- if (DEBUG) print "nr set to",nr > STDERR
- } else nr=-1
- }
- if (m) Lime[m,nr]=t
- if ($1 !~ "#[[:space:]]*pragma") continue
- if ($2 != "lime:") continue
- op=nt=""
- for (i=3; i<=NF; i++) {
- if ($i=="push" || $i=="pop") { op=$i; continue }
- if ($i=="type") { m=$i; continue }
- nt=append(nt,$i)
- }
- if (op=="push" && nt) {
- t=add_node_type(t,nt)
- continue
- }
- if (op=="pop") {
- t=del_node_type(t,nt)
- continue
- }
- if (nt) t=nt
- }
- close(SRC)
- FS=fs
- }
- func swizzle(n) {
- if (ptrd[n]) return ptrd[n]
- if (elts[n]) return elts[n]
- return n
- }
- func dump_port(n,sel,stag,sname) {
- #print n,type[n],ptrd[type[n]],tag[ptrd[type[n]]],name[ptrd[type[n]]] >STDERR
- if (!name[swizzle(type[n])]) if (handle_variants(n)) return
- if (tag[swizzle(type[n])]=="record_type" && !name[swizzle(type[n])])
- return dump_multiport(n,sel,stag,sname)
- if (tag[swizzle(type[n])]=="union_type" && !name[swizzle(type[n])])
- return dump_multiport(n,sel,stag,sname)
- return dump_port_simple(n,sel,stag,sname)
- }
- func dump_multiport(n,sel,stag,sname, f,ns,size,i)
- {
- if (tag[swizzle(type[n])] != "record_type" &&
- tag[swizzle(type[n])] != "union_type")
- fail("multiport has to be either a record or a union")
- printf space(2) "<port id='%s' %s>\n",name[n],
- attwrap("metatag",sname)
- if (sel) printf space(2) "<%s>%s</%s>\n",stag,sel,stag
- derive_typeinfo(n)
- for (i in Modi) printf space(4) "<%s>%s</%s>\n",i,Modi[i],i
- ns=split(Size,size,SUBSEP)
- for (i=1; i<=ns; i++)
- print space(4) "<size>" size[i] "</size>"
- printf space(2) "<metatype id='%s'/>\n",tag[swizzle(type[n])]
- for (f=flds[swizzle(type[n])]; f; f=chan[f]) {
- #print name[f] >STDERR
- dump_port_simple(f,sel,stag,sname)
- }
- print space(2) "</port>"
- }
- # eat up the C array spec
- func eat(inp,name, ns, s,bal,str,len)
- {
- if (!match(inp,"\\<" name "\\>[^\\[]*\\["))
- return 0
- ns=RSTART
- T=substr(inp,1,RSTART-1)
- S1=substr(inp,RSTART+RLENGTH-1)
- S2=""
- s=index(inp,"(")
- #print "==",ns,s,inp >STDERR
- if (s>0 && s<ns)
- {
- T=substr(inp,1,s-1)
- inp=substr(inp,s+1)
- str=inp
- len=0
- for (bal=1; bal; inp=substr(inp,RSTART+RLENGTH))
- {
- if (!match(inp,"[()]"))
- break
- bal+=(substr(inp,RSTART,RLENGTH)=="(")
- bal-=(substr(inp,RSTART,RLENGTH)==")")
- len+=RSTART-(bal==0)
- }
- str=substr(str,1,len)
- match(str,"\\<" name "\\>")
- S1=substr(str,RSTART+RLENGTH)
- S2=inp
- }
- #print "T:",T,"S1:",S1,"S2:",S2 >STDERR
- return 1
- }
- # array info (size, restrict) is missing from .tu
- # query the pre-processed source file given the linenr
- # assume the whole spec takes just one line
- func derive_typeinfo(n, nr,ns,size,el,spec,narg,arg,i,j,a)
- {
- delete Modi
- if (tag[type[n]] == "integer_type" ||
- tag[type[n]] == "enumeral_type")
- {
- if (qual[type[n]]=="c") Modi["const"]=1
- Size=1
- Type=_type(type[n])
- return
- }
- Type=Size=""
- #pfile=gensub(/\.[ch]/,".E","g",file[n])
- if (DEBUG) print "here:",tag[n],name[n],_type(type[n]),SRC,DIR,file[n],line[n] > STDERR
- if (!SRC) fail("no pre-processed source specified!")
- for (nr=-1; getline < SRC; nr+=(nr>=0))
- {
- if ($0 ~ /^# [0-9]/) {
- if (DEBUG) print nr, DIR, $3 > STDERR
- if ($3 ~ "^\"(\\./)?" (DIR ? DIR "/" : "") file[n] "\"$") {
- nr=$2
- if (DEBUG) print "nr set to",nr > STDERR
- } else
- nr=-1
- }
- if (nr<line[n]) continue
- if (DEBUG) print "found line:",line[n],$0 > STDERR
- if (match($0,/^.*[[:space:]]+([a-z$A-Z_][a-z$A-Z_0-9]*)[[:space:]]*\(([^*].*)\)(.*[^;])$/,el) ||
- match($0,/^[[:space:]]*([a-z$A-Z_][a-z$A-Z_0-9]*)[[:space:]]*\(([^*].*)\)(.*[^;])$/,el) ||
- match($0,/^.*[[:space:]]+([a-z$A-Z_][a-z$A-Z_0-9]*)[[:space:]]*\(([^*].*[^;])$/,el))
- {
- # new style
- if (el[2] ~ /^[a-z$A-Z_][a-z$A-Z_0-9]*$/)
- spec=el[3]
- else
- spec=el[2]
- } else {
- # KR style
- spec=$0
- }
- if (DEBUG) print "spec:",spec,"el","'" el[1] "'","'" el[2] "'","'" el[3] "'" > STDERR
- narg=split(spec,arg,",")
- for (i=1; i<=narg; i++)
- {
- if (DEBUG) print arg[i] > STDERR
- if (!eat(arg[i],name[n])) continue
- if (DEBUG) print "HERE","'" T "'", "'" S1 "'","'" S2 "'" >STDERR
- Type=gensub(/[[:space:]]*$/,"","g",T)
- size=S1 #el[3]
- if (S2) while (match(S2,"^[[:space:]]*\\[([^]]*)\\]",a)) {
- Modi["packetsize"]=append(Modi["packetsize"],a[1],SUBSEP)
- S2=substr(S2,RSTART+RLENGTH)
- }
- if (!size) {
- #warn("\n" file[n] ":" line[n] ": unspecified size - 1 assumed!")
- size="[1]"
- }
- while (match(size,"^[[:space:]]*\\[([^]]*)\\]",el)) {
- Size=append(Size,el[1],SUBSEP)
- size=substr(size,RSTART+RLENGTH)
- }
- if (!Size) fail("could not find any sizes for " name[n] "!")
- for (j=1; j<=2; j++)
- {
- gsub(/^[[:space:]]*/,"",Type)
- if (gsub(/^__inout__/,"",Type))
- Modi["inout"]=1
- if (gsub(/^volatile/,"",Type))
- Modi["volatile"]=1
- if (gsub(/^const/,"",Type) || qual[ptrd[type[n]]]=="c")
- Modi["const"]=1
- }
- for(j=1; j<=4; j++)
- {
- gsub(/^[[:space:]]*/,"",Size)
- if (gsub(/^volatile/,"",Size))
- Modi["volatilep"]=1
- if (gsub(/^const/,"",Size))
- Modi["constp"]=1
- if (gsub(/^static/,"",Size))
- Modi["static"]=1
- if (gsub(/^restrict/,"",Size))
- Modi["restrict"]=1
- }
- break
- }
- if (i<=narg) break
- if (nr-line[n]>1) fail("no typeinfo can be derived for " name[n])
- }
- close(SRC)
- }
- # array info (size, restrict) is missing from .tu
- # query the pre-processed source file given the linenr
- # assume the whole spec takes just one line
- func dump_port_simple(n,sel,stag,sname, ns,size,i) {
- if (!stag) stag="tag"
- printf space(2) "<port id='%s' calltype='%s' %s>\n",name[n],tag[type[n]],
- attwrap("metatag",sname)
- if (sel) printf space(2) "<%s>%s</%s>\n",stag,sel,stag
- derive_typeinfo(n)
- for (i in Modi) printf space(4) "<%s>%s</%s>\n",i,Modi[i],i
- print space(4) "<type>" Type "</type>"
- ns=split(Size,size,SUBSEP)
- #print ns,Size >STDERR
- for (i=1; i<=ns; i++)
- print space(4) "<size>" size[i] "</size>"
- print space(2) "</port>"
- }
- # switch must be in a tail position
- func handle_metamorph(n, e,mod,t,i) {
- for (n=body[n]; n && tag[n] != "switch_stmt"; n=Next[n]) {
- if (tag[n]=="compound_stmt") n=body[n]
- }
- if (!n) fail("misformed metamorph 1")
- t=op[cond[n],0]
- if (tag[t] == "component_ref") t=type[op[t,1]]
- else t=ptrd[type[op[t,0]]]
- #print t,type[t],tag[t] >STDERR
- if (tag[t] != "enumeral_type") fail("misformed metamorph 2.1")
- for(i=csts[t]; i; i=chan[i]) select[low[valu[i]]]=name[purp[i]]
- if (!(n=Next[body[Next[body[body[n]]]]])) fail("misformed metamorph 3")
- do {
- if (tag[n] != "case_label") fail("misformed metamorph 4")
- #print tag[n],low[n],low[low[n]] >STDERR
- mod=low[low[n]]
- if (!(n=Next[n])) fail("misformed metamorph 5")
- if (tag[n] != "return_stmt") fail("misformed metamorph 6")
- #print tag[n],expr[n] >STDERR
- if (!(e=expr[n])) fail("misformed metamorph 6.0")
- if (tag[e] != "modify_expr") fail("misformed metamorph 6.1")
- for (e=op[e,1];tag[e]=="nop_expr";e=op[e,0]);
- if (tag[e]=="integer_cst" && low[e]=="0"); else
- {
- if (tag[e]!="addr_expr") fail("misformed metamorph 6.2:" e "," tag[e])
- if (tag[e=op[e,0]]!="function_decl") fail("misformed metamorph 6.3")
- }
- # TODO For now...
- mode[name[e]]=append(mode[name[e]],select[mod],"|")
- #print name[e],mode[name[e]],mod >STDERR
- if (!(n=Next[n])) fail("misformed metamorph 7")
- } while(tag[n] == "case_label")
- if (tag[n] != "scope_stmt" || modi[n] !~ /end/) fail("misformed metamorph 8")
- }
- func dump_comp(n, comp) {
- if (DEBUG) print file[n],name[n],tag[n],retn[type[n]],args[n] > STDERR
- comp=name[n]
- comps[++ncomps]=comp
- printf "<node id='%s'>\n",comp
- if (Lime["type",line[n]]) print "<type>" Lime["type",line[n]] "</type>"
- node_ret[comp]=name[name[retn[type[n]]]]
- if (!node_ret[comp]) node_ret[comp]=name[retn[type[n]]]
- if (tag[retn[type[n]]]=="record_type")
- node_ret[comp]=append("struct",node_ret[comp])
- print space(2) "<ret>" node_ret[comp] "</ret>"
- if (node_ret[comp] ~ /controller/) handle_metamorph(body[n])
- for (n=args[n]; n; n=chan[n]) {
- if (tag[type[n]]=="pointer_type" ||
- tag[type[n]]=="integer_type" ||
- tag[type[n]]=="enumeral_type")
- {
- dump_port(n)
- continue
- }
- fail("\n" file[n] ":" line[n] ":unsupported parameter type:" tag[type[n]])
- }
- print "</node>"
- }
- func domn2size(t) {
- return _expr(maxi[domn[t]])+1
- }
- func elts2type(t, s) {
- s=_expr(elts[t])
- return substr(s,2,length(s)-2)
- }
- ###################################################################################3
- func __Type(t,des) {
- if (tag[name[t]]=="type_decl") return name[name[t]]
- if (unql[t]) return append(des,name[unql[t]])
- return des
- }
- func _Type(t) {
- m=(modi[t] ? modi[t] " " : "")
- if (tag[t]=="pointer_type") return m _Type(ptrd[t]) "*"
- else if (tag[t]=="reference_type") return m _Type(refd[t]) "&"
- else if (tag[t]=="record_type") return __Type(t,"struct")
- else if (tag[t]=="enumeral_type") return __Type(t,"enum")
- else if (tag[t]=="union_type") return __Type(t,"union")
- else if (tag[t]=="void_type") return m "void"
- else if (tag[t]=="real_type") return m "float"
- else if (tag[t]=="integer_type") return __Type(t,m)
- else if (tag[t]=="array_type")
- return m elts2type(t) "[" domn2size(t) "]"
- else if (tag[t]=="function_type")
- return m _Type(retn[t]) "(*)(" _params(prms[t]) ")"
- else if (VERBOSE) printf "Unknown type: %s %s\n",t,tag[t] >STDERR
- }
- func _name(n,t) {
- t=_Type(n)
- if (t ~ /^struct[[:space:]]*$/) return append(t,name[n])
- if (t ~ /^enum[[:space:]]*$/) return append(t,name[n])
- return name[n]
- }
- func __type(t,des) {
- if (tag[name[t]]=="type_decl") return name[name[t]]
- #if (unql[t]) return append(append(des,name[unql[t]]),name[t])
- if (unql[t])
- if (name[unql[t]] ~ /^[0-9]/)
- return name[name[unql[t]]]
- else
- return append(des,name[unql[t]])
- return append(des,name[t])
- }
- func _type(t) {
- m=(modi[t] ? modi[t] " " : "")
- if (tag[t]=="pointer_type") return m _type(ptrd[t]) "*"
- else if (tag[t]=="reference_type") return m _type(refd[t]) "&"
- else if (tag[t]=="record_type") return __type(t,"struct")
- else if (tag[t]=="enumeral_type") return __type(t,"enum")
- else if (tag[t]=="union_type") return __type(t,"union")
- else if (tag[t]=="void_type") return m "void"
- else if (tag[t]=="real_type") return m "float"
- else if (tag[t]=="integer_type") return __type(t,m)
- else if (tag[t]=="array_type")
- return m elts2type(t) "[" domn2size(t) "]"
- else if (tag[t]=="function_type")
- return m _type(retn[t]) "(*)(" _params(prms[t]) ")"
- else if (VERBOSE) printf "Unknown type: %s %s\n",t,tag[t] >STDERR
- }
- func _return_type(t) {
- if (tag[t]=="function_type")
- return _type(retn[t])
- }
- func _const(c) {
- #t=( type[c] ? "(" _type(type[c]) ")" : "")
- if (tag[c]=="integer_cst") return t low[c]
- else if (tag[c]=="string_cst") return t name[c]
- else if (tag[c]=="real_cst") return t "0"
- else printf "Unknown const: %s %s\n",c,tag[c] >STDERR
- }
- func _decl(t) {
- i=init[t]
- if (i) return (modi[t] ? modi[t] " " : "")\
- sprintf("%s %s = %s",_type(type[t]),
- name[t],
- _expr(i))
- return sprintf("%s %s",_type(type[t]),name[t])
- }
- func _params(t) { r=""
- for (first=1; t; t=chan[t]) {
- r=r sprintf("%s%s %s",
- (first ? "" : ", "),
- _type(type[t]),name[t])
- first=0
- }
- return r
- }
- func _elems(t) { r=""
- for (first=1; t; t=chan[t]) {
- r=r sprintf("%s%s",(first ? "" : ", "),
- _expr(valu[t]))
- first=0
- }
- return r
- }
- func _cons(t) { r=""
- for (first=1; t; t=chan[t]) {
- r=r (first ? "" : ", ")
- if (purp[t]) r=r name[purp[t]] ": "
- r=r _expr(valu[t])
- first=0
- }
- return r
- }
- func escape(s) {
- gsub(/\n/,"\\n",s)
- gsub(/\t/,"\\t",s)
- gsub(/\r/,"\\r",s)
- gsub(/\a/,"\\a",s)
- gsub(/\b/,"\\b",s)
- return s
- }
- func _expr(c) {
- if (!c) return ""
- #t=( type[c] ? "(" _type(type[c]) ")" : "")
- if (DEBUG) print c,tag[c],qual[c] >STDERR
- if (0) {}
-
- else if (tag[c]=="bit_not_expr")
- return sprintf(t "( !%s )",_expr(op[c,0]))
- else if (tag[c]=="negate_expr")
- return sprintf(t "( ~%s )",_expr(op[c,0]))
- else if (tag[c]=="ne_expr")
- return sprintf(t "( %s != %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="eq_expr")
- return sprintf(t "( %s == %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="le_expr")
- return sprintf(t "( %s <= %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="ge_expr")
- return sprintf(t "( %s >= %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="lt_expr")
- return sprintf(t "( %s < %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="gt_expr")
- return sprintf(t "( %s > %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="preincrement_expr")
- return sprintf(t "( +%s = %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="predecrement_expr")
- return sprintf(t "( -%s = %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="postincrement_expr")
- return sprintf(t "( %s += %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="postdecrement_expr")
- return sprintf(t "( %s -= %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="rshift_expr")
- return sprintf(t "( %s >> %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="lshift_expr")
- return sprintf(t "( %s @<< %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="truth_andif_expr")
- return sprintf(t "( %s && %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="truth_orif_expr")
- return sprintf(t "( %s || %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="bit_ior_expr")
- return sprintf(t "( %s | %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="bit_and_expr")
- return sprintf(t "( %s & %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="bit_xor_expr")
- return sprintf(t "( %s ^ %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="mult_expr")
- return sprintf(t "( %s * %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="plus_expr")
- return sprintf(t "( %s + %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="minus_expr")
- return sprintf(t "( %s - %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="trunc_div_expr")
- return sprintf(t "( %s / %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="exact_div_expr")
- return sprintf(t "( %s / %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="trunc_mod_expr")
- return sprintf(t "( %s %% %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="compound_expr")
- return sprintf(t "( %s , %s )",_expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="cond_expr")
- return sprintf(t "( %s ? %s : %s )",
- _expr(op[c,0]),
- _expr(op[c,1]),_expr(op[c,2]))
- else if (tag[c]=="min_expr")
- return sprintf(t "( %s < %s ? %s : %s )",
- _expr(op[c,0]),_expr(op[c,1]),
- _expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="max_expr")
- return sprintf(t "( %s > %s ? %s : %s )",
- _expr(op[c,0]),_expr(op[c,1]),
- _expr(op[c,0]),_expr(op[c,1]))
- else if (tag[c]=="modify_expr") {
- if (tag[op[c,0]]=="result_decl")
- return sprintf(t "( %s )",_expr(op[c,1]))
- else
- return sprintf(t "%s = %s",_expr(op[c,0]),
- _expr(op[c,1]))
- }
- else if (tag[c]=="addr_expr") {
- if (DEBUG) print "!!",c,tag[c],tag[op[c,0]] > STDERR
- if (tag[op[c,0]]=="function_decl")
- return sprintf("%s",name[op[c,0]])
- else if (tag[op[c,0]]=="string_cst")
- return sprintf("\"%s\"",escape(name[op[c,0]]))
- else
- return sprintf("&%s",name[op[c,0]])
- }
- else if (tag[c]=="call_expr") return sprintf(t "%s ( %s )",
- _expr(Func[c]),_elems(args[c]))
- else if (tag[c]=="float_expr")
- return sprintf(t "( %s )",_expr(op[c,0]))
- else if (tag[c]=="convert_expr")
- return sprintf(t "%s",_expr(op[c,0]))
- else if (tag[c]=="nop_expr")
- return sprintf(t "( %s )",_expr(op[c,0]))
- else if (tag[c]=="expr_stmt") return t _expr(expr[c])
- else if (tag[c]=="expr_with_file_location")
- return t _expr(op[c,0])
- else if (tag[c]=="save_expr") return t _expr(op[c,0])
- else if (tag[c]=="non_lvalue_expr") return t _expr(expr[c])
- else if (tag[c]=="integer_type") return "("\
- (qual[c]=="c" ? "const ": "")\
- name[c] ")"
- else if (tag[c]=="compound_literal_expr") return t
- else if (tag[c]=="constructor") {
- level++
- bb=_cons(elts[c])
- level--
- return "{" bb "}"
- }
- else if (tag[c]=="stmt_expr") {
- level++
- bb=esrap(stmt[c])
- level--
- return t bb
- }
- else if (tag[c]=="array_ref")
- return _expr(op[c,0]) "[" _expr(op[c,1]) "]"
- else if (tag[c]=="indirect_ref") return name[op[c,0]]
- else if (tag[c]=="component_ref") return _expr(op[c,0])\
- (tag[op[c,0]]=="indirect_ref" ? "->" : ".")\
- _expr(op[c,1])
- else if (tag[c] ~ /_decl/) return name[c]
- else if (tag[c] ~ /_cst/) return _const(c)
- else if (tag[c]=="bit_field_ref") return "/*bit_field_ref*/"
- else if (tag[c]=="array_type") return "TODO"
- else if (tag[c]=="record_type") return "TODO"
- else if (tag[c]=="error_mark") return "ERROR"
- else printf "Unknown expr: %s %s %s\n",c,tag[c],name[c] >STDERR
- }
- func esrap(b, i,n) {
- o=""
- # for (; b; b=Next[b])
- # {
- if (DEBUG) print "!!",b,tag[b] > STDERR
- if (LINE_NO && tag[b] != "compound_stmt" &&\
- (line[b] || file[b]))
- o=o put(sprintf("#line %d \"%s\"",
- line[b],file[b]))
- if (0) {}
- else if (tag[b]=="function_decl") {
- o=o put(sprintf("%s %s %s(%s)",
- modi[b],
- _return_type(type[b]),
- name[b],
- _params(args[b])))
- o=o esrap(body[b])
- }
- else if (tag[b]=="statement_list") {
- if (DEBUG) print "!!",stmts[b] > STDERR
- n=split(stmts[b],el," ")
- for (i=1; i<=n; i++) o=o esrap(el[i])
- }
- else if (tag[b]=="label_stmt")
- o=o put(sprintf("%s:",name[labl[b]]),-1)
- else if (tag[b]=="goto_stmt")
- o=o put(sprintf("goto %s;",name[dest[b]]))
- else if (tag[b]=="asm_stmt")
- o=o put(sprintf("__asm__ %s (%s)\n",
- name[strg[b]],_cons(ins[b])))
- else if (tag[b]=="compound_stmt") {
- #o=o put(sprintf("/* compound till %d */", line[b]))
- if (body[b]) o=o esrap(body[b])
- else o=o put(";")
- }
- else if (tag[b]=="scope_stmt") {
- if(modi[b] ~ /begn/) {
- o=o put("{")
- level++
- } else {
- level--
- o=o put("}")
- }
- }
- else if (tag[b]=="decl_stmt") {
- o=o put(sprintf("%s;",_decl(decl[b])))
- }
- else if (tag[b]=="if_stmt") {
- o=o put(sprintf("if %s",_expr(cond[b])))
- level++
- o=o esrap(then[b])
- level--
- if (Else[b]) {
- o=o put("else")
- level++
- o=o esrap(Else[b])
- level--
- }
- }
- else if (tag[b]=="expr_stmt") {
- o=o put(sprintf("%s;",_expr(expr[b])))
- }
- else if (tag[b]=="return_stmt") {
- o=o put(sprintf("return %s;",_expr(expr[b])))
- }
- else if (tag[b]=="for_stmt") {
- o=o put(sprintf("for (%s; %s; %s)",
- _expr(init[b]),
- _expr(cond[b]),
- _expr(expr[b])))
- level++
- if (body[b]) o=o esrap(body[b])
- else o=o put(";")
- level--
- }
- else if (tag[b]=="switch_stmt") {
- o=o put(sprintf("switch (%s)",_expr(cond[b])))
- level++
- if (body[b]) o=o esrap(body[b])
- else o=o put(";")
- level--
- }
- else if (tag[b]=="case_label") {
- if (low[b]) o=o put(sprintf("case %s:",
- _const(substr(low[b],2))),
- -1)
- else o=o put("default:",-1)
- }
- else if (tag[b]=="do_stmt") {
- o=o put("do")
- level++
- if (body[b]) o=o esrap(body[b])
- else o=o put(";")
- level--
- o=o put(sprintf("while (%s);",_expr(cond[b])))
- }
- else if (tag[b]=="while_stmt") {
- o=o put(sprintf("while (%s)",_expr(cond[b])))
- level++
- if (body[b]) o=o esrap(body[b])
- else o=o put(";")
- level--
- }
- else if (tag[b]=="continue_stmt")
- o=o put("continue;")
- else if (tag[b]=="break_stmt")
- o=o put("break;")
- else if (tag[b]=="namespace_decl") {
- o=o put(sprintf("namespace %s {",name[b]))
- level++
- if (dcls[b]) o=o esrap(dcls[b])
- o=o put("}")
- level--
- }
- else
- printf "Unexpected tag: %s %s\n",b,tag[b] >STDERR
-
- # }
- level-=inc
- return o
- }
- func quote(s) { return gensub(/"/,"\\\\\"","g",s) }
- func pexpr(e) { return quote(_expr(e)) }
- func put(x,incr) {
- y=""
- for (i=0; i<level+incr; i++) y=y "\t"
- y=y x "\n"
- return y
- }
- func Flatten(a,sep,len, i, ret) {
- for (i in a) ret=append(ret,i SUBSEP a[i],sep)
- return ret
- }
- func flatten(a,sep,len, ret) {
- if (!len) for(i in a) len++
- for (i=0; i<len; i++) ret=append(ret,a[i],sep)
- return ret
- }
- func flatten1(a,sep,len, ret) {
- if (!len) for(i in a) len++
- for (i=1; i<=len; i++) ret=append(ret,a[i],sep)
- return ret
- }
- @include pragmas.awk
- @include common.awk