# HG changeset patch # User Nobuyasu Oshiro # Date 1313880792 -32400 # Node ID 1b10fe6932e12b81b043d3a0910c3502bc367b5c # Parent b362627d71bab4e085fb880543ac43dcb35c5c24# Parent 561a7518be6b6c702d1196c9914ccdeb354c4f16 merge 69 diff -r 561a7518be6b -r 1b10fe6932e1 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,10 @@ +syntax: glob + +*.o +*.s +.*.swp +.*.swo +GTAGS +GRTAGS +GSYMS +GPATH diff -r 561a7518be6b -r 1b10fe6932e1 .hgtags --- a/.hgtags Sun Aug 21 07:07:55 2011 +0900 +++ b/.hgtags Sun Aug 21 07:53:12 2011 +0900 @@ -1,5 +1,2 @@ -a06113de4d676b497759e6a9bf820a208b02e09b gcc-4.4.0 -855418dad1a3a87de4782b8184eef35cd8812e23 gcc-4.4.2 -ae3a4bfb450bd98011c4167c72bb1d5ad73cdd51 gcc-4.4.3 77e2b8dfacca7d714bc9daeb6169b88f9d7c35eb gcc-4.4.5 b7f97abdc51746370aa15065311ea13e56c08d1f gcc-4.6-20100522 diff -r 561a7518be6b -r 1b10fe6932e1 .hgtags.orig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgtags.orig Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,1 @@ +77e2b8dfacca7d714bc9daeb6169b88f9d7c35eb gcc-4.4.5 diff -r 561a7518be6b -r 1b10fe6932e1 CbC-DEVEL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-DEVEL Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,25 @@ +GCC 4.4.3 -> 4.5.0 へのアップデートの作業メモ + +オリジナルのgcc-core 4.5.0と mergeして、衝突は全て解決 + +make時にエラー,未解決 -> (CbC-MAKELOG にログがのってます) +関数/マクロの引数構成に変更 +) build_decl,c_finish_stmt_expr,, -> locationの追加 +) buid_modify_expr, build_external_ref -> 色々変更 + +# GCCのソース中の用法を見る。コメントを読む。 +# locationに関しては間違っても動く。 + +全てc-parser.c のcbc拡張の古い部分の変更 + +-- + +cbc-goto.hでエラー(消された関数を使用) -> targetm.calls.promote_funciton_return(funtype) + + gcc/ChangeLog より -- + (expand_call): When making sibcall decisions, use promote_function_mode. + Below, remove an if for targetm.calls.promote_function_return and + and use promote_function_mode. + -- + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-INSTALL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-INSTALL Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,220 @@ + + * CbC on GCCのインストール方法 + +まずはMercurialリポジトリから取得 + hg clone ssh://one@firefly.cr/hg/CbC/GCC cbc-gcc +ビルド用ディレクトリへ + mkdir build-gcc; cd build-gcc +コンフィギュア +一般的には以下のconfigureでビルドできる + ../cbc-gcc/configure CFLAGS="-g3 -O0" + --prefix=$PWD/INSTALL_DIR --disable-nls \ + --disable-bootstrap --enable-languages=c \ + --enable-checking=tree,rtl,assert,types + + -g3: + gdbでmacroの展開を可能にする + -O0: + gdbでトレースしやすいように、最適化をカット + --prefix: + インストールするベースディレクトリ + --enbale-checking: + デバグ用の指定、browse_treeやdebug_rtx、assertもこれでonになる + --disable-bootstrap: + 通常、GCCは3回ビルドされる。それを最初の1回だけに限定 + --disable-nls: + gettextのl10nをoffにしよう + --enable-language: + 使用する言語 c|c++|ada ... もちろんCbCはcだけ + これもcbcを使えるようにしたい +ビルド +make && make install + + + + * PowerPC Macでのインストール + +最新のlibgmp, libmpfrをインストール +[gmp] + ./configure --enable-cxx --build=powerpc-apple-darwin9 --host=powerpc-apple-darwin9 + make && make install +[mpfr] + ./configure --build=powerpc-apple-darwin9 --host=powerpc-apple-darwin9 + make && make install +[CbC on GCC] + ../cbc-gcc/configure CFLAGS="-g3 -O0" --with-gmp=/usr/local + --with-mpfr=/usr/local --prefix=$PWD/INSTALL_DIR \ + --disable-nls --disable-bootstrap --enable-languages=c \ + --enable-checking=tree,rtl,assert,types + make && make install +もちろんインストール場所によってprefixは変更しよう + + + + + * PS3でのビルド + SPU + $ ../GCC/configure CFLAGS='-g -O0' --prefix=$PWD/INSTALL_DIR + --disable-nls --disable-shared --disable-threads + --enable-checking=tree,rtl,assert --with-system-zlib + --with-newlib --enable-languages=c + --enable-version-specific-runtime-libs --disable-libssp + --program-prefix=cbc-spu- --target=spu --disable-bootstrap + $ make && make install + $ cd INSTALL_DIR; ln -s /usr/spu; cd .. + で、動作確認のあと + $ sudo make prefix=/usr/local/cbc install + $ cd /usr/local/cbc; ln -s /usr/spu; cd - + + PPU + $ ../GCC/configure --prefix=$PWD/INSTALL_DIR + --host=ppc64-redhat-linux --build=ppc64-redhat-linux + --target=ppc64-redhat-linux --program-prefix=cbc- --disable-bootstrap + --enable-checking=tree,rtl,assert --disable-nls --enable-shared + --enable-thread=posix --enable-languages=c --with-system-zlib + --enable-__cxa_atexit --disable-libunwind-exceptions --disable-dssi + --enable-plugin --with-long-double-128 --with-gnu-as + --with-as=/usr/bin/as --with-gnu-ld --with-ld=/usr/bin/ld + --with-cpu=default32 + $ make && make install + 動作確認 + $ make prefix=/usr/local/cbc install + + + + * 琉球大学総合情報センターのSolarisサーバでのビルド (sparc) + +なぜかデフォルトのgccが自分のライブラリすら見てくれないのでパスを指定 + export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib/gcc:$HOME/opt/lib + export LIBRARY_PATH=/usr/local/lib:/usr/local/lib/gcc:$HOME/opt/lib +gmpのインストール + ./configure --prefix=$HOME/opt \ + --build=sparc-sun-solaris \ + --host=sparc-sun-solaris + make + make check + make install +libmpfrのインストール + ./configure --prefix=$HOME/opt/ \ + --with-gmp=$HOME/opt + --build=sparc-sun-solaris \ + --host=sparc-sun-solaris + make + make check + make install + # sparc-sun-solaris2.10の方がいいかもしれない +CbCをインストール + ../CbCGCC/configure --prefix=$PWD/INSTALL_DIR --disable-nls \ + --disable-bootstrap --enable-languages=c \ + --with-gmp=$HOME/opt --with-mpfr=$HOME/opt \ + --build=sparc-sun-solaris2.10 --target=sparc-sun-solaris2.10 \ + --host=sparc-sun-solaris2.10 --enable-shared \ + --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld + make + make install +ビルドは可能。 +ただし、実行は不能 goto cs();すら動かない +config/sparc/sparc.cのoutput_sibcall()でエラーが出る +gdbがインストールされてないので詳細は未調査 +もしかしてsibcallってあまり実装されてないんじゃ… + + + +___________________________________________________________ + PS3用のクロスコンパイラの作成 +----------------------------------------------------------- + +PS3でのGCCのビルドはメモリが少なすぎるためか、insn-*.cのコンパイルに膨 +大な時間がかかってしまう。 +なので別のマシンからPS3をターゲットとしたクロスコンパイラを作成する。 +ただしこれはCbConGCCの開発のためと考えた方が良い。実際にCbC言語を使っ +たプログラムをPS3で開発する際はちゃんとPS3上にノンクロスコンパイラを作 +成しよう。時間はかかるがビルドは可能。 + + * 必要なもの + o binutilsのソース + o gccのソース + o ターゲットマシンのlib*.{a,so}類 + o ターゲットマシンの.hファイル + ~/PS3CROSSにクロスコンパイラ環境を整えるとする + ~/PS3CROSS/cross-tools: クロスコンパイルに使うツールのインストール先 + ~/PS3CROSS/sources: ソース置き場、出来上がったら消してもいいよ + ~/PS3CROSS/target-env: ターゲット環境(libやinclude)が入ったディレクトリ + + * 準備 + $ CROSS=$HOME/PS3CROSS + $ cd $CROSS + $ mkdir sources cross-tools target-env + $ cd sources + $ wget ... binutilsとかgccのソースをダウンロード + + * binutilsのビルド + $ tar xvf binutils..tar.gz + $ mkdir PS3-binutils-build; cd !#1 + $ ../binutils-.../configure --prefix=$CROSS/cross-tools \ + --with-lib-path=$CROSS/target-env \ + --hosti686-pc-linux-gnu --build=i686-pc-linux-gnu \ + --target=ppc64-redhat-linux --enable-64-bit-bfd \ + --disable-nls --enable-shared --with-sysroot + $ make && make install + + * ターゲットマシンの環境をコピーする + $ cd $CROSS/target-env + $ mkdir include lib lib64 + $ ln -s . usr + ## 必要なライブラリはすべてコピー + $ cd lib + $ rsync -avl 'charles.cr:/lib/libc[.-_]*' ./ + $ rsync -avl 'charles.cr:/usr/lib/libc[.-_]*' ./ + $ rsync -avl 'charles.cr:/usr/lib/crt*' ./ + $ rsync -avl 'charles.cr:/lib/ld*' ./ + $ cd ../lib64 + $ ..... + ## ヘッダは軽いので全部コピー + $ cd ../include + $ rsync -avl 'charles.cr:/usr/include/*' ./ + + * GCCのビルド + $ cd $CROSS/sources + $ mkdir PS3-gcc-build; cd !#1 + $ ../.../configure --prefix=$CROSS/cross-tools + --host=i686-pc-linux-gnu --target=ppc64-redhat-linux + --with-sysroot=$CROSS/target-env --disable-nls + --disable-shared --disable-threads + --enable-languages=c --without-headers + --disable-bootstrap + $ make all-gcc + $ make ## エラーで終わるけど気にするな + $ make install-gcc + $ make install-target-libgcc + + * テスト + $ cat >test.c < + int + main(int argc, char **argv) + { + int a=0; + int i; + for (i=0; i<10; i++) { + a = i; + } + printf("hello world\n"); + printf("a = %d\n", a); + return a; + } + EOF + $ $CROSS/cross-tools/bin/gcc -m32 test.c -o test32 + $ $CROSS/cross-tools/bin/gcc -m64 test.c -o test64 + $ file test32 test64 + test32: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped + test64: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped + $ scp test{32,64} PS3Machine: + PS3Machine $ ./test32 + + + + + + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-REPOSITORY --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-REPOSITORY Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,57 @@ + + * CbC/GCCのリポジトリ管理方法 + +Continuation based C のGCC実装用には二つのリポジトリを仕様する + + o CbC/GCC + 実際にCbCを実装したGCCの本体 + o CbC/GCC_original + オリジナルのGCC。本家のgcc-core-4.x.yをそのままリポジトリ化。 + +GCC_origのほうはGCCがリリースされる度にバージョンアップさせ、コミットする。 +さらにその変更をCbC用のGCCリポジトリにpushする + + 本家 + release GCC_orig GCC + | | | + | 4.4.0 4.4.0-cbc + 4.4.1 up | | + | --> 4.4.1 push | + | | --> 4.4.1-cbc + | | | + 4.4.2 up | | + | --> 4.4.2 push | + | | --> 4.4.2-cbc + | | | + + + * 本家GCCのニューリリース時の対応 + +GCC_originalをアップデート + $ cd $HOME + $ wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.4.1/gcc-core-4.x.y.tar.gz + $ tar xvf gcc-core-4.x.y.tar.gz + $ cd gcc-4.x.y + $ cd ${HG_REPO}/CbC/GCC_original + $ rm -rf * + $ mv ${HOME}/gcc-4.4.1/* ./ + $ hg commit + +GCC_originalが最新のGCCになったら、その変更をGCCにpushする +GCC_originalからGCCへのpush + $ cd ${HOME} + $ mkdir workspace;cd workspace # 作業ディレクトリ作成 + $ hg clone ${HG}/one/CbC/GCC # CbC用のGCCをクローン + $ cd GCC + $ hg incoming ${HG}/one/CbC/GCC_original # チェック + $ hg pull ${HG}/one/CbC/GCC_original # pull + +この時点で、場合によっては衝突が起こる。ほとんどはgcc/calls.cの中だと +思われる。また、expand_call関数が大幅に変更されたならgcc/cbc-goto.hも +同じように書き換える必要があるかもしれない。 +がんばって動くまで修正したら + $ hg commit + $ hg push ${HG}/one/CbC/GCC # push +これで最新版に更新される + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/.gdb_history --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/.gdb_history Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,256 @@ +p debug_rtx(funexp) +run -O2 test_para2.c +p browse_tree (exp) +c +p browse_tree (exp) +n +p debug_rtx(funexp) +n +p debug_rtx(funexp) +n +p debug_rtx(get_last_insn()) +c +run -O2 test_csp1.c +p browse_tree (exp) +n +p debug_rtx(get_last_insn()) +c +b recog.c:2077 +run +c +p insn +p debug_rtx(insn) +backtrace +l +info b +del 2 +b recog.c:2078 +run +del 3 +b recog.c:2076 +c +l +p icode +c +p icode +c +c +p icode +n +c +n +c +c +c +c +run +c +p icode +backtrace +run +backtrace +info b +del 4 +b recog.c:2077 +run +backtrace +info b +disable 1 +info b +c +backtrace +quit +b expand_call +run -O2 test_para2.c +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +n +p browse_tree (fntype) +quit +b expand_call +run -O2 test04.c +p browse_tree (exp) +c +p browse_tree (exp) +n +p browse_tree (fntype ) +p browse_tree (fntype->type.values ) +p browse_tree (fntype->type.values->value ) +p browse_tree (fntype->type.values->type.value ) +p browse_tree (fntype->type.values->type.values ) +p browse_tree (fntype->type.values ) +p browse_tree (fntype->type.values->list.vlaue ) +p browse_tree (fntype->type.values->list.value ) +p browse_tree (fntype->type.values->common.chain ) +p browse_tree (fntype->type.value ) +p browse_tree (fntype->type.values ) +p browse_tree (fntype ) +l +p browse_tree (exp) +q +quit +b expand_call +run -O2 test04.c +p browse_tree (exp) +c +p browse_tree (exp) +p browse_tree (exp) +p browse_tree (exp) +p browse_tree (exp->exp.operands[1])) +p browse_tree (exp->exp.operands[1]) +p browse_tree (exp) +quit +b expand_call +run -O2 test_tailcall1.c +l +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +n +p browse_tree (fndecl) +p fndecl +n +p browse_tree (fntype) +n +p pass +p try_tail_call +run +c +c +p browse_tree (exp) +p try_tail_call +l +info stack +n +p try_tail_call +n +p try_tail_call +n +p try_tail_call +n +p try_tail_call +n +l +l - +l - +p try_tail_call +n +n +p browse_tree (exp) +n +n +n +n +p pass +p try_tail_call +quit +b expand_call +run -O2 test_tailcall1.c +cc +c +c +p browse_tree (exp) +n +p try_tail_call +n +p tree +p p +n +p p +p addr +n +p addr +n +p fndecl +n +p fndecl +n +p fntype +n +n +p funtype +n +p funtype +n +p try_tail_call +n +p try_tail_call +quit +b expand_call +run -O2 test_tailcall1.c +c +c +p browse_tree (exp) +n +p try_tail_call +n +p try_tail_call +n +n +p try_tail_call +n +p pass +quit +b expand_call +run -O2 test_tailcall1.c +p browse_tree (exp) +c +c +p browse_tree (exp) +n +p try_tail_call +n +p try_tail_call +p fndecl +p targetm.function_ok_for_sibcall(fndecl,exp) +run +c +c +n +p browse_tree (exp) +n +s +l +p decl +p exp +p browse_tree(exp) +n +s +s +quit +run -O2 test03.c +b expand_call +run +n +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +c +quit +b expand_call +run -O2 test_para2.c +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +c +p browse_tree (exp) +n +s +n +p debug_rtx(get_last_insn()) +quit diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/bug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/bug.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,19 @@ +typedef void (*atexit_callback)(void); +typedef void (*cxa_atexit_callback)(void *); +struct one_atexit_routine +{ + int callback; +}; + + +static int +atexit_common (const struct one_atexit_routine *r, const void *dso) + + +{ + return 0; +} + +int main(){ + printf("hello\n"); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/code_segment_pointer_check/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/Makefile Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,25 @@ + +CbCC=../../../build_cbc44/INSTALL_DIR/bin/gcc + +#CC=gcc +CC=../../../build_cbc44/INSTALL_DIR/bin/gcc + + +# fastcall版では-O0,-O2は動作確認、-O3以上はだめ +CFLAGS=-g -O2 -fomit-frame-pointer +#CFLAGS=-g -O0 + +.SUFFIXES: .cbc .o + +all: code_segment_pointer_check2 + +.cbc.o: + $(CbCC) $(CFLAGS) -c -o $@ $< + +code_segment_pointer_check2: code_segment_pointer_check2.o + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -rf *.o *.s code_segment_pointer_check2 + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/code_segment_pointer_check/code_segment_check.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_check.cbc Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,57 @@ +#include +#include +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(1), ## args) + +/* + * コードセグメント間の遷移をテスト + * + */ + +__code end (int a); +__code cs0a (int a, double b, int c, float d, char e); +__code cs1a (char e, int a, double b, int c, float d); +__code cs2a (float d, char e, int a, double b, int c); +__code cs3a (int c, float d, char e, int a, double b); +__code cs4a (double b, int c, float d, char e, int a); +int main (); + +__code end(int a) { + dprint("exit code is %d\n",a); + exit(a); +} + +int i=0; +__code cs0a(int a, double b, int c, float d, char e) { + if ( i++ >= 10 ) { + dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto end((int)(a*b*c*d*e)); + } + goto cs1a(e, a, b, c, d); +} +__code cs1a(char e, int a, double b, int c, float d) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs2a(d, e, a, b, c); +} +__code cs2a(float d, char e, int a, double b, int c) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs3a(c, d, e, a, b); +} +__code cs3a(int c, float d, char e, int a, double b) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs4a(b, c, d, e, a); +} +__code cs4a(double b, int c, float d, char e, int a) { + //dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs0a(a, b, c, d, e); +} + +__code starter(int a, double b, int c, float d, char e) { + dprint("exit code is expected to %d\n",(int)(a*b*c*d*e)); + dprint("int a=%d,double b=%2.3lf,int c=%d,float d=%2.3f,char e=%d\n", a, b, c, d, e); + goto cs0a(a,b,c,d,e); +} +int main() { + goto starter(11, 22.2, 33, 44.44, 55); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/code_segment_pointer_check/code_segment_pointer_check.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_pointer_check.cbc Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,120 @@ +#include +#include +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(0), ## args) + +/* + * コードセグメント間の遷移で + * + * + * + */ + +__code schedule (); +__code cs0a (); +__code cs1a (int a); +__code cs2a (int a, double b); +__code cs3a (int a, double b, int c); +__code cs4a (int a, double b, int c, float d); +__code cs0b (); +__code cs1b (int a); +__code cs2b (int a, double b); +__code cs3b (int a, double b, int c); +__code cs4b (int a, double b, int c, float d); + +/* defined in file code_segment_pointer_check.cbc at offset 1649 */ +int main (); + +__code end(int a) { + dprint("exit with code %d\n",a); + exit(a); +} + +__code (*cs0) (); +__code (*cs1) (int); +__code (*cs2) (int, double); +__code (*cs3) (int, double, int); +__code (*cs4) (int, double, int, float); +int i=0; +__code schedule() { + dprint("i=%d\n",i); + if ( i>=100 ) { + goto end(0); + } + switch (i++%5) { + case 0: + goto cs0(); + case 1: + goto cs1(i); + case 2: + goto cs2(i, i*1.3); + case 3: + goto cs3(i, i*1.3, 20*i); + case 4: + goto cs4(i, i*1.3, 20*i, i*0.8); + default: + exit(0); + } + dprint("code unreachable!\n"); +} + +__code cs0a() { + dprint("no args\n"); + cs0 = cs0b; + goto schedule(); +} +__code cs1a(int a) { + dprint("int a=%d\n", a); + cs1 = cs1b; + goto schedule(); +} +__code cs2a(int a, double b) { + dprint("int a=%d, double b=%lf\n", a, b); + cs2 = cs2b; + goto schedule(); +} +__code cs3a(int a, double b, int c) { + dprint("int a=%d, double b=%lf, int c=%d\n", a, b, c); + cs3 = cs3b; + goto schedule(); +} +__code cs4a(int a, double b, int c, float d) { + dprint("int a=%d, double b=%lf, int c=%d, float d=%f\n", a, b, c, d); + cs4 = cs4b; + goto schedule(); +} + +__code cs0b() { + dprint("no args\n"); + cs0 = cs0a; + goto schedule(); +} +__code cs1b(int a) { + dprint("int a=%d\n", a); + cs1 = cs1a; + goto schedule(); +} +__code cs2b(int a, double b) { + dprint("int a=%d, double b=%lf\n", a, b); + cs2 = cs2a; + goto schedule(); +} +__code cs3b(int a, double b, int c) { + dprint("int a=%d, double b=%lf, int c=%d\n", a, b, c); + cs3 = cs3a; + goto schedule(); +} +__code cs4b(int a, double b, int c, float d) { + dprint("int a=%d, double b=%lf, int c=%d, float d=%f\n", a, b, c, d); + cs4 = cs4a; + goto schedule(); +} + +int main() { + cs0 = cs0a; + cs1 = cs1a; + cs2 = cs2a; + cs3 = cs3a; + cs4 = cs4a; + goto schedule(); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.cbc Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,655 @@ +#include +#include +#include"code_segment_pointer_check2.h" +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(0), ## args) + +/* + * コードセグメント間の遷移をチェック + * + */ + +typedef __code (*CODEP)(int,int,int,int,int,int); +extern CODEP csps[]; +CODEP csps[] = { + //cs0,cs1 + cs0,cs1,cs2,cs3,cs4,cs5,cs6,cs7,cs8,cs9, + cs10,cs11,cs12,cs13,cs14,cs15,cs16,cs17,cs18,cs19, + cs20,cs21,cs22,cs23,cs24,cs25,cs26,cs27,cs28,cs29, + cs30,cs31,cs32,cs33,cs34,cs35,cs36,cs37,cs38,cs39, + cs40,cs41,cs42,cs43,cs44,cs45,cs46,cs47,cs48,cs49, + cs50,cs51,cs52,cs53,cs54,cs55,cs56,cs57,cs58,cs59, + cs60,cs61,cs62,cs63,cs64,cs65,cs66,cs67,cs68,cs69, + cs70,cs71,cs72,cs73,cs74,cs75,cs76,cs77,cs78,cs79, + cs80,cs81,cs82,cs83,cs84,cs85,cs86,cs87,cs88,cs89, + cs90,cs91,cs92,cs93,cs94,cs95,cs96,cs97,cs98,cs99, + cs100,cs101,cs102,cs103,cs104,cs105,cs106,cs107,cs108,cs109, + cs110,cs111,cs112,cs113,cs114,cs115,cs116,cs117,cs118,cs119 +}; + +__code end(int a, int b, int c, int d, int e) { + dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + exit(a); +} + +__code schedule(int i, int a, int b, int c, int d, int e) { + //CODEP p; + //p = csps[i%120]; + + if ( i>=1000 ) { + goto end(a, b, c, d, e); + } + + dprint("i=%d\n", i); + goto csps[i%120](i+1, a, b, c, d, e); + + dprint("code unreachable!\n"); +} + +int main() { + goto schedule(0, 11,22,33,44,55); +} + + + +/* created by script make_permutations.py. */ + +__code cs0(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,c,d,e); +} + +__code cs1(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,c,d,e); +} + +__code cs2(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,a,d,e); +} + +__code cs3(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,d,a,e); +} + +__code cs4(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,d,e,a); +} + +__code cs5(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,b,d,e); +} + +__code cs6(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,b,d,e); +} + +__code cs7(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,a,d,e); +} + +__code cs8(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,d,a,e); +} + +__code cs9(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,d,e,a); +} + +__code cs10(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,d,b,e); +} + +__code cs11(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,d,b,e); +} + +__code cs12(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,a,b,e); +} + +__code cs13(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,b,a,e); +} + +__code cs14(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,b,e,a); +} + +__code cs15(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,d,e,b); +} + +__code cs16(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,d,e,b); +} + +__code cs17(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,a,e,b); +} + +__code cs18(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,e,a,b); +} + +__code cs19(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,d,e,b,a); +} + +__code cs20(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,d,c,e); +} + +__code cs21(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,d,c,e); +} + +__code cs22(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,a,c,e); +} + +__code cs23(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,c,a,e); +} + +__code cs24(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,c,e,a); +} + +__code cs25(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,b,c,e); +} + +__code cs26(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,b,c,e); +} + +__code cs27(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,a,c,e); +} + +__code cs28(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,c,a,e); +} + +__code cs29(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,c,e,a); +} + +__code cs30(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,c,b,e); +} + +__code cs31(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,c,b,e); +} + +__code cs32(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,a,b,e); +} + +__code cs33(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,b,a,e); +} + +__code cs34(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,b,e,a); +} + +__code cs35(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,c,e,b); +} + +__code cs36(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,c,e,b); +} + +__code cs37(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,a,e,b); +} + +__code cs38(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,e,a,b); +} + +__code cs39(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,c,e,b,a); +} + +__code cs40(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,d,e,c); +} + +__code cs41(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,d,e,c); +} + +__code cs42(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,a,e,c); +} + +__code cs43(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,e,a,c); +} + +__code cs44(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,d,e,c,a); +} + +__code cs45(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,b,e,c); +} + +__code cs46(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,b,e,c); +} + +__code cs47(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,a,e,c); +} + +__code cs48(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,e,a,c); +} + +__code cs49(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,b,e,c,a); +} + +__code cs50(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,e,b,c); +} + +__code cs51(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,e,b,c); +} + +__code cs52(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,a,b,c); +} + +__code cs53(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,b,a,c); +} + +__code cs54(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,b,c,a); +} + +__code cs55(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,d,e,c,b); +} + +__code cs56(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,a,e,c,b); +} + +__code cs57(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,a,c,b); +} + +__code cs58(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,c,a,b); +} + +__code cs59(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, d,e,c,b,a); +} + +__code cs60(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,c,e,d); +} + +__code cs61(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,c,e,d); +} + +__code cs62(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,a,e,d); +} + +__code cs63(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,e,a,d); +} + +__code cs64(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,c,e,d,a); +} + +__code cs65(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,b,e,d); +} + +__code cs66(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,b,e,d); +} + +__code cs67(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,a,e,d); +} + +__code cs68(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,e,a,d); +} + +__code cs69(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,b,e,d,a); +} + +__code cs70(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,e,b,d); +} + +__code cs71(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,e,b,d); +} + +__code cs72(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,a,b,d); +} + +__code cs73(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,b,a,d); +} + +__code cs74(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,b,d,a); +} + +__code cs75(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,c,e,d,b); +} + +__code cs76(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,a,e,d,b); +} + +__code cs77(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,a,d,b); +} + +__code cs78(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,d,a,b); +} + +__code cs79(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, c,e,d,b,a); +} + +__code cs80(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,e,c,d); +} + +__code cs81(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,e,c,d); +} + +__code cs82(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,a,c,d); +} + +__code cs83(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,c,a,d); +} + +__code cs84(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,c,d,a); +} + +__code cs85(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,b,c,d); +} + +__code cs86(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,b,c,d); +} + +__code cs87(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,a,c,d); +} + +__code cs88(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,c,a,d); +} + +__code cs89(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,c,d,a); +} + +__code cs90(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,c,b,d); +} + +__code cs91(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,c,b,d); +} + +__code cs92(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,a,b,d); +} + +__code cs93(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,b,a,d); +} + +__code cs94(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,b,d,a); +} + +__code cs95(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,c,d,b); +} + +__code cs96(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,c,d,b); +} + +__code cs97(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,a,d,b); +} + +__code cs98(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,d,a,b); +} + +__code cs99(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,c,d,b,a); +} + +__code cs100(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,b,e,d,c); +} + +__code cs101(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,a,e,d,c); +} + +__code cs102(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,a,d,c); +} + +__code cs103(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,d,a,c); +} + +__code cs104(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, b,e,d,c,a); +} + +__code cs105(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,b,d,c); +} + +__code cs106(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,b,d,c); +} + +__code cs107(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,a,d,c); +} + +__code cs108(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,d,a,c); +} + +__code cs109(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,b,d,c,a); +} + +__code cs110(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,d,b,c); +} + +__code cs111(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,d,b,c); +} + +__code cs112(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,a,b,c); +} + +__code cs113(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,b,a,c); +} + +__code cs114(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,b,c,a); +} + +__code cs115(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, a,e,d,c,b); +} + +__code cs116(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,a,d,c,b); +} + +__code cs117(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,a,c,b); +} + +__code cs118(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,c,a,b); +} + +__code cs119(int i, int a, int b, int c, int d, int e) { + //dprint("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e); + goto schedule(i, e,d,c,b,a); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/code_segment_pointer_check/code_segment_pointer_check2.h Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,369 @@ +/* defined in file code_segment_pointer_check2.cbc at offset 987 */ +__code end (int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1102 */ +__code schedule (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1345 */ +int main (); + +/* defined in file code_segment_pointer_check2.cbc at offset 1398 */ +__code cs0 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1542 */ +__code cs1 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1686 */ +__code cs2 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1830 */ +__code cs3 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 1974 */ +__code cs4 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2118 */ +__code cs5 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2262 */ +__code cs6 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2406 */ +__code cs7 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2550 */ +__code cs8 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2694 */ +__code cs9 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2838 */ +__code cs10 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 2983 */ +__code cs11 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3128 */ +__code cs12 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3273 */ +__code cs13 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3418 */ +__code cs14 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3563 */ +__code cs15 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3708 */ +__code cs16 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3853 */ +__code cs17 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 3998 */ +__code cs18 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4143 */ +__code cs19 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4288 */ +__code cs20 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4433 */ +__code cs21 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4578 */ +__code cs22 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4723 */ +__code cs23 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 4868 */ +__code cs24 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5013 */ +__code cs25 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5158 */ +__code cs26 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5303 */ +__code cs27 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5448 */ +__code cs28 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5593 */ +__code cs29 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5738 */ +__code cs30 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 5883 */ +__code cs31 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6028 */ +__code cs32 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6173 */ +__code cs33 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6318 */ +__code cs34 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6463 */ +__code cs35 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6608 */ +__code cs36 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6753 */ +__code cs37 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 6898 */ +__code cs38 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7043 */ +__code cs39 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7188 */ +__code cs40 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7333 */ +__code cs41 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7478 */ +__code cs42 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7623 */ +__code cs43 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7768 */ +__code cs44 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 7913 */ +__code cs45 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8058 */ +__code cs46 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8203 */ +__code cs47 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8348 */ +__code cs48 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8493 */ +__code cs49 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8638 */ +__code cs50 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8783 */ +__code cs51 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 8928 */ +__code cs52 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9073 */ +__code cs53 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9218 */ +__code cs54 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9363 */ +__code cs55 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9508 */ +__code cs56 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9653 */ +__code cs57 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9798 */ +__code cs58 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 9943 */ +__code cs59 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10088 */ +__code cs60 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10233 */ +__code cs61 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10378 */ +__code cs62 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10523 */ +__code cs63 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10668 */ +__code cs64 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10813 */ +__code cs65 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 10958 */ +__code cs66 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11103 */ +__code cs67 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11248 */ +__code cs68 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11393 */ +__code cs69 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11538 */ +__code cs70 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11683 */ +__code cs71 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11828 */ +__code cs72 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 11973 */ +__code cs73 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12118 */ +__code cs74 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12263 */ +__code cs75 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12408 */ +__code cs76 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12553 */ +__code cs77 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12698 */ +__code cs78 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12843 */ +__code cs79 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 12988 */ +__code cs80 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13133 */ +__code cs81 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13278 */ +__code cs82 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13423 */ +__code cs83 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13568 */ +__code cs84 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13713 */ +__code cs85 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 13858 */ +__code cs86 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14003 */ +__code cs87 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14148 */ +__code cs88 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14293 */ +__code cs89 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14438 */ +__code cs90 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14583 */ +__code cs91 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14728 */ +__code cs92 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 14873 */ +__code cs93 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15018 */ +__code cs94 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15163 */ +__code cs95 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15308 */ +__code cs96 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15453 */ +__code cs97 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15598 */ +__code cs98 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15743 */ +__code cs99 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 15888 */ +__code cs100 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16034 */ +__code cs101 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16180 */ +__code cs102 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16326 */ +__code cs103 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16472 */ +__code cs104 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16618 */ +__code cs105 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16764 */ +__code cs106 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 16910 */ +__code cs107 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17056 */ +__code cs108 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17202 */ +__code cs109 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17348 */ +__code cs110 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17494 */ +__code cs111 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17640 */ +__code cs112 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17786 */ +__code cs113 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 17932 */ +__code cs114 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18078 */ +__code cs115 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18224 */ +__code cs116 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18370 */ +__code cs117 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18516 */ +__code cs118 (int i, int a, int b, int c, int d, int e); + +/* defined in file code_segment_pointer_check2.cbc at offset 18662 */ +__code cs119 (int i, int a, int b, int c, int d, int e); + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/conv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/conv.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,92 @@ +#include "stdio.h" + +f0(int i) { + int k,j; + k = 3+i; + j = g0(i+3); + return k+4+j; +} + +g0(int i) { + return i+4; +} + + +typedef void *stack; + +__code f_g0(int i,int k,stack sp) ; + +struct cont_interface { // General Return Continuation + __code (*ret)(int, void*); +}; + +__code f(int i,stack sp) { + int k,j; + k = 3+i; + goto f_g0(i,k,sp); +} + +struct f_g0_interface { // Specialized Return Continuation + __code (*ret)(); + int i_,k_,j_; +}; + +__code f_g1(int j,stack sp); +__code g(int i,stack sp) ; + +__code f_g0(int i,int k,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = f_g1; + c->k_ = k; + c->i_ = i; + + goto g(i+3,sp); +} + +__code f_g1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int k = c->k_; + sp += sizeof(struct f_g0_interface); + goto (( (struct cont_interface *)sp)->ret)(k+4+j,sp); +} + +__code g(int i,stack sp) { + goto (( (struct cont_interface *)sp)->ret)(i+4,sp); +} + +struct main_continuation { // General Return Continuation + __code (*ret)(int, void*); + __code (*main_ret)(int, void*); + void *env; +}; + +__code main_return(int i,stack sp) { + printf("#0061:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(i, + ((struct main_continuation *)sp)->env); +} + +#define STACK_SIZE 2048 +char main_stack[STACK_SIZE]; +#define stack_last (&main_stack[STACK_SIZE]) + +typedef __code (*return_type)(int, void*); +int +main(int argc, char **argv) +{ + struct main_continuation *cont; + stack sp = stack_last; + + printf("#0075:%d\n",f0(233)); + + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return; + cont->main_ret = (return_type) _CbC_return; + cont->env = _CbC_environment; + goto f(233,sp); +} + +/* end */ diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/conv1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/conv1.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,225 @@ +#include "stdio.h" + +static int loop; + +#if 1 // def __micro_c__ +#define CC_ONLY 0 +#else +#define CC_ONLY 1 +#endif + +/* classical function call case (0) */ + +f0(int i) { + int k,j; + k = 3+i; + j = g0(i+3); + return k+4+j; +} + +g0(int i) { + return h0(i+4)+i; +} + +h0(int i) { + return i+4; +} + +#if !CC_ONLY + +/* straight conversion case (1) */ + +typedef char *stack; + +struct cont_interface { // General Return Continuation + __code (*ret)(int, void *); +}; + +__code f(int i,stack sp) { + int k,j; + k = 3+i; + goto f_g0(i,k,sp); +} + +struct f_g0_interface { // Specialized Return Continuation + __code (*ret)(int, void *); + int i_,k_,j_; +}; + +__code f_g1(int j,stack sp); + +__code f_g0(int i,int k,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = f_g1; + c->k_ = k; + c->i_ = i; + + goto g(i+3,sp); +} + +__code f_g1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int k = c->k_; + sp+=sizeof(struct f_g0_interface); + c = (struct f_g0_interface *)sp; + goto (c->ret)(k+4+j,sp); +} + +__code g_h1(int j,stack sp); + +__code g(int i,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = g_h1; + c->i_ = i; + + goto h(i+3,sp); +} + +__code g_h1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int i = c->i_; + sp+=sizeof(struct f_g0_interface); + c = (struct f_g0_interface *)sp; + goto (c->ret)(j+i,sp); +} + +__code h(int i,stack sp) { + struct f_g0_interface *c = (struct f_g0_interface *)sp; + goto (c->ret)(i+4,sp); +} + +struct main_continuation { // General Return Continuation + __code (*ret)(); + __code (*main_ret)(); + void *env; +}; + +__code main_return(int i,stack sp) { + if (loop-->0) + goto f(233,sp); + printf("#0103:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +/* little optimzation without stack continuation (2) */ + +__code f2(int i,char *sp) { + int k,j; + k = 3+i; + goto g2(i,k,i+3,sp); +} + +__code g2(int i,int k,int j,char *sp) { + j = j+4; + goto h2(i,k+4+j,sp); +} + +__code h2_1(int i,int k,int j,char *sp) { + goto main_return2(i+j,sp); +} + +__code h2(int i,int k,char *sp) { + goto h2_1(i,k,i+4,sp); +} + +__code main_return2(int i,stack sp) { + if (loop-->0) + goto f2(233,sp); + printf("#0132:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +/* little optimizaed case (3) */ + +__code f2_1(int i,char *sp) { + int k,j; + k = 3+i; + goto g2_1(k,i+3,sp); +} + +__code g2_1(int k,int i,char *sp) { + goto h2_11(k,i+4,sp); +} + +__code f2_0_1(int k,int j,char *sp); +__code h2_1_1(int i,int k,int j,char *sp) { + goto f2_0_1(k,i+j,sp); +} + +__code h2_11(int i,int k,char *sp) { + goto h2_1_1(i,k,i+4,sp); +} + +__code f2_0_1(int k,int j,char *sp) { + goto (( (struct cont_interface *)sp)->ret)(k+4+j,sp); +} + +__code main_return2_1(int i,stack sp) { + if (loop-->0) + goto f2_1(233,sp); + printf("#0165:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +#define STACK_SIZE 2048 +char main_stack[STACK_SIZE]; +#define stack_last (main_stack+STACK_SIZE) + +#endif + +#define LOOP_COUNT 10000000 + +main(int ac,char *av[]) +{ +#if !CC_ONLY + struct main_continuation *cont; + stack sp = stack_last; +#endif + int sw; + int j; + if (ac==2) sw = atoi(av[1]); + else sw=3; + + if (sw==0) { + for(loop=0;loopret = main_return; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f(233,sp); + } else if (sw==2) { + loop = LOOP_COUNT; + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return2; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f2(233,sp); + } else if (sw==3) { + loop = LOOP_COUNT; + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return2_1; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f2_1(233,sp); +#endif + } +return 0; +} + +/* end */ diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/conv1/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/conv1/Makefile Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,11 @@ +CbCC = ../../../build_cbc44/INSTALL_DIR/libexec/gcc/i686-pc-linux-gnu/4.4.1/cc1 + + +time: + for exe in *; do \ + if [ -x $$exe ]; then \ + echo $$exe; \ + time ./$$exe; \ + fi; \ + done + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/conv1/conv1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/conv1/conv1.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,227 @@ +#include +static int loop; + +#if 1 // def __micro_c__ +#define CC_ONLY 0 +#else +#define CC_ONLY 1 +#endif + +typedef char *stack; +#include "conv1.h" + +/* classical function call case (0) */ + +f0(int i) { + int k,j; + k = 3+i; + j = g0(i+3); + return k+4+j; +} + +g0(int i) { + return h0(i+4)+i; +} + +h0(int i) { + return i+4; +} + +#if !CC_ONLY + +/* straight conversion case (1) */ + + +struct cont_interface { // General Return Continuation + __code (*ret)(); +}; + +__code f(int i,stack sp) { + int k,j; + k = 3+i; + goto f_g0(i,k,sp); +} + +struct f_g0_interface { // Specialized Return Continuation + __code (*ret)(); + int i_,k_,j_; +}; + +__code f_g1(int j,stack sp); + +__code f_g0(int i,int k,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = f_g1; + c->k_ = k; + c->i_ = i; + + goto g(i+3,sp); +} + +__code f_g1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int k = c->k_; + sp+=sizeof(struct f_g0_interface); + c = (struct f_g0_interface *)sp; + goto (c->ret)(k+4+j,sp); +} + +__code g_h1(int j,stack sp); + +__code g(int i,stack sp) { // Caller + struct f_g0_interface *c = + (struct f_g0_interface *)(sp -= sizeof(struct f_g0_interface)); + + c->ret = g_h1; + c->i_ = i; + + goto h(i+3,sp); +} + +__code g_h1(int j,stack sp) { // Continuation + struct f_g0_interface *c = (struct f_g0_interface *)sp; + int i = c->i_; + sp+=sizeof(struct f_g0_interface); + c = (struct f_g0_interface *)sp; + goto (c->ret)(j+i,sp); +} + +__code h(int i,stack sp) { + struct f_g0_interface *c = (struct f_g0_interface *)sp; + goto (c->ret)(i+4,sp); +} + +struct main_continuation { // General Return Continuation + __code (*ret)(); + __code (*main_ret)(int,void*); + void *env; +}; + +__code main_return(int i,stack sp) { + if (loop-->0) + goto f(233,sp); + printf("#0103:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +/* little optimzation without stack continuation (2) */ + +__code f2(int i,char *sp) { + int k,j; + k = 3+i; + goto g2(i,k,i+3,sp); +} + +__code g2(int i,int k,int j,char *sp) { + j = j+4; + goto h2(i,k+4+j,sp); +} + +__code h2_1(int i,int k,int j,char *sp) { + goto main_return2(i+j,sp); +} + +__code h2(int i,int k,char *sp) { + goto h2_1(i,k,i+4,sp); +} + +__code main_return2(int i,stack sp) { + if (loop-->0) + goto f2(233,sp); + printf("#0132:%d\n",i); + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); +} + +/* little optimizaed case (3) */ + +__code f2_1(int i,char *sp) { + int k,j; + k = 3+i; + goto g2_1(k,i+3,sp); +} + +__code g2_1(int k,int i,char *sp) { + goto h2_11(k,i+4,sp); +} + +__code f2_0_1(int k,int j,char *sp); +__code h2_1_1(int i,int k,int j,char *sp) { + goto f2_0_1(k,i+j,sp); +} + +__code h2_11(int i,int k,char *sp) { + goto h2_1_1(i,k,i+4,sp); +} + +__code f2_0_1(int k,int j,char *sp) { + goto (( (struct cont_interface *)sp)->ret)(k+4+j,sp); +} + +__code main_return2_1(int i,stack sp) { + if (loop-->0) + goto f2_1(233,sp); + printf("#0165:%d\n",i); + exit(0); + //goto (( (struct main_continuation *)sp)->main_ret)(0, + //((struct main_continuation *)sp)->env); +} + +#define STACK_SIZE 2048 +char main_stack[STACK_SIZE]; +#define stack_last (main_stack+STACK_SIZE) + +#endif + +#define LOOP_COUNT 500000000 +int +main(int ac,char *av[]) +{ +#if !CC_ONLY + struct main_continuation *cont; + stack sp = stack_last; +#endif + int sw; + int j; + if (ac==2) sw = atoi(av[1]); + else sw=3; + + if (sw==0) { + for(loop=0;loopret = main_return; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f(233,sp); + } else if (sw==2) { + loop = LOOP_COUNT; + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return2; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f2(233,sp); + } else if (sw==3) { + loop = LOOP_COUNT; + sp -= sizeof(*cont); + cont = (struct main_continuation *)sp; + cont->ret = main_return2_1; + cont->main_ret = _CbC_return; + cont->env = _CbC_environment; + goto f2_1(233,sp); +#endif + } +return 0; +} + +/* end */ diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/conv1/conv1.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/conv1/conv1.h Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,54 @@ +/* defined in file conv1.c at offset 468 */ +__code f (int i,stack sp); + +/* defined in file conv1.c at offset 680 */ +__code f_g0 (int i,int k,stack sp); + +/* defined in file conv1.c at offset 897 */ +__code f_g1 (int j,stack sp); + +/* defined in file conv1.c at offset 1162 */ +__code g (int i,stack sp); + +/* defined in file conv1.c at offset 1355 */ +__code g_h1 (int j,stack sp); + +/* defined in file conv1.c at offset 1588 */ +__code h (int i,stack sp); + +/* defined in file conv1.c at offset 1838 */ +__code main_return (int i,stack sp); + +/* defined in file conv1.c at offset 2107 */ +__code f2 (int i,char *sp); + +/* defined in file conv1.c at offset 2189 */ +__code g2 (int i,int k,int j,char *sp); + +/* defined in file conv1.c at offset 2270 */ +__code h2_1 (int i,int k,int j,char *sp); + +/* defined in file conv1.c at offset 2346 */ +__code h2 (int i,int k,char *sp); + +/* defined in file conv1.c at offset 2410 */ +__code main_return2 (int i,stack sp); + +/* defined in file conv1.c at offset 2658 */ +__code f2_1 (int i,char *sp); + +/* defined in file conv1.c at offset 2742 */ +__code g2_1 (int k,int i,char *sp); + +/* defined in file conv1.c at offset 2844 */ +__code h2_1_1 (int i,int k,int j,char *sp); + +/* defined in file conv1.c at offset 2918 */ +__code h2_11 (int i,int k,char *sp); + +/* defined in file conv1.c at offset 2987 */ +__code f2_0_1 (int k,int j,char *sp); + +/* defined in file conv1.c at offset 3086 */ +__code main_return2_1 (int i,stack sp); + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/loto6.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/loto6.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,80 @@ +/* + * Nov 10, 2009 + * created by gongo. + * + * Nov 10, 2009 + * modified by kent. + */ + +#include +#include + +(*ret)(int, void*); +void *env; + + +__code +print(int *numbers) +{ + printf("%d-%d-%d-%d-%d-%d\n", numbers[0], numbers[1], numbers[2], numbers[3], numbers[4], numbers[5]); + free(numbers); + goto ret(0, env); +} + + __code +take(int *array, int size, int length) +{ + int *taked = (int*)malloc(sizeof(int)*length); + + memcpy(taked, array, sizeof(int)*length); + free(array); + + goto print(taked); +} + +__code +shuffle(int *array, int size, int idx) +{ + int j = random() % size; + int tmp = array[idx]; + array[idx] = array[j]; + array[j] = tmp; + + if (++idx < size) { + goto shuffle(array, size, idx); + } else { + goto take(array, size, 6); + } +} + +__code +range_loop(int *array, int idx, int from, int to, int step, int size) +{ + array[idx] = from; + + if (from+step > to) { + goto shuffle(array, size, 0); + } else { + goto range_loop(array, idx+1, from+step, to, step, size); + } +} + +__code +range(int from, int to, int step) +{ + int size = (to-from+1)/step; + int *array = (int*)malloc(sizeof(int)*size); + + goto range_loop(array, 0, from, to, step, size); +} + +int +main() +{ + srand(time(NULL)); + ret = _CbC_return; + env = _CbC_environment; + + goto range(1, 43, 1); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/matrix/compute_power.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/matrix/compute_power.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,107 @@ +#include +#include "matrix.h" + +void compute(); +double ** create_identity_matrix(int size); +double ** multiply(double **a, double **b, int l, int m, int n); +void print_matrix(double **a, int row, int col); + +int +main(int argc, char **argv) +{ + compute(); + return 0; +} + +void +compute() +{ + double **A, **B, **C; + A = create_identity_matrix(4); + B = create_identity_matrix(4); + printf("A = \n"); + print_matrix(A, 4, 4); + printf("B = \n"); + print_matrix(B, 4, 4); + + C = multiply(A, B, 4,4,4); + printf("C = \n"); + print_matrix(C, 4, 4); + + + free(A); + free(B); + free(C); +} + +double ** +create_identity_matrix(int size) +{ + int i,j; + double **ret; + ret = create_matrix(sizeof(double), size, size); + + for (j=0; j +#include + +//size_t size; +int size; +typedef int test_int; + +test_int ti; + +void end(){ + exit(0); +} + +int main(int argc, char **argv){ + size=0; + ti=10; + + printf("main: "); + printf("normal:%d\n", argc); + + size = 10; + printf("size = %d\n", size); + printf(" ti = %d\n", ti); + end(); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/normal2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/normal2.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,65 @@ +//#include +//#include + +struct abc { + int a; + double b; + char c; + double *d; +}; + +struct def { + int d; + struct abc e; + struct abc *f; +}; + +void print_abc(struct abc a){ + printf("\tstruct abc:\n"); + printf("\ta=%d, b=%lf, c=%d, d=%p\n", a.a, a.b, a.c, a.d); +} +void print_def(struct def b){ + printf("\tstruct def:\n"); + printf("\ta=%d, b=%p\n", b.d, b.f); + print_abc(b.e); +} + +void cs_exit(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); +} + +void cs0(struct abc a, struct def b, int c){ + printf("cs0 :\n"); + print_abc(a); + print_def(b); + return cs_exit( c*a.a+b.e.c ); +} + + +void cs_goto(int c, struct abc a, struct def b){ + printf("cs_return :\n"); + print_abc(a); + print_def(b); + return cs0(a, b, c); +} + +int main(int argc, char **argv){ + struct abc A; + struct def B; + //int a=10, b=20, c=30, d=40, e=50, f=60, g=70; + A.a = 10, A.b = 20.02, A.c = '\0', A.d = 0; + B.d = 30, B.f = &A; + B.e.a = 50, B.e.b = 60.06, B.e.c = '\1', B.e.d = 0; + + printf("main :\n"); + print_abc(A); + print_def(B); + //printf("20*%d + 30*%d + 40*%d + 50*%d =\n", a, b, c, d); + cs_goto(100, A, B); + return 0; +} + + + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/parallel_check/c-int-double.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/parallel_check/c-int-double.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,46 @@ +#include +#include + +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(1), ## args) + +int +test(int a) +{ + return (int)pow(a, 2.0); +} + +int +callee(double a, double b, double c, int d) +{ + dprint("a=%d,b=%d,c=%d,d=%d\n", a,b,c,d); + return a+b+c+d; +} + +int +caller(int a, double b, double c, double d) +{ + int x; + double y,z,w; + //x = test(a); + //y = test(b); + //z = test(c); + //w = test(d); + x=a, y=b; + z=c, w=d; + + return callee(y,z,w,x); + //return callee(b,c,d, a); +} + +int +main (int argc, char **argv) +{ + int r; + r = caller(11,22,33,44); + //r = caller(11,22,33,44, 55,66,77,88); + printf("r = %d\n", r); +} + + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/parallel_check/c-int.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/parallel_check/c-int.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,71 @@ +#include +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(1), ## args) + +void +callee(int a, int b, int c, int d) +{ + int r; + dprint("a=%d,b=%d,c=%d,d=%d\n", a,b,c,d); + r = a+b+c+d; + printf("r = %d\n", r); + return; +} + +void +caller1(int a, int b, int c, int d) +{ + int x,y,z,w; + x=a, y=b; + z=c, w=d; + + callee(x,y,z,w); + return; +} + +void +caller2(int a, int b, int c, int d) +{ + int x,y,z,w; + x=a, y=b; + z=c, w=d; + + callee(y,z,w,x); + return; +} + +void +caller3(int a, int b, int c, int d) +{ + callee(b,c,d,a); + return; +} + +void +caller4(int a, int b, int c, int d) +{ + callee(a+b,b+c,c+d,d+a); + return; +} + +void +caller5(int a, int b, int c, int d) +{ + int x,y,z,w; + x = a+b; + y = b+c; + z = c+d; + w = d+a; + + callee(x,y,z,w); + return; +} + +int +main (int argc, char **argv) +{ + int r; + caller(11,22,33,44); + //r = caller(11,22,33,44, 55,66,77,88); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/parallel_check/c-struct.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/parallel_check/c-struct.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,51 @@ +#include +#include + +#define dprint(f, args...) \ + printf("in %s env=%p: "f, __FUNCTION__, __builtin_frame_address(1), ## args) + +typedef struct { + int a; + double b; + char *c; +} STRUCT; + +int +test(int a) +{ + return (int)pow(a, 2.0); +} + + +int +callee(int a, STRUCT s, int b) + /* |-|----|-| */ +{ + dprint("a=%d,b=%d\n", a,b); + dprint("s.a=%d,s.b=%lf,s.c=%s\n", s.a, s.b, s.c); + return a+b+ s.a; +} + +int +caller(STRUCT s, int a, double b) + /* |----|-|--| */ +{ + STRUCT s0;// = {44, 55.5, "aiueo2"}; + //int a0 = 55; + //a0 = a; + s0 = s; + + return callee(10, s0, 20); +} + +int +main (int argc, char **argv) +{ + int r; + STRUCT s = { 33, 44.4, "aiueo" }; + + r = caller(s, 11, 22.2); + //r = caller(11,22,33,44, 55,66,77,88); + printf("r = %d\n", r); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/quicksort/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/Makefile Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,39 @@ + +CbCC=../../BUILD/INSTALL_DIR/bin/gcc + +#CC=gcc +#CC=../../../build_gcc/INSTALL_DIR/bin/gcc +CC=../../BUILD/INSTALL_DIR/bin/gcc + +HEADERMAKER=../../CbC-scripts/make_headers.py2 + +# fastcall版では-O0,-O2は動作確認、-O3以上はだめ +#CFLAGS=-g -O2 -fomit-frame-pointer +#CFLAGS=-g -O2 +CFLAGS=-g -O0 +#CFLAGS=-g -Os # an error occurred. + +.SUFFIXES: .cbc .o + +all: quicksort_cbc quicksort_c quicksort_cbc2 + +.cbc.o: + $(CbCC) $(CFLAGS) -c -o $@ $< +.cbc.h: + $(HEADERMAKER) $^ > $@ + +quicksort_cbc.o: quicksort_cbc.h +quicksort_cbc2.o: quicksort_cbc2.h +quicksort_test.o: quicksort_test.h + +quicksort_cbc: quicksort_cbc.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ +quicksort_cbc2: quicksort_cbc2.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ + +quicksort_c: quicksort_c.o + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -rf *.o *.s quicksort_c quicksort_cbc quicksort_cbc2 diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/quicksort/benchmark.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/benchmark.sh Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,44 @@ +#!/usr/bin/env zsh + +time=/usr/bin/time +QS=./quicksort_cbc +size=10000000 +seed=123456789 +num=10 + + +max=0 +min=99999 +count=0 +amount=0 + +echo "size of array = $size" +while [[ $count -lt $num ]]; do + usertime=$( $time -p $QS -n $size -s $seed 2>&1 >& - |grep '^user'|tr -s " "|cut -f2 -d" ") + #usertime=$(printf "%d" $usertime) + echo $usertime + + amount=$(($usertime+$amount)) + if [[ $usertime -lt $min ]]; then + min=$usertime + fi + if [[ $usertime -gt $max ]]; then + max=$usertime + fi + #seed=$seed[1,-2] + seed=$(($seed+10)) + count=$(($count+1)) +done + +echo "amount time = $amount" +echo "maxtime = $max" +echo "mintime = $min" + +amount=$(($amount - $max - $min)) +echo "amount time - mintime - maxtime = $amount" +count=$(($count-2)) +echo "count = $count" +averagetime=$(($amount/($count))) +echo "average time = $averagetime" + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/quicksort/mc/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/mc/Makefile Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,39 @@ + +CbCC=../../../../device/mc + +#CC=gcc +CC=../../../../build_gcc/INSTALL_DIR/bin/gcc + +HEADERMAKER=../../../CbC-scripts/make_headers.py2 + +CFLAGS=-g -Wall + +.SUFFIXES: .cbc .o .s .c + +all: quicksort_cbc quicksort_c quicksort_cbc2 + +quicksort_c.c quicksort_cbc.cbc quicksort_cbc2.cbc quicksort_test.cbc benchmark.sh: + ln -s ../$@ + +.s.o: + $(CC) -c -o $@ $< +.cbc.s: + $(CbCC) $< +.cbc.h: + $(HEADERMAKER) $^ > $@ + +quicksort_cbc.o: quicksort_cbc.h +quicksort_cbc2.o: quicksort_cbc2.h +quicksort_test.o: quicksort_test.h + +quicksort_cbc: quicksort_cbc.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ +quicksort_cbc2: quicksort_cbc2.o quicksort_test.o + $(CC) $(CFLAGS) -o $@ $^ + +quicksort_c: quicksort_c.o + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -rf *.o *.s quicksort_c quicksort_cbc quicksort_cbc2 diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/quicksort/quicksort_c.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_c.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,183 @@ +#include +#include +#include +#include + +static inline void +SWAP (int *a, int *b) +{ + int tmp; + tmp = *a; + *a = *b; + *b = tmp; +} + +static inline int +mid_point(int a, int b, int c) +{ + if (a < b) { + if (b < c) + return b; + else if (a < c) + return c; + else + return a; + } else { + if (a < c) + return a; + else if (b < c) + return c; + else + return b; + } +} + +void +selectsort(int *v, int s0, int e0) +{ + int i,j; + int m; + int size = e0-s0+1; + v += s0; + for (i=0; i v[j]) + m = j; + } + if (m!=i) + SWAP(&v[i],&v[m]); + } + return; +} + +void +quicksort(int *v, int s0, int e0) +{ + int p; + int s=s0, e=e0; +#if 0 + if (e<=s) return; + if (e-s<5) { + selectsort(v,s0,e0); + return; + } +#else + if (e<=s) return; +#endif + + //p = (v[s]+v[(s+e)/2]+v[e])/3; + p = mid_point(v[s],v[e],v[(s+e)/2]); + + while (1) { + while (v[s] v[i+1]) + return 0; + } + return 1; +} + +void +random_initialize(int *v, int size, int min, int max) +{ + int i; + int diff = max-min+1; + + for (i=0; i +#include +#include + +typedef void *stack; +typedef struct { + int size; + void *interface; + __code (*ret)(void*, stack) ; +} frame, *framep; + +/* quickstart main routine. */ +typedef struct { + int *v; + int s; + int e; +} QS_IF ; +typedef __code (*RET)(void*); + +#include"quicksort_cbc.h" + +/* for check. */ +void *mustbefreed; + +__code returner(stack sp) +{ + framep fp = (framep)sp; + sp += fp->size; + goto fp->ret(fp->interface, sp); +} + +__code quicksort_start(void *arg, stack sp) +{ + QS_IF *recvif = arg; + int a,b,c,p; + a = recvif->v[recvif->s]; + b = recvif->v[recvif->e]; + c = recvif->v[(recvif->s+recvif->e)/2]; + + //printf("quicksort_start: s=%d,e=%d", recvif->s, recvif->e); + if (recvif->e <= recvif->s) goto returner(sp); + + if (a < b) { + if (b < c) + p = b; + else if (a < c) + p = c; + else + p = a; + } else { + if (a < c) + p = a; + else if (b < c) + p = c; + else + p = b; + } + + goto quicksort_divider (recvif, recvif->s, recvif->e, p, sp); +} +/* main routine end. */ + +/* divide routine. */ +__code quicksort_divider(QS_IF *recvif, int s, int e, int p, stack sp) +{ + goto quicksort_divider_s(recvif, s, e, p, sp); +} +__code quicksort_divider_s(QS_IF *recvif, int s, int e, int p, stack sp) +{ + if (recvif->v[s]v[e]) { + e--; + goto quicksort_divider_e(recvif, s, e, p, sp); + } else + goto quicksort_swapper(recvif, s, e, p, sp); +} +__code quicksort_swapper(QS_IF *recvif, int s, int e, int p, stack sp) +{ + if (sv[s]; + recvif->v[s] = recvif->v[e]; + recvif->v[e] = tmp; + goto quicksort_divider(recvif, s+1, e-1, p, sp); + } else { + goto quicksort_treecall(recvif, s, e, sp); + } +} +/* divide routin end. */ + + +/* recursive call routine. */ +__code quicksort_treecall(QS_IF *recvif, int s, int e, stack sp) +{ + framep fp; + QS_IF *outif; + + /* interface for first quicksort_start this segment directly jump to. */ + outif = (sp-=sizeof(QS_IF)); + outif->v = recvif->v; + outif->s = recvif->s; + outif->e = e; + fp = (sp-=sizeof(frame)); + fp->ret = quicksort_start; + fp->interface = recvif; + fp->size = sizeof(frame)+sizeof(QS_IF); + + /* recvif is used by second quicksort_start. */ + recvif->s = e+1; + goto quicksort_start(outif, sp); +} +/* recursive call routine end. */ + +#define STACK_SIZE 10240 + +typedef struct { + __code (*ret)(void*); + void *ret_arg; + stack *sp; +} QS_FINISH; +__code +quicksort(int *v, int s, int e, RET ret, void *arg ) +{ + framep fp; + stack sp0, sp; + sp0 = mustbefreed = malloc(STACK_SIZE); + sp = sp0 + STACK_SIZE; + QS_FINISH *finish_if; + QS_IF *outif; + + /* interface for quicksort_finish. */ + finish_if = (sp -= sizeof(QS_FINISH)); + finish_if->ret = ret; + finish_if->ret_arg = arg; + finish_if->sp = sp0; + + /* interface for quicksort_start. */ + outif = (sp -= sizeof(QS_IF)); + outif->v = v; + outif->s = s; + outif->e = e; + /* frame for quicksort_finish. */ + fp = (sp -= sizeof(frame)); + fp->ret = quicksort_finish; + fp->interface = finish_if; + fp->size = sizeof(frame)+sizeof(QS_IF); + + goto quicksort_start(outif, sp); +} +__code +quicksort_finish(void *arg, stack sp) +{ + QS_FINISH interface; + interface = *(QS_FINISH*)arg; + //assert((void*)interface.sp==(void*)mustbefreed); + free(interface.sp); + goto interface.ret(interface.ret_arg); +} + + + +#if 0 +void +quicksort_c(int *v, int s0, int e0, stack sp) +{ + int p; + int s=s0, e=e0; + if (e<=s) return; + + //p = (v[s]+v[(s+e)/2]+v[e])/3; + p = mid_point(v[s],v[e],v[(s+e)/2]); + + while (1) { + while (v[s]ret = caller_finish; + fp->interface = NULL; + fp->size = sizeof(*outif)+sizeof(frame); + + goto quicksort_start(outif, sp); +} +__code caller_finish0(void *arg, stack sp) +{ +} + +__code __returner0(void *arg , stack sp) +{ + framep fp = sp; + sp += fp->size; + goto fp->ret(fp->interface, sp); +} + +#endif + + + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/quicksort/quicksort_cbc2.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_cbc2.cbc Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,159 @@ +#include +#include +#include + +typedef struct { + int *v; + int s; + int e; +} QS_IF; + +typedef void *stack; +typedef __code (*RET)(QS_IF, stack); +typedef struct { + int size; + QS_IF interface; + RET ret; +} frame, *framep; + +typedef __code (*RETTYPE)(void*); +typedef struct { + RETTYPE ret; + void *ret_arg; + stack *sp; +} QS_FINISH; +#define STACK_SIZE 10240 + +#include"quicksort_cbc2.h" + +__code returner(stack sp) +{ + framep fp = (framep)sp; + sp += fp->size; + goto fp->ret(fp->interface, sp); +} + +__code quicksort_start(QS_IF recvif, stack sp) +{ + int a,b,c,p; + a = recvif.v[recvif.s]; + b = recvif.v[recvif.e]; + c = recvif.v[(recvif.s+recvif.e)/2]; + + //printf("quicksort_start: s=%d,e=%d", recvif->s, recvif->e); + if (recvif.e <= recvif.s) goto returner(sp); + + if (a < b) { + if (b < c) + p = b; + else if (a < c) + p = c; + else + p = a; + } else { + if (a < c) + p = a; + else if (b < c) + p = c; + else + p = b; + } + + goto quicksort_divider (recvif, recvif.s, recvif.e, p, sp); +} +/* main routine end. */ + +/* divide routine. */ +__code quicksort_divider(QS_IF recvif, int s, int e, int p, stack sp) +{ + goto quicksort_divider_s(recvif, s, e, p, sp); +} +__code quicksort_divider_s(QS_IF recvif, int s, int e, int p, stack sp) +{ + if (recvif.v[s]ret = quicksort_start; + fp->size = sizeof(frame); + fp->interface.v = recvif.v; + fp->interface.s = e+1; + fp->interface.e = recvif.e; + + /* recvif is used by second quicksort_start. */ + recvif.e = e; + goto quicksort_start(recvif, sp); +} +/* recursive call routine end. */ + +__code +quicksort(int *v, int s, int e, RETTYPE ret, void *arg ) +{ + framep fp; + stack sp0, sp; + sp0 = malloc(STACK_SIZE); + printf("allocate a stack %p\n", sp0); + sp = sp0 + STACK_SIZE; + QS_FINISH *finish_if; + + /* interface for quicksort_finish. */ + finish_if = (sp -= sizeof(*finish_if)); + finish_if->ret = ret; + finish_if->ret_arg = arg; + finish_if->sp = sp0; + + /* interface for quicksort_start. */ + /* frame for quicksort_finish. */ + fp = (sp -= sizeof(frame)); + fp->ret = quicksort_finish; + fp->size = sizeof(frame); + fp->interface.v = v; + fp->interface.s = s; + fp->interface.e = e; + + goto quicksort_start(fp->interface, sp); +} +__code +quicksort_finish(QS_IF recvif, stack sp) +{ + QS_FINISH *interface = (QS_FINISH*)sp; + free(interface->sp); + printf("free the stack %p\n", interface->sp); + goto interface->ret(interface->ret_arg); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/quicksort/quicksort_test.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_test.cbc Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +#include"quicksort_test.h" + +extern __code quicksort(int *,int,int, __code (*)(void*), void*); + + +void +random_initialize(int *v, int size, int min, int max) +{ + int i; + int diff = max-min+1; + + for (i=0; i v[i+1]) + return 0; + } + return 1; +} + +__code +exit0(void *arg) +{ + int *v = arg; + int b; + //print_array(arg, size); + b = check_sort(arg, size); + if (b) { + printf("sorting successful!\n"); + exit(EXIT_SUCCESS); + } else { + printf("sorting failure! \n"); + exit(EXIT_FAILURE); + } +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/regexp/dfareg Binary file CbC-examples/regexp/dfareg has changed diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/regexp/dfareg.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/regexp/dfareg.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,182 @@ +#include + +#include + +__code state_20_21(char* s); +__code state_1(char* s); +__code state_3_8_9_13_23_24(char* s); +__code state_6_7(char* s); +__code state_2_3_9_13_23_24_25(char* s); +__code state_10_11(char* s); +__code state_18_19(char* s); +__code state_4_5(char* s); +__code state_14_15(char* s); +__code state_3_9_13_22_23_24(char* s); +__code state_3_9_12_13_23_24(char* s); +__code state_16_17(char* s); +__code accept(); +__code reject(); + +int main(int argc, char* argv[]) { + if (argc == 1) { + printf("usage: %s text\n", argv[0]); + exit(0); +} + + puts("regexp: P(erl|HP|ython)*"); + puts("number of state: 12"); + printf("string: %s\n", argv[1]); + goto state_1(argv[1]); + return 0; +} + +__code state_20_21(char* s) { + switch(*s++) { + case 'n': + goto state_3_9_13_22_23_24(s); + break; + default: goto reject(); + } +} + +__code state_1(char* s) { + switch(*s++) { + case 'P': + goto state_2_3_9_13_23_24_25(s); + break; + default: goto reject(); + } +} + +__code state_3_8_9_13_23_24(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_6_7(char* s) { + switch(*s++) { + case 'l': + goto state_3_8_9_13_23_24(s); + break; + default: goto reject(); + } +} + +__code state_2_3_9_13_23_24_25(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_10_11(char* s) { + switch(*s++) { + case 'P': + goto state_3_9_12_13_23_24(s); + break; + default: goto reject(); + } +} + +__code state_18_19(char* s) { + switch(*s++) { + case 'o': + goto state_20_21(s); + break; + default: goto reject(); + } +} + +__code state_4_5(char* s) { + switch(*s++) { + case 'r': + goto state_6_7(s); + break; + default: goto reject(); + } +} + +__code state_14_15(char* s) { + switch(*s++) { + case 't': + goto state_16_17(s); + break; + default: goto reject(); + } +} + +__code state_3_9_13_22_23_24(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_3_9_12_13_23_24(char* s) { + switch(*s++) { + case 'y': + goto state_14_15(s); + break; + case 'H': + goto state_10_11(s); + break; + case 'e': + goto state_4_5(s); + break; + case '\0': goto accept(); + break; + default: goto reject(); + } +} + +__code state_16_17(char* s) { + switch(*s++) { + case 'h': + goto state_18_19(s); + break; + default: goto reject(); + } +} + + +__code accept() { + printf("\nstring matches regexp. \n\n"); +} + + +__code reject() { + printf("\nstring does not match regexp. \n\n"); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/regexp/dfareg.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/regexp/dfareg.py Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,414 @@ +#!/usr/bin/env python + +import copy +import sys + +class NondeterministicFiniteAutomaton(object): + def __init__(self, transition, start, accepts, map_): + self.transition = transition + self.start = start + self.accepts = accepts + self.map = map_ + + def epsilonExpand(self, set_): + que = set(set_) + done = set() + while que: + stat = que.pop() + nexts = self.transition(stat, "") + done.add(stat) + for nextStat in nexts: + if not nextStat in done: que.add(nextStat) + return frozenset(done) + +class DeterministicFiniteAutomaton(object): + def __init__(self, transition, start, accepts, map_): + self.transition = transition + self.start = start + self.accepts = accepts + self.map = map_ + def getRuntime(self): + return DFARuntime(self) + +class DFARuntime(object): + def __init__(self, DFA): + self.DFA = DFA + self.curState = self.DFA.start + + def doTransition(self, char): + self.curState = self.DFA.transition( + self.curState, char) + + def isAcceptState(self): + return self.curState in self.DFA.accepts + + def doesAccept(self, input): + for alphabet in input: + self.doTransition(alphabet) + return self.isAcceptState() + +class Token(object): + CHARACTER = 0 + OPE_UNION = 1 + OPE_STAR = 2 + LPAREN = 3 + RPAREN = 4 + EOF = 5 + + def __init__(self, value, kind): + self.value = value + self.kind = kind + + +class Lexer(object): + def __init__(self, str): + self.stringList = list(str) + + def scan(self): + if not self.stringList: + return Token(None, Token.EOF) + + ch = self.stringList.pop(0) + if ch == '\\': + return Token(self.stringList.pop(0), Token.CHARACTER) + elif ch == '|': + return Token(ch, Token.OPE_UNION) + elif ch == '(': + return Token(ch, Token.LPAREN) + elif ch == ')': + return Token(ch, Token.RPAREN) + elif ch == '*': + return Token(ch, Token.OPE_STAR) + else: + return Token(ch, Token.CHARACTER) + +""" + Context-free Grammer: + (A) expression -> subexpr EOF + (B) subexpr -> seq '|' subexpr | seq + (C) seq -> subseq | '' + (D) subseq -> star subseq | star + (E) star -> factor '*' | factor + (F) factor -> '(' subexpr ')' | CHARACTER +""" + +class Parser(object): + def __init__(self, lexer): + self.lexer = lexer + self.look = None + self.move() + + def match(self, tag): + if self.look.kind != tag: + raise Exeption("syntax error") + self.move() + + def move(self): + self.look = self.lexer.scan() + + def factor(self): + if self.look.kind == Token.LPAREN: + # factor -> '(' subexpr ')' + self.match(Token.LPAREN) + node = self.subexpr() + self.match(Token.RPAREN) + return node + else: + # factor -> CHARACTER + node = Character(self.look.value) + self.match(Token.CHARACTER) + return node + + def star(self): + # star -> factor '*' | factor + node = self.factor() + if self.look.kind == Token.OPE_STAR: + self.match(Token.OPE_STAR) + node = Star(node) + return node + + def seq(self): + if self.look.kind == Token.LPAREN \ + or self.look.kind == Token.CHARACTER: + # seq -> subseq + return self.subseq() + else: + # seq -> '' + return Character("") + + def subseq(self): + node1 = self.star() + if self.look.kind == Token.LPAREN \ + or self.look.kind == Token.CHARACTER: + # subseq -> star subseq + node2 = self.subseq() + node = Concat(node1, node2) + return node + else: + # subseq -> star + return node1 + + def subexpr(self): + node1 = self.seq() + if self.look.kind == Token.OPE_UNION: + self.match(Token.OPE_UNION) + # subexpr -> seq '|' subexpr + node2 = self.subexpr() + node = Union(node1, node2) + return node + else: + # subexpr -> seq + return node1 + + def expression(self): + # expression -> subexpr EOF + node = self.subexpr() + self.match(Token.EOF) + + # Create TREE, NFA + context = Context() + fragment = node.assemble(context) + return fragment.build() + +class Context(object): + def __init__(self): + self.stateCount = 0 + + def newState(self): + self.stateCount += 1 + return self.stateCount + +class NFAFragment(object): + def __init__(self): + self.start = None # integer + self.accepts = None # frozenset + self.map = dict() # transition + + def connect(self, from_, char, to): + slot = self.map.setdefault((from_, char), set()) + slot.add(to) + + def newSkelton(self): + # copy fragment (self), and it return + newFrag = NFAFragment(); + newFrag.map = copy.deepcopy(self.map) + return newFrag + + def __or__(self, frag): + newFrag = self.newSkelton() + for k, v in frag.map.iteritems(): + newFrag.map[k] = v.copy() + return newFrag + + def build(self): + map_ = self.map + def transition(state, char): + return frozenset(map_.get((state, char), [])) + + return NondeterministicFiniteAutomaton( + transition, + self.start, + self.accepts, + self.map + ) + +class Character(object): + def __init__(self, char): + self.char = char + + def assemble(self, context): + frag = NFAFragment() + s1 = context.newState() + s2 = context.newState() + frag.connect(s1, self.char, s2) + frag.start = s1 + frag.accepts = frozenset([s2]) + return frag + +class Union(object): + def __init__(self, op1, op2): + self.op1 = op1 + self.op2 = op2 + + def assemble(self, context): + frag1 = self.op1.assemble(context) + frag2 = self.op2.assemble(context) + frag = frag1 | frag2 + s = context.newState() + frag.connect(s, "", frag1.start) + frag.connect(s, "", frag2.start) + frag.start = s + frag.accepts = frag1.accepts | frag2.accepts + return frag + +class Concat(object): + def __init__(self, op1, op2): + self.op1 = op1 + self.op2 = op2 + + def assemble(self, context): + frag1 = self.op1.assemble(context) + frag2 = self.op2.assemble(context) + frag = frag1 | frag2 + + for state in frag1.accepts: + frag.connect(state, "", frag2.start) + + frag.start = frag1.start + frag.accepts = frag2.accepts + return frag + +class Star(object): + def __init__(self, op): + self.op = op + + def assemble(self, context): + fragOrig = self.op.assemble(context) + frag = fragOrig.newSkelton() + + for state in fragOrig.accepts: + frag.connect(state, "", fragOrig.start) + + s = context.newState() + frag.connect(s, "", fragOrig.start) + frag.start = s + frag.accepts = fragOrig.accepts | frozenset([s]) + return frag + +class NonDisjoinSets(object): + def __init__(self, sub): + self.sub = sub + def __contains__(self, a_set): + return a_set & self.sub + +def nfa2dfa(nfa): + def transition(set_, alpha): + ret = set() + for elem in set_: + ret |= nfa.transition(elem, alpha) + return nfa.epsilonExpand(frozenset(ret)) + + def stateSetTransition(stateSet, char): + trans = set() + for state in stateSet: + t = nfa.map.setdefault((state, char), None) + if not t == None: trans.update(nfa.epsilonExpand(t)) + return frozenset(trans) + + map_ = dict() + que = set(frozenset([nfa.epsilonExpand(set([nfa.start]))])) + done = set() + + while que: + stateSet = que.pop() + + for state in stateSet: + for k, v in nfa.map.iteritems(): + if state == k[0] and k[1] != '': + slot = map_.setdefault((stateSet, k[1]), set()) + slot.update(nfa.epsilonExpand(v)) + + done.add(stateSet) + + for v in map_.itervalues(): + if not v in done: + que.add(frozenset(v)) + + return DeterministicFiniteAutomaton( + transition, + nfa.epsilonExpand(frozenset([nfa.start])), + NonDisjoinSets(nfa.accepts), + map_ + ) + +# emit CbC-souce, from dfa +def dfa2CbC(dfa, regexp): + + # return state name from set + def set2name(set_): + l = list(set_) + l.sort() + return '_'.join(str(x) for x in l) + + funcMap = dict() + funcMap[dfa.start] = set() + + # dfa.map => {(frozenset([1, 15]), 'd'): frozenset([16]), ....} + # : frozenset(1, 15) x 'd' -> frozenset([16]) + + for v in dfa.map.itervalues(): + funcMap[frozenset(v)] = set() + + for key in dfa.map.iterkeys(): + slot = funcMap.setdefault(key[0], set()) + slot.add(key[1]) + + # emit cbc code + print "#include \n" + print "#include \n" + for k in funcMap.iterkeys(): + print '__code state_' + set2name(k) + "(char* s);" + print '__code accept();' + print '__code reject();' + print """ +int main(int argc, char* argv[]) { +\tif (argc == 1) { +\t\tprintf(\"usage: %%s text\\n\", argv[0]); +\t\texit(0); +} + +\tputs(\"regexp: %s\"); +\tputs(\"number of state: %d\"); +\tprintf(\"string: %%s\\n\", argv[1]); +\tgoto state_%s(argv[1]); +\treturn 0; +}\n""" % (regexp, len(funcMap), set2name(dfa.start)) + + for k, v in funcMap.iteritems(): + print '__code state_' + set2name(k) + "(char* s) {" + print "\tswitch(*s++) {" + for case in v: + print "\t\tcase '%c': " % (case) + print "\t\t\tgoto state_%s(s);\n\t\t\tbreak;" % set2name(dfa.map[(frozenset(k), case)]) + if k in dfa.accepts: print "\t\tcase '\\0': goto accept();\n\t\t\tbreak;" + print "\t\tdefault: goto reject();\n\t}" + print "}\n" + + print """ +__code accept() { +\tprintf(\"\\nstring matches regexp. \\n\\n\"); +}\n""" + print """ +__code reject() { +\tprintf(\"\\nstring does not match regexp. \\n\\n\"); +}\n""" + +class Regexp(object): + def __init__(self, regexp): + self.regexp = regexp + self.nfa = None + self.dfa = None + self._compile() + + def _compile(self): + lexer_ = Lexer(self.regexp) + parser_ = Parser(lexer_) + self.nfa = parser_.expression() + self.dfa = nfa2dfa(self.nfa) + + def emitCbC(self): + dfa2CbC(self.dfa, self.regexp) + + def matches(self, string): + runtime = self.dfa.getRuntime() + return runtime.doesAccept(string) + +def compile(regexp): + return Regexp(regexp) + +def main(argv): + if len(argv) == 1 : exit("usage: dfareg.py regexp [> file]") + r = compile(argv[1]) + r.emitCbC() + +if __name__ == '__main__' : main(sys.argv) diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/return_check/test_return.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/return_check/test_return.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,89 @@ +#include + +#if 0 +typedef float testtype; +testtype good = 33.3f; +testtype bad = 0.0f; +void print_testtype(testtype t) +{ + printf("return value = %2.3f good=%2.3f,bad=%2.3f\n", t,good,bad); +} +#elif 1 +typedef char testtype; +testtype good = 33; +testtype bad = 0; +void print_testtype(testtype t) +{ + printf("return value = %d, good=%d,bad=%d\n", t,good,bad); +} +#elif 0 +typedef double testtype; +testtype good = 333.3; +testtype bad = 0.00; +void print_testtype(testtype t) +{ + printf("return value = %3.3lf, good=%3.3lf,bad=%3.3lf\n", t,good,bad); +} +#elif 0 +typedef +struct { + int a; + float b; + int c[4]; +} testtype; +testtype good = {33, 33.3, {4,4,4,4}}; +testtype bad = {0, 00.0, {0,0,0,0}}; +void print_testtype(testtype t) +{ + printf( "return value = {\n" + " a = %d\n" + " b = %2.3f\n" + " c = { %d, %d, %d, %d }" + "}\n", t.a, t.b, + t.c[0],t.c[1],t.c[2],t.c[3]); +} +#else +typedef int testtype; +testtype good = 33; +testtype bad = 0; +void print_testtype(testtype t) +{ + printf("return value = %d, good=%d,bad=%d\n", t,good,bad); +} +#endif + +typedef void (*RET_FUNC)(testtype, void *); + +void g(RET_FUNC func) +{ + func(good, NULL); +} + +testtype f_cbc() +{ + //__label__ _cbc_exit0; + //int retval; + void *ret; + + ret = _CbC_return; + + printf("f0: fp = %p\n", __builtin_frame_address(0)); + printf("__return_func = %p\n", ret); + g(ret); + + printf("not good\n"); + return bad; +//_cbc_exit0: + //printf("f1: fp = 0x%x\n", __builtin_frame_address(0)); + //return retval; +} + +int main(int argc, char **argv) +{ + testtype t; + printf("main before: fp = %p\n", __builtin_frame_address(0)); + t = f_cbc(); + print_testtype(t); + printf("main after: fp = %p\n", __builtin_frame_address(0)); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/return_check/typedeffed.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/return_check/typedeffed.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,89 @@ +#include + +#if 0 +typedef float testtype; +testtype good = 33.3f; +testtype bad = 0.0f; +void print_testtype(testtype t) +{ + printf("return value = %2.3f good=%2.3f,bad=%2.3f\n", t,good,bad); +} +#elif 1 +typedef char testtype; +testtype good = 33; +testtype bad = 0; +void print_testtype(testtype t) +{ + printf("return value = %d, good=%d,bad=%d\n", t,good,bad); +} +#elif 0 +typedef double testtype; +testtype good = 333.3; +testtype bad = 0.00; +void print_testtype(testtype t) +{ + printf("return value = %3.3lf, good=%3.3lf,bad=%3.3lf\n", t,good,bad); +} +#elif 0 +typedef +struct { + int a; + float b; + int c[4]; +} testtype; +testtype good = {33, 33.3, {4,4,4,4}}; +testtype bad = {0, 00.0, {0,0,0,0}}; +void print_testtype(testtype t) +{ + printf( "return value = {\n" + " a = %d\n" + " b = %2.3f\n" + " c = { %d, %d, %d, %d }" + "}\n", t.a, t.b, + t.c[0],t.c[1],t.c[2],t.c[3]); +} +#else +typedef int testtype; +testtype good = 33; +testtype bad = 0; +void print_testtype(testtype t) +{ + printf("return value = %d, good=%d,bad=%d\n", t,good,bad); +} +#endif + +typedef void (*RET_FUNC)(testtype, void *); + +void g(RET_FUNC func) +{ + func(good, NULL); +} + +testtype f_cbc() +{ + //__label__ _cbc_exit0; + //int retval; + void *ret; + + ret = _CbC_return; + + printf("f0: fp = %p\n", __builtin_frame_address(0)); + printf("__return_func = %p\n", ret); + g(ret); + + printf("not good\n"); + return bad; +//_cbc_exit0: + //printf("f1: fp = 0x%x\n", __builtin_frame_address(0)); + //return retval; +} + +int main(int argc, char **argv) +{ + testtype t; + printf("main before: fp = %p\n", __builtin_frame_address(0)); + t = f_cbc(); + print_testtype(t); + printf("main after: fp = %p\n", __builtin_frame_address(0)); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/return_check/variable_return_type.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/return_check/variable_return_type.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,196 @@ +#include +#include + +#define dprint(f, args...) \ + fprintf(stdout, "in %s\t: "f, __FUNCTION__, ## args) + + +/* for integer. */ +int goodint = 33; +int badint = 0; +typedef void (*RETINT_FUNC)(int, void *); +void g_int(RETINT_FUNC func) +{ + func(goodint, NULL); +} +int f_int() +{ + void *ret; + + ret = _CbC_return; + + dprint("fp = %p\n", __builtin_frame_address(0)); + dprint("__return_func = %p\n", ret); + g_int(ret); + //goto g(ret); + + dprint("not good\n"); + return badint; +} + + +/* for double. */ +double gooddouble = 333.3; +double baddouble = 0.00; +typedef void (*RETDOUBLE_FUNC)(double, void *); +void g_double(RETDOUBLE_FUNC func) +{ + func(gooddouble, NULL); +} +double f_double() +{ + void *ret; + ret = _CbC_return; + + dprint("fp = %p\n", __builtin_frame_address(0)); + dprint("__return_func = %p\n", ret); + g_double(ret); + //goto g_double(ret); + + dprint("not good\n"); + return baddouble; +} + +/* for float. */ +float goodfloat = 33.3f; +float badfloat = 0.0f; +typedef void (*RETFLOAT_FUNC)(float, void *); +void g_float(RETFLOAT_FUNC func) +{ + func(goodfloat, NULL); +} +float f_float() +{ + void *ret; + ret = _CbC_return; + + dprint("fp = %p\n", __builtin_frame_address(0)); + dprint("__return_func = %p\n", ret); + g_float(ret); + //goto g_float(ret); + + dprint("not good\n"); + return badfloat; +} + +/* for char. */ +char goodchar = 33; +char badchar = 0; +typedef void (*RETCHAR_FUNC)(char, void *); +void g_char(RETCHAR_FUNC func) +{ + func(goodchar, NULL); +} +char f_char() +{ + void *ret; + + ret = _CbC_return; + + dprint("fp = %p\n", __builtin_frame_address(0)); + dprint("__return_func = %p\n", ret); + g_char(ret); + //goto g(ret); + + dprint("not good\n"); + return badchar; +} + + +/* for struct. */ +struct ifid { + int a; + float b; + int c[4]; + double d; +}; +struct ifid goodstruct = {33, 33.3, {4,4,4,4}, 333.333}; +struct ifid badstruct = {0, 00.0, {0,0,0,0}, 0.0}; +typedef void (*RETSTRUCT_FUNC)(struct ifid, void *); +void g_struct(RETSTRUCT_FUNC func) +{ + func(goodstruct, NULL); +} +struct ifid f_struct() +{ + void *ret; + + ret = _CbC_return; + + dprint("fp = %p\n", __builtin_frame_address(0)); + dprint("__return_func = %p\n", ret); + g_struct(ret); + //goto g(ret); + + dprint("not good\n"); + return badstruct; +} + +int main(int argc, char **argv) +{ + void *bptr; + int rint; + float rfloat; + double rdouble; + char rchar; + struct ifid rstruct; + + bptr = __builtin_frame_address(0); + + dprint("before int: fp = %p\n", __builtin_frame_address(0)); + rint = f_int(); + dprint("f_int = %d, good=%d,bad=%d\n", rint,goodint,badint); + + dprint("before float: fp = %p\n", __builtin_frame_address(0)); + rfloat = f_float(); + dprint("f_float = %3.3f, good=%3.3f,bad=%3.3f\n", rfloat,goodfloat,badfloat); + assert(bptr==__builtin_frame_address(0)); + + dprint("before double: fp = %p\n", __builtin_frame_address(0)); + rdouble = f_double(); + dprint("f_double = %3.3lf, good=%3.3lf,bad=%3.3lf\n", rdouble,gooddouble,baddouble); + assert(bptr==__builtin_frame_address(0)); + + dprint("before char: fp = %p\n", __builtin_frame_address(0)); + rchar = f_char(); + dprint("f_char = %d, good=%d,bad=%d\n", rchar,goodchar,badchar); + assert(bptr==__builtin_frame_address(0)); + + dprint("before struct: fp = %p\n", __builtin_frame_address(0)); + rstruct = f_struct(); + dprint( "return value = {\n" + " a = %d\n" + " b = %2.3f\n" + " c = { %d, %d, %d, %d }\n" + " d = %3.3f\n" + "}\n", rstruct.a, rstruct.b, + rstruct.c[0],rstruct.c[1],rstruct.c[2],rstruct.c[3], rstruct.d); + + + + dprint("end: fp = %p\n", __builtin_frame_address(0)); + + if (bptr!=__builtin_frame_address(0)) { + dprint("CbC_return failure!\n"); + return 1; + } + if ( rint!=goodint + || rchar!=goodchar + || (rfloat < goodfloat-0.01 || goodfloat+0.01 < rfloat) + || (rdouble < gooddouble-0.01 || gooddouble+0.01 < rdouble) + || rstruct.a!=goodstruct.a + || (rstruct.b < goodstruct.b-0.01 || goodstruct.b+0.01 < rstruct.b) + || (rstruct.d < goodstruct.d-0.01 || goodstruct.d+0.01 < rstruct.d) + || rstruct.c[0]!=goodstruct.c[0] + || rstruct.c[1]!=goodstruct.c[1] + || rstruct.c[2]!=goodstruct.c[2] + || rstruct.c[3]!=goodstruct.c[3] ) { + dprint("CbC_return failure!\n"); + return 1; + } + + + dprint("CbC_return successful!\n"); + return 0; +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/stack1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/stack1.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,126 @@ +/* + test for CbC converted __code from C + */ + +//#include +#define NULL 0 + +extern void *malloc(int); + +typedef void *stack; + +void *stack0; /* size of void* == 1 */ + +struct cont_save { /* General Return Continuation */ + __code (*ret)(); +}; + + __code g(int,void *); + __code f_g0(int ,int ,void *); + __code f_g1(int,void *); + __code print(int i,int j,__code (*exit1)(),void*exit1env); + +struct f_g0_save { /* Specialized Return Continuation */ + __code (*ret)(); + int ii,kk,jj; +}; + +__code g(int i,void *sp) { + goto (* ((struct cont_save *)sp)->ret)(i+4,sp); +} + +__code __attribute__ ((fastcall)) f_g1(int j,void *sp) { /* Continuation */ + int k; + struct f_g0_save *c; + + c = sp; + k = c->kk; + sp += sizeof(struct f_g0_save); + goto (* ((struct cont_save *)sp)->ret)(k+4+j,sp); +} + +__code f(int i,void *sp) { + int k,j; + struct f_g0_save *c; +printf("#0042:f 0 sp: %x\n",sp-stack0); + + k = 3+i; + +printf("#0046:f 1 sp: %x\n",sp-stack0); + sp -= sizeof(struct f_g0_save); +printf("#0048:f 2 sp: %x\n",sp-stack0); + c = sp; + c->kk = k; + c->ii = i; + c->jj = j; + c->ret = f_g1; + goto g(i,sp); +} + + + +struct f0_save { /* Specialized Return Continuation */ + __code (*ret)(); + __code (*exit1)(); + void *exit1env; + int jj; +}; + +__code f1(int i,void *sp) ; +__code f0(int i,int j,__code(*exit2)(), void *exit2env,void *sp) +{ + struct f0_save *c; + printf("#0070:f0 1 sp: %x\n",sp-stack0); + sp -= sizeof(struct f0_save); + printf("#0072:f0 2 sp: %x\n",sp-stack0); + c = sp; + c->jj = j; + c->exit1 = exit2; + c->exit1env = exit2env; + c->ret = f1; + printf("#0078:f0 3 sp: %x\n",sp-stack0); + goto f(i,sp); +} + +__code f1(int i,void *sp) { + int j; + int *exit2env; + __code (*exit2)(); + struct f0_save *c; + + c = sp; + j = c->jj; + exit2 = c->exit1; + exit2env = c->exit1env; + + sp += sizeof(struct f0_save); + goto print(i,j,exit2,exit2env); +} + +int main(int ac, char*av[]){ + main0(ac,av); +} + +int main0( int ac, char *av[]) +{ + int i,j; + int *sp; + + // i = atoi(av[1]); + i = 1; + stack0 = ((char *)malloc(1024)+1024); + sp = stack0; + j = i; + + printf("#0108:sp: %x %x\n",sp-(int*)stack0,sizeof(*stack0)); + //goto f0(i,j,_CbC_return,_CbC_environment,sp); + goto f0(i,j,NULL,NULL,sp); +} + +__code print(int i,int j,__code (*exit1)(),void*exit1env) +{ + printf("#0114:%d %d\n",i,j); + //goto (*exit1)(0),exit1env; + exit(0); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test01.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test01.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,34 @@ +#include + +int test_code(void){ + printf("\t\ttest_code: return 10\n"); + return 10; +} + +int test_goto(int a){ + printf("\ttest_goto: a = %d\n", a); + //return test_code(); + return test_code(); +} + +int main(int argc, char **argv){ + int ret; + printf("test code\n"); + ret = test_goto(20); + printf("main: ret = %d\n", ret); + + return test_goto2(10,20,30,40,50,60,70,80,90,100); + return 0; +} + +int test_code2(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j,int k){ + printf("\t\ttest_code: return 10\n"); + printf("a=%d,b=%d,c=%d,d=%d,e=%d,f=%d,g=%d,h=%d,i=%d,j=%d,k=%d\n",a,b,c,d,e,f,g,h,i,j,k ); + return a+b+c+d+e+f+g+h+i+j+k; +} + +int test_goto2(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j,int k){ + printf("\ttest_goto: a = %d\n", a); + //return test_code(); + return test_code2(a,b,c,d,e,f,g,h,i,j,k); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test02.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test02.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,22 @@ +#include + +__code test_code(void){ + printf("\t\ttest_code: return 10\n"); + return; +} + +__code test_goto(int a){ + printf("\ttest_goto: a = %d\n", a); + //return test_code(); + goto test_code(); +} + +int main(int argc, char **argv){ + int ret=0; + printf("test code\n"); + test_goto(20); + printf("main: ret = %d\n", ret); + + return 0; +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test03.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test03.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,26 @@ + +extern void test02() ; +extern void test03() ; + +extern int data; + +extern void +test01() { + test02(); +} + +extern void +test02() { + test03(); +} + +extern void +test03() { + data = 3; +} + +int +main() +{ + test01(); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test04.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test04.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,33 @@ + +int test01(int a, double b, int *c){ + return a+b- *c; +} + +int test(int *a, double b){ + int c; + c = *a*b + 10; + printf("a = %x, *a = %d, b = %d\n", a, *a, b); + *a = test01( *a+b, 0.02, &c); + return *a+b; +} + + +int test02(int a, int b){ + int i,sum=0; + i = a; + while ( i <= b ) { + sum += i; + i++; + } + return sum - a*b; +} + +int main(int argc, char **argv){ + int a=10; + + printf("= %d\n", test02(0, 10)); + test( &a, 10.1); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test05.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test05.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,58 @@ +//#include +#define dprint(f, args...) \ + printf("in %s: "f, __FUNCTION__, ## args) + +__code caller (int a); +void f01 (int a); +void f02 (int a, float b); +__code cs01 (int a); +__code cs02 (int a, float b); +int main (); + + +int g=0; +void (*funcp)(int); +__code (*csp)(int); + +__code caller(int a) { + f01(a+2); + f02(a+3, 13.2); + funcp(a+4); + goto csp(a+4); + dprint("\n"); +} + +__code end() { + dprint("\n"); + exit(0); +} + +void f01(int a) { + dprint("%d\n", a); + g += a; + return ; +} +void f02(int a, float b) { + dprint("%d, %f\n", a, b); + g -= a; + g += b*0.3; + return ; +} +__code cs01(int a) { + dprint("%d\n", a); + g += a; + goto end() ; +} +__code cs02(int a, float b) { + dprint("%d, %f\n", a, b); + g -= a; + g += b*0.3; + goto end() ; +} + +int main() { + funcp = f01; + csp = cs01; + caller(10); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_array.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_array.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,17 @@ +//#include +void print_array(int *, int); + +int main(int argc, char **argv){ + int array[10] = {10, 2, 3, 0, 7, 5}; + array[1] += array[2]+array[4]; + print_array(array, 10); + return 0; +} + +void print_array(int *a, int size){ + while( size-->0 ){ + printf(" %7d", *a++); + } + printf("\n"); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_call.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_call.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,12 @@ + +int test(int a){ + printf("a = %d\n", a); + return 10*a; +} + +int main(){ + test(10); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_cs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_cs.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,43 @@ +//#include +//#include + +__code cs_exit(int , double , char ); +__code cs1(int, int, int, int); +__code cs2(double, double, int, double); +void test_goto(void); + +int main(int argc, char **argv){ + printf("main start\n"); + //goto cs2(2.22, 3.33, 4, 5.55); + test_goto(); + return 0; +} + +void test_goto(){ + goto cs1(10, 20, 30, 40); +} + +__code cs1(int a, int b, int c, int d){ + printf("%4d, %4d, %4d, %4d\n", a, b, c, d); + a += 40, b += 40, c += 40, d += 40; + goto cs2((double)a, (double)b, c, (double)d); +} + +__code cs2(double a, double b, int c, double d){ + printf("%4d, %4d, %4d, %4d\n", (int)a, (int)b, (int)c, (int)d); + a += 40, b += 40, c += 40, d += 40; + goto cs_exit((int)a, b, (char)c); +} + +__code cs_exit(int a, double b, char c){ + printf("%4d, %4d, %4d\n", (int)a, (int)b, (int)c); + printf("cs_exit was called!\n"); + exit(0); +} + + +void caller(int a, double b){ + cs2(b,20.0,a, 40.4); + cs1(10,20,30, 40); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_csp1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_csp1.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,60 @@ +#include +#include + +//static __code (*csp)(int, int, int, int); + +__code cs_end (int a); +__code cs0 (int a, int b, int c, int d); +void* freturn (); +__code cs_goto (int a, int b, int c, int d); +int function (double a, float b, int c); +int main (int argc, char **argv); + + +__code cs_goto(int a, int b, int c, int d){ + __code (*csp)(int, int, int, int); + csp = freturn(); + printf("csp = %x.\n", csp); + + //printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + //printf("cs_goto : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + //printf("cs_goto : a-4=%d, a-8=%d, a-12=%d, a-16=%d.\n", *(&a-4), *(&a-8), *(&a-12), *(&a-16)); + //printf("cs_goto : cs0(a, b, c, d)\n"); +#ifdef INDIRECT + goto csp(b+a, d+b, a+c, c+d); +#else + goto cs0(b+a, d+b, a+c, c+d); +#endif +} + +__code cs_end(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); + goto cs_end(a); +} + +__code cs0(int a, int b, int c, int d){ + //printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs_cs0 : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + goto cs_end( (int)(20*a + 30*b + 40*c + 50*d) ); +} + + +void* freturn(){ + return cs0; +} + +int function(double a, float b, int c){ + + printf("function:\n"); + printf("a=%lf, b=%f, c=%d\n", a, b, c); + //goto cs_goto(10, 20, 30, 40); + goto cs_goto(10, 20, 30, 40); +} + +int main(int argc, char **argv){ + //csp = cs0; + function(10.01, 20.02, 30); + return 0; +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_env.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_env.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,68 @@ + +typedef void (*RET_FUNC)(int, void *); + +int main(int argc, char **argv) +{ + int r; + r = f(); + printf("%d\n", r); +} + +//void z(RET_FUNC ret, void *fp) +__code z(RET_FUNC ret, void *fp) +{ + printf("z: fp=0x%x\n", __builtin_frame_address(0)); + ret(5, fp); +} +__code i(RET_FUNC ret, void *fp) +{ + printf("i: fp=0x%x\n", __builtin_frame_address(0)); + goto z(ret, fp); +} +__code h(RET_FUNC ret, void *fp) +{ + printf("h: fp=0x%x\n", __builtin_frame_address(0)); + goto i(ret, fp); +} +__code g(RET_FUNC ret, void *fp) +{ + printf("g: fp=0x%x\n", __builtin_frame_address(0)); + goto h(ret, fp); +} + +int f() +{ + __label__ exit0; + int retval; + //void (*ret)(int retval_, void *fp); + + /* + ret = ({ + void __return_func(int retval_, void *fp){ + retval = retval_; + goto exit0; + } + __return_func; + }); + */ + printf("f0: fp = 0x%x\n", __builtin_frame_address(0)); + void __return_func(int retval_, void *fp){ + retval = retval_; + goto exit0; + } + //ret = __return_func; + + printf("f1: fp = 0x%x\n", __builtin_frame_address(0)); + + //g(__return_func, __builtin_frame_address(0)); + goto g(__return_func, __builtin_frame_address(0)); + + printf("bad\n"); + +exit0: + printf("f2: fp = 0x%x\n", __builtin_frame_address(0)); + return retval; +} + + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_func2code.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_func2code.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,43 @@ +#include +#include + +#define DEBUG 1 +#ifdef DEBUG + #define log(f, args...) \ + fprintf(stderr, "in %s: "f, __FUNCTION__, ## args) +#else + #define log(f, args...) ; +#endif + +__code +exitter(int a) +{ + exit(0); +} + +__code +cs0(int x, int y) +{ + log("x = %d, y = %d.\n", x, y); + log("will exit with code %d.\n", x*y); + goto exitter(x*y); +} + +void +continuation(int a) +{ + log("go code segment cs0\n"); + goto cs0(a, a*20); + log("Error: continuation reachs bad region.\n"); +} + +int +main(int argc, char **argv) +{ + int a; + if (argc>2) { + a = atoi(argv[1]); + } + + continuation(20); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_nest.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_nest.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,50 @@ + +int printf(char *, ...); +typedef void (*RET_FUNC)(int, void *); + +void g(RET_FUNC func) +{ + func(33, 0); +} + +int f() +{ + void *ret; + ret = ({ + __label__ exit0; + int retval; + void __return_func(int retval_, void *fp){ + retval = retval_; + goto exit0; + } + if (0) { + exit0: + printf("f2: fp = 0x%x\n", __builtin_frame_address(0)); + return retval; + } + __return_func; + }); + + //g(__return_func, __builtin_frame_address(0)); + printf("f0: fp = 0x%x\n", __builtin_frame_address(0)); + printf("__return_func = %x\n", ret); + g(ret); + + printf("not good\n"); + return 0; + +//exit0: + //printf("f2: fp = 0x%x\n", __builtin_frame_address(0)); + //return retval; +} + +int main(int argc, char **argv) +{ + int t; + printf("main before: fp = 0x%x\n", __builtin_frame_address(0)); + t = f(); + printf("f = %d\n", t); + printf("main after: fp = 0x%x\n", __builtin_frame_address(0)); +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_para.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,26 @@ +#include +#include + +__code cs_exit(int a){ + printf("cs_exit was called: a=%d.\n", a); + exit(a); +} + +__code cs0(int a, double b, int c, int d){ + printf("cs0 was called: a=%d, b=%lf, c=%d, d=%d.\n", a, b, c, d); + goto cs_exit( (int)(20*a + 4.4*b + 2022/c + 28*d) ); +} + + +__code cs_goto(){ + goto cs0(11, 22.2, 33, 44); +} + +int main(int argc, char **argv){ + + printf("it is in main.\n"); + goto cs_goto(); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_para2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para2.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,40 @@ +#include +#include + +__code cs_end(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); +} + +__code cs0(int a, int b, int c, int d); + +__code cs_goto(int a, int b, int c, int d){ + //printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs_goto : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + //printf("cs_goto : a-4=%d, a-8=%d, a-12=%d, a-16=%d.\n", *(&a-4), *(&a-8), *(&a-12), *(&a-16)); + //printf("cs_goto : cs0(a, b, c, d)\n"); + goto cs0(b, c, d, a); +} + +__code cs0(int a, int b, int c, int d){ + //printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs_cs0 : a=%d, b=%d, c=%d, d=%d.\n", a, b, c, d); + goto cs_end( (int)(20*a + 30*b + 40*c + 50*d) ); +} + + +int function(double a, float b, int c){ + + //printf("function:\n"); + //printf("a=%lf, b=%f, c=%d\n", a, b, c); + //goto cs_goto(10, 20, 30, 40); + goto cs_goto(10, 20, 30, 40); +} + +int main(int argc, char **argv){ + + function(10.01, 20.02, 30); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_para3.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para3.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,83 @@ +#include +#include + +struct abc { + int a; + double b; + char c; + double *d; +}; + +struct def { + int d; + struct abc e; + struct abc *f; +}; + +void print_abc(struct abc a){ + printf("\tstruct abc:\n"); + printf("\ta=%d, b=%lf, c=%d, d=%p\n", a.a, a.b, a.c, a.d); +} +void print_def(struct def b){ + printf("\tstruct def:\n"); + printf("\td=%d, f=%p\n", b.d, b.f); + print_abc(b.e); +} + +__code cs_exit(int a){ + printf("cs_exit : a=%d.\n", a); + exit(a); +} + +__code cs0(struct abc a, struct def b, int c){ + printf("cs0 :\n"); + printf("c=%d\n", c); + print_abc(a); + print_def(b); + goto cs_exit( c*a.a+b.e.c ); +} + + +__code cs_goto(int c, struct abc a, struct def b){ + printf("cs_goto :\n"); + printf("c=%d\n", c); + print_abc(a); + print_def(b); + goto cs0(a, b, c); +} + +int function(){ + struct abc A; + struct def B; + A.a = 10, A.b = 20.02, A.c = '\0', A.d = 0xad; + B.d = 30, B.f = 0xbf; + B.e.a = 50, B.e.b = 60.06, B.e.c = '\1', B.e.d = 0xed; + + printf("function :\n"); + print_abc(A); + print_def(B); + //printf("20*%d + 30*%d + 40*%d + 50*%d =\n", a, b, c, d); + goto cs_goto(100, A, B); + return 0; +} + +int main(int argc, char **argv){ + struct abc A; + struct def B; + //int a=10, b=20, c=30, d=40, e=50, f=60, g=70; + A.a = 10, A.b = 20.02, A.c = '\0', A.d = 0xad; + B.d = 30, B.f = 0xbf; + B.e.a = 50, B.e.b = 60.06, B.e.c = '\1', B.e.d = 0xed; + + /* + printf("main :\n"); + print_abc(A); + print_def(B); + //printf("20*%d + 30*%d + 40*%d + 50*%d =\n", a, b, c, d); + goto cs_goto(100, A, B); + */ + function(); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_para4.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_para4.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,74 @@ +//#include +//#include + +#define DPRINT 1 +#define NOINLINE __attribute__((noinline)) + +extern __code cs_goto(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2); +extern __code cs0(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2); + +__code (*csp)(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2); + +__code NOINLINE cs_exit(int a){ + int b = 20 * a + 3; + printf("cs_exit : a=%d. b=%d\n", a, b); + exit(a); +} + +__code NOINLINE cs0(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2){ +#if DPRINT + //printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d.\n", a, b, c, d, e, f, g); + printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("cs0 : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); +#endif + goto cs_exit( (int)(10*a + 10*b + 10*i2 + 10*j2) ); +} + +__code NOINLINE cs_goto(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int a2, int b2, int c2, int d2, int e2, int f2, int g2, int h2, int i2, int j2){ +#if DPRINT + printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("cs_goto : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); +#endif + goto cs0(b, c, d, e, f, g, h, i, j, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, a); +} + +int function(double l, float m, int n){ + int a=10, b=20, c=30, d=40, e=50, f=60, g=70, h=80, i=90, j=100; + int a2=110, b2=120, c2=130, d2=140, e2=150, f2=160, g2=170, h2=180, i2=190, j2=200; + +#if DPRINT + printf("function: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("function: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); + //printf("l=%lf, m=%f, n=%d\n", l, m, n); +#endif + //goto cs_goto(10, 20, 30, 40); + goto cs_goto(a, b, c, d, e, f, g, h, i, j, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); +} + + +int main(int argc, char **argv){ + + //printf("main :\n"); + /* + printf("main : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a, b, c, d, e, f, g, h, i, j); + printf("main : a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n", + a2, b2, c2, d2, e2, f2, g2, h2, i2, j2); + */ + //csp = cs0; + function(10.01, 20.02, 30); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_return.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_return.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,89 @@ +#include + +#if 0 +typedef float testtype; +testtype good = 33.3f; +testtype bad = 0.0f; +void print_testtype(testtype t) +{ + printf("return value = %2.3f good=%2.3f,bad=%2.3f\n", t,good,bad); +} +#elif 1 +typedef char testtype; +testtype good = 33; +testtype bad = 0; +void print_testtype(testtype t) +{ + printf("return value = %d, good=%d,bad=%d\n", t,good,bad); +} +#elif 0 +typedef double testtype; +testtype good = 333.3; +testtype bad = 0.00; +void print_testtype(testtype t) +{ + printf("return value = %3.3lf, good=%3.3lf,bad=%3.3lf\n", t,good,bad); +} +#elif 0 +typedef +struct { + int a; + float b; + int c[4]; +} testtype; +testtype good = {33, 33.3, {4,4,4,4}}; +testtype bad = {0, 00.0, {0,0,0,0}}; +void print_testtype(testtype t) +{ + printf( "return value = {\n" + " a = %d\n" + " b = %2.3f\n" + " c = { %d, %d, %d, %d }" + "}\n", t.a, t.b, + t.c[0],t.c[1],t.c[2],t.c[3]); +} +#else +typedef int testtype; +testtype good = 33; +testtype bad = 0; +void print_testtype(testtype t) +{ + printf("return value = %d, good=%d,bad=%d\n", t,good,bad); +} +#endif + +typedef void (*RET_FUNC)(testtype, void *); + +void g(RET_FUNC func) +{ + func(good, NULL); +} + +testtype f_cbc() +{ + //__label__ _cbc_exit0; + //int retval; + void *ret; + + ret = _CbC_return; + + printf("f0: fp = %p\n", __builtin_frame_address(0)); + printf("__return_func = %p\n", ret); + g(ret); + + printf("not good\n"); + return bad; +//_cbc_exit0: + //printf("f1: fp = 0x%x\n", __builtin_frame_address(0)); + //return retval; +} + +int main(int argc, char **argv) +{ + testtype t; + printf("main before: fp = %p\n", __builtin_frame_address(0)); + t = f_cbc(); + print_testtype(t); + printf("main after: fp = %p\n", __builtin_frame_address(0)); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_struct.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_struct.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,31 @@ + +struct aaa{ + int a; // 4 + char b; // 1 + int c; // 4 + double d; // 8 + char e[10]; //10 +}; //27 --> 32 + +int main(int argc, char **argv){ + struct aaa A; + A.a = 10; + A.b = 'A'; + A.c = 20; + A.d = 1.11; + A.e[0] = 'A', A.e[1] = 'Z'; + + printf("sizeof aaa = %d\n", sizeof(struct aaa)); + tset01( A, 10); + return 0; +} + +void tset01( struct aaa B, int size){ + printf("B.a = %d\n", B.a); + printf("B.b = %d\n", B.b); + printf("B.c = %d\n", B.c); + printf("B.d = %lf\n", B.d); + B.e[9] = '\0'; + printf("B.e = %s\n", B.e); + printf("size = %d\n", size); +} diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_tailcall1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_tailcall1.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,28 @@ +#include + + +void B(int a, int b, int c){ + printf("B: a=%d, b=%d, c=%d\n", a, b, c); + return ; +} + +void* freturn(){ + return B; +} +void A(int a, int b, int c, int d){ + void (*fp)(int, int, int); + fp = freturn(); + + printf("A: a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); + return fp(a, b, c+d); + //return B(a, b, c+d); +} + +int main(int argc, char **argv){ + printf("main: \n"); + //fp = B; + A(10, 20, 30, 40); + return 0; +} + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-examples/test_tree.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/test_tree.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,54 @@ +//#include +double test(char, char, int, double); +__code cs(int , double , char ); +void testvoid(double a); +int testint(double a); + +__code cs(int a, double b, char c){ + printf("__code cs was called.\n"); + printf("a = %d, b = %lf, c = %d\n", a, b, c); + exit(0); +} +__code cs1(int a, double b, char c, int d){ + printf("__code cs1 was called.\n"); + printf("a = %d, b = %lf, c = %d, d = %d\n", a, b, c, d); + exit(0); +} + +int main(int argc, char **argv){ + double t; + //goto cs(2, 10.2, 2); + + t = test('a', 'b', 10, 2.5); + printf("t = %lf\n", t); + testvoid(2.22); + testint(2.22); + + printf("test_goto\n"); + goto test_goto1(10, 20, 30.3); + return 0; +} +void test0(){ + exit(0); +} + +void testvoid(double a){ + return ; +} +int testint(double a){ + int b; + b = (a*100-a) +2; + return 1; +} + +double test(char c, char l, int a, double d){ + return (double)a*d+c+l; +} + +void test_goto(int a, int b, double c){ + goto cs(2, 10.2, 3); +} +__code test_goto1(int a, int b, double c){ + goto cs1(2, 10.2, 3, 4); +} + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-implemantation.ja --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-implemantation.ja Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,207 @@ + + + GCC への CbC コンパイル機能の実装について + + +___________________________________________________________ + Code Segmentの実装 +----------------------------------------------------------- + +Code SegmentをC言語に組み込む。 +コンパイラとしては単なるvoidの関数として扱い、parse treeにcode +segmentであることのフラグを追加する。 + + * 予約語''__code``の追加 + c-common.cで定義されているc_common_reswords配列に追加 + { "__code", RID_CbC_CODE, 0} # D_CONLYも入れるか? + + * treeの生成関数 + 関数の型を表すtreeはbuild_funciton_type関数で生成されるが、code + segmentではこれを使えない。build_function_typeはhash管理でまったく同 + じ引数型、返り値型を持つものは同じオブジェクトを使うから。 + なのでbuild_code_segment_typeでこの代わりを行う。 + # 本当はbuild_function_typeのhashにcbcフラグも含める方がいいかもし + # れない。 + この関数は主にgrokdeclaratorから呼ばれる + + * cbc_set_codesegment関数 + Undocumented. + でも今は意味なかったような… + + + +___________________________________________________________ + goto文の実装 +----------------------------------------------------------- + +CbCについて重要な構文''goto cs(a, b, c);``を実装する。 +c-parser.c内の c_parser_statement_after_labels()関数における巨大なスイ +ッチ文のcase RID_GOTOのコードを修正する。 + + * アイデア + 全てのgoto文を単なる関数呼び出しとその後のリターン文と解釈することで + tail callを可能にする。 + 次のgoto文は + goto cs(a); + このparse treeでもこの様に解釈される + cs(a); + return; + + * Parser側での修正 + + オリジナルC言語のパース方法 + 1. gotoに続くトークンがCPP_NAME + 通常のgoto文として処理 + 2. gotoに続くトークンが'*` + computed gotoとして処理 + see "GCC Manual" Sec 6.3. (not internals Manual) + これを以下の様に変更する + + CbCでのパース方法 + 1. gotoに続くトークンがCPP_NAME && CPP_NAMEに次ぐトークンが';` + 通常のgoto文として処理 + 2. gotoに続くトークンが'*` + computed gotoとして処理 + 3. それ以外 + CbCのgotoとして処理 + + 処理内容 + 1. gotoトークンに続く文を関数呼び出しとみて + c_parser_expr_no_commas()関数を使ってパース、treeを取得 + # これで(*csp)(a)などにも対応できる + 2. 取得したtreeがCALL_EXPRでなければエラー + 3. treeにCbC_GOTOのフラグを立てる + 4. treeにTAILCALLのフラグを立てる + 5. add_stmt + 6. return文のtreeを生成 + + * RTL expansion + + 通常のCALL_EXPRを解析するexpand_callを一部修正する。この関数の途中か + らでexpand_cbc_goto関数に切り替えてRTLの生成はそこで全てを請け負う。 + 本来expand_callではtreeにsibcallフラグが立っていても、生成の過程で不 + 可能と検知するとsibcallを中断して通常のcallになるが、cbc_expand_call + では無理やりsibcallにする。 + + expand_callでの修正内容 + Undocumented. + expand_cbc_gotoの処理内容 + Undocumented. + +___________________________________________________________ + goto文における並列代入の実装 Nov 26, 2009 +----------------------------------------------------------- + +c-parser.c: c_parser_statement_after_labels()における goto文のパースの +段階で全ての引数を一時変数に代入する形に変更する。 +もちろんこれだけで並列代入ができる分けではないが、おそらくGCCの最適化 +機構でできると考える。 + + 1. c_parser_expr_no_commasでCALL_EXPRを取得 + 2. 全ての引数に対して一時変数を作成 + 3. それぞれを代入 + 4. CALL_EXPRの引数を一時変数に置き換え + 2-4の処理をcbc_replace_argumentsで行う。 + + + +___________________________________________________________ + return擬似変数の実装 +----------------------------------------------------------- + +___________________________________________________________ + environmentの実装 +----------------------------------------------------------- + + + + + + + + + + + + + + + + + +___________________________________________ + * goto文における並列代入実装について考える +------------------------------------------- + +Nov 26, 2009 +c-parser.c: c_parser_statement_after_labels()における goto文のパースの +段階で全ての引数を一時変数に代入する形に変更する。 +もちろんこれだけで並列代入ができる分けではないが、おそらくGCCの最適化 +機構でできると考える。 + + 1. c_parser_expr_no_commasでCALL_EXPRを取得 + 2. 全ての引数に対して一時変数を作成 build_decl? + 名前なしでできるか? + 3. それぞれを代入 + 4. CALL_EXPRの引数を一時変数に置き換え + 5. expand_callでの実装を元に戻す? + 現状のままでも動きはするはず +引数のタイプ + 関数 + o ADDR_EXPR + o PARM_DECL, VAR_DECL, + other + o *_EXPR + o PARM_DECL, VAR_DECL, + +実装の準備 + o CALL_EXPRから引数リストを取得 + DECL_ARGUMENTS(fundecl) + tree args = DECL_ARGUMENTS (fndecl); + for (; args; args = TREE_CHAIN (args)) + { + tree type = TREE_TYPE (args); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + DECL_ARG_TYPE (args) = integer_type_node; + } + o 名前なしの変数作成 + var = build_decl(VAR_DECL, NULL_TREE, TYPE); + DECL_ARTIFICIAL (val) = 1; + o 代入文 + build_modify_expr (loc, TO_EXPR, NOP_EXPR, FROM_EXPR) + o Constantなら一時変数いらない + もしくはcallerの引数と同じ場合にのみ一時変数を使うか + o CALL_EXPRは取得後に引数を変えても大丈夫なのか? + o expand_callでのstore_one_arg, check_sibcall_argument_overlapの動作 + +実装に邪魔ないくつかの関数の解析 + o mem_overlaps_already_clobbered_arg_p(addr, size) + 指定したメモリ[addr,addr+size]範囲がすでに前の引数格納によって上書 + きされていないかをチェックする。 + 引数範囲を1byte毎にbitmapの1bitに表し、上書きされた場所は1がセット + されている。それにかぶるとNG. + また、addrが動的(esp+eaxなど)ならNG. + o sotre_one_args() +この実装ではexpand_cbc_gotoをいじらない事にした + + + + * DEBUG手法 + + gccコマンドではなくcc1コマンドに対してgdbを起動 + $ ls + GCC/ build-test/ test/ + $ cd test + $ gdb ../build-test/gcc/cc1 + + treeの表示 + (gdb) p browse_tree (exp) <== expはtree構造体 + + rtxの表示 + (gdb) p debug_rtx (exp) <== expはrtx構造体 + + browse_treeはtree, debug_rtxはrtxをconfigureの + --enable-checkingで指定している必要がある + + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-memo.ja --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-memo.ja Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,888 @@ +GCC + + + + +[[configureオプションの追加]] +$ cd gcc +$ vi configure.ac + ... +$ autoheader-2.59 # versionはconfigure.acの中に書いてある奴に合わせる +$ autoconf-2.59 +$ vi Makefile.in +これでconfigureスクリプトが完成するが、このautoconfはtarボールでは成功しない +svnリポジトリからチェックアウトしないと必要な関数が定義されてないのでエラーになる +なのでチェックアウトしたものでconfigureを生成したあと、それだけコピーしてこればOK +TOPディレクトリでは +$ autogen Makefile.def +$ autoconf-2.59 +ただしこれを使うことはないと思われる? + + +[[fastcall i386]] +1: %ecx +2: %edx +3: (%esp) +4: 4(%esp) +5: 8(%esp) + +__attribute__((noreturn)): 今のところこれでは問題が出ない +__attribute__((fastcall)): こっちはいろいろ問題あり + + +fastcallで起こる問題: +せっかく計算したebpが上書きされてしまっている +ecxに退避してそこにjmpすれば動く (これを直にかける?) +expand_cbc_gotoを直す必要がある +08048714 : +8048714: 53 push %ebx +8048715: 83 ec 28 sub $0x28,%esp +8048718: 89 4c 24 0c mov %ecx,0xc(%esp) +804871c: 8b 44 24 0c mov 0xc(%esp),%eax +8048720: 89 44 24 1c mov %eax,0x1c(%esp) +8048724: 8b 44 24 1c mov 0x1c(%esp),%eax +8048728: 8b 00 mov (%eax),%eax +804872a: 01 44 24 0c add %eax,0xc(%esp) +804872e: 8b 44 24 1c mov 0x1c(%esp),%eax +8048732: 8b 58 08 mov 0x8(%eax),%ebx +8048735: 8b 44 24 1c mov 0x1c(%esp),%eax +8048739: 8b 40 04 mov 0x4(%eax),%eax +804873c: 8b 54 24 0c mov 0xc(%esp),%edx +8048740: 89 c1 mov %eax,%ecx +8048742: 83 c4 28 add $0x28,%esp +8048745: 5b pop %ebx +8048746: ff e3 jmp *%ebx +これを手動で直すと-O0でも-O2でも動くことが確認できた + + + + + +**PROJECT CVS** +firefly.cr:~one/CVS_DB/CbC_Project/GCC + +-checkout + cvs co CbC_project/GCC +-commit + cvs commit +-import from 3rdparty source + tar xzvf gcc-xxx.tgz + cd gcc-xxx + cvs import -ko -m ".." CbC/project/GCC FSF_GCC REL_4_x_y +-merge + cd /temp + cvs checkout -jREL_4_2_1 -jREL_xxx CbC_project/GCC + もしくはすでに本流をcheckoutしているディレクトリで + cvs update -jREL_4_2_1 -jREL_4_2_2 でもできる? (4_2_2に移行時はこれをしたけど...まだ分かんない ) + cvs update -jREL_4_2_2 -jREL_4_2_3 + + +コンパイル時に実行されるプログラムは主に3つ +省略すると +cc1, as, collect2 +/usr/libexec/gcc/i386/redhat-linux/4.1.1/cc1 test.c -o test.s +as -o test.o test.s +/usr/libexec/gcc/i386/redhat/linux/4.1.1/collect2 ..... test.o + +cc1とcollect2は +gcc-core-4.2.0/gcc/内でコンパイルされるもの。 +必要なのはcc1だ。 + + + +CbCの実装 + tail callを使う。 + +tail call +関数の末尾呼び出しを最適化して、callでなくjmpで関数に飛ぶようになる。 +gcc -O1 -foptimize-sibling-calls か +gcc -O2 でコンパイルすればこの最適化が行われる。 + +最適化条件? (構造体未確認) +(推測!!) + 返り値が同じ + 呼ばれる関数の引数サイズが呼び出し側関数の引数サイズより小さい + +expand_gimple_basic_blockでstatement毎にRTLに変換されているが、 +ほとんどのstmtはexpand_expr_stmtに送られるけど、 +tail call の場合は expand_gimple_tailcallに直接送られる + + +**TEST BUILD** +mkdir build-test +cd build-test +../GCC/configure --disable-nls --disable-bootstrap --enable-languages=c --prefix=$PWD/installed --enable-checking=tree,rtl,assert +デバグのため、下の(a)を実行 +make +make install # これまでしないと処理系によってはerrorがいくつか... + +(a). 全てのMakefileの-O2 を -O0 に変更 viで :%s/-O2/-O0/gってとこか? + どうやら --prefix=...って、ちゃんとしないといけない? + stdio.hをインクルードしてるとエラーが出る。 + これはオレが失敗したのか?それともconfigureが悪いのか? + +$ CFLAGS="-O0 -gdwarf-2 -g3" ../GCC/configure ... + + +stdio.hをインクルードしたらerrorが出る問題 +firefly: --prefix=$PWD/USR-LOCALあり、別ディレクトリ + preinstall: NG postinstall: OK installed: OK +firefly: --prefixなし、別ディレクトリ + preinstall: NG postinstall: ?? +firefly: --prefixあり、同ディレクトリ + preinstall: NG postinstall: OK installed: OK +firefly(nativePkg): --prefixなし、別ディレクトリ + preinstall: NG + +chani: --prefix=$PWD/installedあり、同ディレクトリ + preinstall: OK +chani(nativePkg): --prefixなし、別ディレクトリ + preinstall: OK + + + +$PWD/installed/bin/gcc -O2 .... +$PWD/installed/libexec/gcc/i686-pc-linux-gnu/4.2.1/cc1 -O2 test01.c +browse_tree (tree) +debug_rtx(rtl) + + + +**GCC DEBUG** +gdb $BUILD-TEST/installed/libexec/gcc/i686-pc-linux-gnu/4.2.1/cc1 +プログラム内で +p browse_tree (current_function_decl) + + + + + +cc1 +main.c, toplev.c, + +main() in main.c + +toplev_main() in toplev.c + general_init(argv[0]) + signal設定 + init_gcc() + decode_options(argc, argv) + randomize() + do_compile() in toplev.c + timevar_start(TV_TOTAL) + process_options() + compile_file() + +struct lang_hooks lang_hooks +この構造体にパーサ等の関数ポインタが含まれている。 +これはlanghooks-def.hでLANG_HOOKS_INITIALIZERが定義されているが、 +言語ごとの定義はcならc-objc-common.hで、各メンバの定義が入れ替えられる。 + +options +decode_options -O?などのオプションを処理 + handle_options その他のオプションを順番に走査 + コンパイル対象のファイル名を main_input_filenameに入れる + -で始まる引数があればhandle_optionを呼ぶ + handle_option オプションを処理する + + +compile_file() + lang_hooks.parse_file() == c_common_parse_file + c_parse_file() in c-parser.c Parse a single source file. + c_parser_translation_unit() in c-parser.c + c_parser_external_declaration() + + +c_parser_external_declaration() in c-parser.c +CPPのtokenはここで処理して通常のはc_parser_declaration_or_fndefに渡す + +全体を通して、c_parser *parserという変数が関数の第一引数に渡される。 +これがファイルをparseする際の状態を保持しているっぽい + +c_parser_declaration_or_fndef() +こいつがglobalな関数、変数の宣言を処理する。 + c_parser_declspecs() 基本type (int, char, strcut...) + declspecs_add_scspec(specs, tree) extern,inline,staticなどのstorageをspecsにおさめる(specsのフラグをたてる) + declspecs_add_type(specs, c_typespec t) int, char, longなど第2引数が型名、第1引数にそれを格納 + finish_declspecs() Complexやunsignedなどの後に来る型名の処理? + shadow_tag(specs) 名前無しのstructやunionを処理。 + c_parser_declarator() 名前の前の*の処理 + c_parser_direct_declarator() idを取得 + c_parser_direct_declarator_inner() idの後の[]や()をパース + c_parser_parms_declarator() 引数リストもしくはidリスト(これはoldSTYLEのため) + c_parser_parms_list_declarator() + c_parser_parameter_declaration() + 通常の変数なら + start_decl() + start_init() c_parser_initializer() finish_init() + finish_decl() + + 関数パラメータ + start_function() 関数のdeclaration treeを作成する + treeはcurrent_function_declに保存 + old-styleパラメータ(while c_parser_declaration_or_fndef(parser, f, f, t, f) + fnbody = c_parser_compound_statement(parser) 関数本体の定義 + add_stmt(fnbody) fnbodyを専用のstatement listに追加する gimplifyに使われる? + finish_function() + current_function_declからfndeclを取得 + ...(fndecl) = pop_stmt_list(....(fndecl)) statement listからbodyを取得しfndeclにつなげる + c_genericize(fndecl) convert LD-tree to LI-tree + c_gimple_diagnostics_recursively(fndecl) + cgraph_finalize_function(fndecl,false) ファイルにアセンブラを出力? + cgraph_assemble_pending_functions() in cgraphunit.c + +関数とcode segment +code segmentはパース中の型はcts_CbC_codeとしてdeclspecsに保持している +finish_declspecsにおいて、treeを構成する際に型をvoid_type_nodeで格納 +このvoid_typeになんらかのフラグをつける?それともfunction_typeにつける? + + + +IDの取得 +c_parser_declarator() 名前の前の*の処理 + c_parser_direct_declarator() id or (.id)をパース + c_parser_direct_declarator_inner() idの後の[]や()をパース fnTreeを生成 + c_parser_parms_declarator() 型なしidリスト(これはoldSTYLEのため) + c_parser_parms_list_declarator() 型付き引数リストのパース 可変長かもみる + c_parser_parameter_declaration() + build_function_declarator() パースした引数とdelcで関数の宣言をつくる + c_declarator->u.arg_infoに引数を保持 + + +**expand_* treeをパースしてRTLを出力する +tree_expand_cfg() + expand_used_vars() + expand_function_start(current_function_decl) + cfunの値を設定して行く + assign_parms() + ここでcfun->args_sizeが設定されている + expand_gimple_basic_block() in for-loop + expand_expr_stmt() in stmt.c + expand_expr() in expr.h + expand_expr_real() expr.c + expand_expr_real_1() + +expand_expr_real_1() expr.c:8210 + expand_mult() expmed.c + expand_binop() optabs.c + GEN_FCN (icode) (temp, xop0, xop1); + 下の感じのRTLが返される + (set (reg:DF 67) (mult:DF (reg:DF 66) (reg/v:DF 64 [ d ]))) + が、この関数が返すのは (reg:DF 67)だけ + emit_insn(rtx) + RTLをDL-listに追加する. rtxはinsnでなければinsnでラッピングされる + + +**PASS LIST** +関数ごとに出力する場合、 +cgraph_assemble_pending_functions() flag_unit_at_a_timeが真なら実行 + cgraph_expand_function() + tree_rest_of_compilation + execute_pass_list + +まとめて出力する場合 +compile_file + lang_hooks.decls.final_write_globals = c_write_global_declarations flag_unit_at_a_timeが偽なら実行 + cgraph_optimize + cgraph_expand_all_functions + cgraph_expand_function + +GIMPLE treeから RTL への変換 +pass.execute = tree_expand_cfg() + +RTLからアセンブラへの変換pass final.cで定義 +pass_final.execute == rest_of_handle_final in final.c + + +最終的な RTL=>"文字列" 変換する pass +execute_one_pass() + rest_of_handle_final() + assemble_start_function() + final_start_function() + final() # insnリストを出力 + final_scan_insn() # 与えられたinsnのアセンブラを出力 + recog_memoized() # insn_data[code]のcode 決定 + get_insn_template() # 出力するアセンブラのchar*文字列を返す + output_asm_insn() # 文字列の%..を修正してファイルに出力 + final_end_function() + assemble_end_function() + +RTLの仮想レジスタを物理レジスタに置き換える pass +execute_one_pass() + instantiate_virtual_regs() + instantiate_virtual_regs_in_insn() for each instruction + extract_insn() + recog_memoized() + insn_extract() +ppcではこのrecog_memoizedで-1しか返ってこないことで落ちる + +下のmdのmatch_operand 0がaddressにしか対応してないのが問題だと思う +;; sibling call patterns +(define_expand "sibcall" + [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (use (reg:SI LR_REGNO)) + (return)])] + "" + " + { + #if TARGET_MACHO + if (MACHOPIC_INDIRECT) + operands[0] = machopic_indirect_call_target (operands[0]); + #endif + + gcc_assert (GET_CODE (operands[0]) == MEM); + gcc_assert (GET_CODE (operands[1]) == CONST_INT); + + operands[0] = XEXP (operands[0], 0); + }") + + +targetm.asm_outから出力 +ターゲットマシンによってtargetm構造体の内容が変わる。 + + + +/* In all nodes that are expressions, this is the data type of the expression. + In POINTER_TYPE nodes, this is the type that the pointer points to. + In ARRAY_TYPE nodes, this is the type of the elements. + In VECTOR_TYPE nodes, this is the type of the elements. */ +#define TREE_TYPE(NODE) ((NODE)->common.type) // in tree.h +このnodeの型を表す(functionなら関数の型、pointerならそいつのさしている型.. + +/* The tree-code says what kind of node it is. + Codes are defined in tree.def. */ +#define TREE_CODE(NODE) ((enum tree_code) (NODE)->common.code) // in tree.h +このnodeがどんなtreeなのかを表す + + + +c_parser_compound_statement() + c_begin_compound_stmt() + c_parser_compund_statement_nostart() __label__, lvarの処理 + c_parser_statement_after_labels() + c_end_compound_stmt() + +c_parser_if_statement() +c_parser_do_statement() + +c_parser_paren_condition() ifやwhileの'()'の中をparseする + + +parse expressions + +c_parser_unary_expression() increment,decrement, &, *ポインタ、アドレスの処理 +c_parser_postfix_expression() 数字や変数、文字列などの処理(TCCのunary()か) +c_parser_postfix_expression_after_primary() 変数とかの後ろの'[]'や'()'の処理(関数や配列の添字) + + +c_parser_* Cのパーサ +build_* treeの生成 (Cパーサから呼ばれる) +expand_* tree(gimple)のパーサ +emit_* rtlの生成 (treeパーサから呼ばれる) + + + + +宣言時の新しい識別子 +token->type==CPP_NAME +build_id_declarator + XOBNEWを使って parser_obstackに作られる => gcc_obstack_init in default.h +変数名等を格納するc_declaratorはparser_obstack上に作られ、 + + +tree.def +tree.[ch] + +union tree_node GTY((ptr_alias (union lang_tree_node), + desc ("tree_node_structure (&%h)"))) +{ + struct tree_common GTY ((tag ("IS_COMMON"))) common; + struct tree_int_cst GTY ((tag ("IS_INT_CST"))) common; + struct tree_real_cst GTY ((tag ("IS_REAL_CST"))) common; + .. + .. +}; +c-tree.h: +struct c_expr{ + tree value; + enum tree_code original_code; +} + + +tokenizer + +c_parser_peek_token() int c-parser.c 現在参照すべきtoken を返す + c_lex_one_token() in c-parser.c + c_lex_with_flags() in c-lex.c + cpp_get_token() in libcpp(macro.c) +c_parser_next_token_is( parser, token0) tokenを取得し、それがtoken0ならtrue +c_parser_consume_token( parser) 次のtokenを取ってくる + +parser->tokens[0,1] (c_token) +この[0]に現在のtokenの情報がある。 +[1]はnext? +新たなtokenはlibcppのcpp_get_tokenによって取得する。 + +cppでは'!'や'*'などの一つ一つのtokenとなんらかの文字列を返す +予約語等の処理はgccがやる. +token +struct c_token{ + enum cpp_ttype type: 8; /* libcppで得られるtokenのtype, '<','==', name, '['などなど */ + enum c_id_kind id_kind: 8; /* type==CPP=NAMEの時のみ */ + enum rid keyword: 8; /* Cの予約語(int, if, typedef, gotoなど) */ + pragma_kind: 7; + in_systemheader: 1; + tree value; + location_t location; +} +enum cpp_ttype in libcpp/include/cpplib.h +{ + TTYPE_TABLE ==>> CPP_EQ, CPP_NOT, ... , CPP_NAME, ..., CPP_PADDING, + N_TTYPES, + + /* Positions in the table. */ + CPP_LAST_EQ = CPP_LSHIFT, + CPP_FIRST_DIGRAPH = CPP_HASH, + CPP_LAST_PUNCTUATOR= CPP_ATSIGN, + CPP_LAST_CPP_OP = CPP_LESS_EQ +}; +本来予約語もCPP_NAMEに含まれるが、無理矢理CPP_KEYWORDを作っている +CPP_KEYWORDはc-parser.cで独自に定義、N_TTYPES+1 +typedef enum c_id_kind { + C_ID_ID, /* An ordinary identifier. */ + C_ID_TYPENAME, /* An identifier declared as a typedef name. */ + C_ID_CLASSNAME, /* An identifier declared as an Objective-C class name. */ + C_ID_NONE /* Not an identifier. */ +} c_id_kind; + + +enum c_declarator_kind { /* in c-tree.h */ + cdk_id, /* An identifier. */ + cdk_function, /* A function. */ + cdk_array, /* An array. */ + cdk_pointer, /* A pointer. */ + cdk_attrs /* Parenthesized declarator with nested attributes. */ +}; +struct c_declarator { /* in c-tree.h */ + enum c_declarator_kind kind; /* The kind of declarator. */ + struct c_declarator *declarator; /* Except for cdk_id, the contained declarator. For cdk_id, NULL. */ + location_t id_loc; /* Currently only set for cdk_id. */ + union { + tree id; /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract declarator. */ + struct c_arg_info *arg_info; /* For functions. */ + struct { /* For arrays. */ + tree dimen; /* The array dimension, or NULL for [] and [*]. */ + int quals; /* The qualifiers inside []. */ + tree attrs; /* The attributes (currently ignored) inside []. */ + BOOL_BITFIELD static_p : 1; /* Whether [static] was used. */ + BOOL_BITFIELD vla_unspec_p : 1; /* Whether [*] was used. */ + } array; + int pointer_quals; /* For pointers, the qualifiers on the pointer type. */ + tree attrs; /* For attributes. */ + } u; +}; + +/* A type specifier keyword "void", "_Bool", "char", "int", "float", + "double", or none of these. */ +enum c_typespec_keyword { //でも使われてるのはdeclspec + cts_none, + cts_void, + cts_CbC_code, いる? + cts_bool, + cts_char, + cts_int, + cts_float, + cts_double, + cts_dfloat32, + cts_dfloat64, + cts_dfloat128 +}; +enum c_typespec_kind { + ctsk_resword, + ctsk_tagref, + ctsk_tagfirstref, + /* A definition of a tag such as "struct foo { int a; }". */ + ctsk_tagdef, + ctsk_typedef, + ctsk_objc, + ctsk_typeof +}; +struct c_typespec { + enum c_typespec_kind kind; + tree spec; +}; +struct c_declspecs { /* c-tree.c */ + /* The type specified, if a single type specifier such as a struct, + union or enum specifier, typedef name or typeof specifies the + whole type, or NULL_TREE if none or a keyword such as "void" or + "char" is used. Does not include qualifiers. */ + tree type; + /* The attributes from a typedef decl. */ + tree decl_attr; + /* When parsing, the attributes. Outside the parser, this will be + NULL; attributes (possibly from multiple lists) will be passed + separately. */ + tree attrs; + /* Any type specifier keyword used such as "int", not reflecting + modifiers such as "short", or cts_none if none. */ + enum c_typespec_keyword typespec_word; + /* The storage class specifier, or csc_none if none. */ + enum c_storage_class storage_class; + BOOL_BITFIELD declspecs_seen_p : 1; + BOOL_BITFIELD type_seen_p : 1; + BOOL_BITFIELD typedef_p : 1; + BOOL_BITFIELD default_int_p; + BOOL_BITFIELD long_p : 1; + BOOL_BITFIELD long_long_p : 1; + BOOL_BITFIELD short_p : 1; + BOOL_BITFIELD signed_p : 1; + : +} + + + + +**TAIL CALL OPTIMIZATION** +execute_tail_calls in tree-tailcall.c + tree_optimize_tail_calls_1(true) + たいした調査もせず、簡単にフラグCALL_EXPR_TAILCALLをたててるだけ。 + +expand_call 1834-3115 in calls.c + initialize_argument_information(); + 引数処理 + 引数をレジスタやスタックのどこに保存するかを決める + tree actparmsで示された引数をargs, args_sizeに格納する + 1011行目 We can't use sibcalls if a callee-copied argument is stored in the current function's frame. + if statement 2200行目: try_tail_call=0 + targetm.function_ok?for?sibcall(fndecl, exp) + args_size.constant > (current_function_args_size - current_function_pretend_args_size) + emit_call_1(); + SIBLING_CALL_P(..) = ( (ecf_flag & ECF_SIBLING) != 0); + +expand_callでtailcall可能かどうかの判定を詳しく行っているようだ +bool try_tail_call = CALL_EXPR_TAILCALL(exp); +2252あたりのfor文が怪しいが、900行ある。 + +2252 in calls.c +for(pass = try_tail_call ? 0:1; pass<2; pass++) 2253-3087 +2回ループ。 +1回目はtailcall用。 +2回目は普通のcalling +生成後にどちらかを選ぶ? +2227 args_size.constant > (current_function_args_size - current_function_pretend_args_size) + + hard_function_value + check_sibcall_argument_overlap + prepare_call_address + load_register_parameters + + + +Language Dependent Tree + v +GENERIC + v +GIMPLE + +GENERIC trees + LD trees + v +GIMPLE + + +**RTL** +RTL expression + クラス: RTX_OBJ, RTX_CONST_OBJ, _COMPARE _COMM_COMPARE _UNARY ... in rtx.def + オペランド: e(expression), i(integer), w, s, E, ... + +RTLへのアクセス +GET_CODE (RTX) (enum rtx_code) (RTX)->code + RTXのコード(種類)を返す +GET_RTX_CLASS (code) + このrtxコードのクラスを返す +GET_RTX_LENGTH (code) + このrtxコードのオペランドの数を返す +GET_RTX_FORMAT (code) + オペランドの種類を文字列で返す + i.e. "iuuBieieee" on CALL_INSN +XEXP(RTX, N) X->u.fld[N].rt_rtx + RTX のN番目のオペランドをexpressionとして取得する +XINT(RTX, N) X->u.fld[N].rt_int + RTX のN番目のオペランドをintegerとして取得する +XVEC(RTX, N) X->u.fld[N].rt_rtvec + RTX のN番目のオペランドをrtvectorとして取得する + XVECEXP(RTX, N, M) XVEC(RTX,N)->elem[M] + RTX のN番目のオペランドをrtvectorとし、その M番目の要素を返す + XVECLEN(RTX, N) XVEC(RTX,N)->num_elem + RTX のN番目のオペランドをrtvectorとし、そのサイズを返す + +struct rtvec_def GTY(()) { + int num_elem; /* number of elements */ + rtx GTY ((length ("%h.num_elem"))) elem[1]; +}; + + +typedef struct trx_def *rtx; //gcc/coretypes.h +struct rtx_def; //gcc/rtl.h +struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), + chain_prev ("RTX_PREV (&%h)"))) +{ + /* The kind of expression this is. */ + ENUM_BITFIELD(rtx_code) code: 16; + + /* The kind of value the expression has. */ + ENUM_BITFIELD(machine_mode) mode : 8; + + /* 1 in a MEM if we should keep the alias set for this mem unchanged + when we access a component. + 1 in a CALL_INSN if it is a sibling call. + 1 in a SET that is for a return. + In a CODE_LABEL, part of the two-bit alternate entry field. */ + unsigned int jump : 1; + /* In a CODE_LABEL, part of the two-bit alternate entry field. + 1 in a MEM if it cannot trap. */ + unsigned int call : 1; + /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere. + 1 in a SUBREG if it references an unsigned object whose mode has been + from a promoted to a wider mode. + 1 in a SYMBOL_REF if it addresses something in the per-function + constants pool. + 1 in a CALL_INSN, NOTE, or EXPR_LIST for a const or pure call. + 1 in a JUMP_INSN, CALL_INSN, or INSN of an annulling branch. */ + unsigned int unchanging : 1; + /* 1 in a MEM or ASM_OPERANDS expression if the memory reference is volatile. + 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL, BARRIER, or NOTE + if it has been deleted. + 1 in a REG expression if corresponds to a variable declared by the user, + 0 for an internally generated temporary. + 1 in a SUBREG with a negative value. + 1 in a LABEL_REF or in a REG_LABEL note for a non-local label. + In a SYMBOL_REF, this flag is used for machine-specific purposes. */ + unsigned int volatil : 1; + /* 1 in a MEM referring to a field of an aggregate. + 0 if the MEM was a variable or the result of a * operator in C; + 1 if it was the result of a . or -> operator (on a struct) in C. + 1 in a REG if the register is used only in exit code a loop. + 1 in a SUBREG expression if was generated from a variable with a + promoted mode. + 1 in a CODE_LABEL if the label is used for nonlocal gotos + and must not be deleted even if its count is zero. + 1 in an INSN, JUMP_INSN or CALL_INSN if this insn must be scheduled + together with the preceding insn. Valid only within sched. + 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and + from the target of a branch. Valid from reorg until end of compilation; + cleared before used. */ + unsigned int in_struct : 1; + /* At the end of RTL generation, 1 if this rtx is used. This is used for + copying shared structure. See `unshare_all_rtl'. + In a REG, this is not needed for that purpose, and used instead + in `leaf_renumber_regs_insn'. + 1 in a SYMBOL_REF, means that emit_library_call + has used it as the function. */ + unsigned int used : 1; + /* 1 in an INSN or a SET if this rtx is related to the call frame, + either changing how we compute the frame address or saving and + restoring registers in the prologue and epilogue. + 1 in a REG or MEM if it is a pointer. + 1 in a SYMBOL_REF if it addresses something in the per-function + constant string pool. */ + unsigned frame_related : 1; + /* 1 in a REG or PARALLEL that is the current function's return value. + 1 in a MEM if it refers to a scalar. + 1 in a SYMBOL_REF for a weak symbol. */ + unsigned return_val : 1; + + /* The first element of the operands of this rtx. + The number of operands and their types are controlled + by the `code' field, according to rtl.def. */ + union u { + rtunion fld[1]; + HOST_WIDE_INT hwint[1]; + struct block_symbol block_sym; + struct real_value rv; + } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; +}; + + +FUNCTION_TYPEの実態はtree_type +make_node_stat(FUNCTION_TYPE)で作成される + TREE_TYPE + TYPE_ARG_TYPES ->type.values + TYPE_UID ->type.uid + TYPE_ALIGN ->type.align + TYPE_USER_ALIGN ->type.user_align + TYPE_MAIN_VARIANT ->type.main_variant + TYPE_ATTRIBUTES ->type.attributes + +こいつの lang_flag_6 ビットフィールドをcode segmentかどうかのフラグとする。 +#define TYPE_LANG_FLAG_5(NODE) (TYPE_CHECK (NODE)->type.lang_flag_5) //tree.h +#define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 (TYPE) //c-tree.h +code segmentを作ったらCbC_IS_CODE_SEGMENT(type) = 1 でセット できる? + + + + + + +**GENERIC TREE** +関数の型 + + unit size + align 64 symtab 0 alias set -1 precision 64 + pointer_to_this > + QI + size constant invariant 8> + unit size constant invariant 1> + align 8 symtab 0 alias set -1 + arg-types > + +関数の引数 + + unit size + align 32 .... + chain > + +配列 + + BLK + size constant invariant 320> + unit size constant invariant 40> + align 32 symtab 0 alias set -1 + domain unit size + align 32 symtab 0 alias set -1 precision 32 min max > + SI size unit size + align 32 symtab 0 alias set -1 precision 32 min max >> + +関数呼び出し + + side-effects arg 0 + unsigned SI + size + unit size + align 32 symtab 0 alias set -1> + constant invariant + arg 0 + addressable used public external decl_5 QI defer-output file test_tree.c line 2>> + arg 1 + chain + chain + chain + constant invariant 2.5e+0>>>>>> + + +build_function_call(tree fndecl, tree exprlist) +FUNCTION_DECLとEXPRのリストからCALL_EXPRを作って返す + +convert_arguments(arglist, params, function, fundecl); +check_function_arguments(); + + +配列の作り方 +icst : INTEGER_CST +itype: INTEGER_TYPE + +icst = build_int_cst (NULL_TREE, size-1); +itype = build_index_type (icst); +array = build_array_type + +//build_range_type(size_type, integer_zero_node, exp) + + + +**PPC** +http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/ASMIntroduction/chapter_1_section_1.html +http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html#//apple_ref/doc/uid/TP40002438-SW17 +http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html +http://www.freescale.co.jp/pdf/MPCFPE32BJ_R1a.pdf +http://www.nk.rim.or.jp/~jun/ppcasm/ppcasm01.html + + + + + +**ソースコード読み会 準備** +cd ~/public_html +mkdir gcc; cd gcc +checkout CbC_project/GCC; CbC_project/GCC +./configure --... +make +gtags +htags -Ffx -t 'GCC source tour' +cd ../../ +tar -czv CbC_project --exclude **/CVS -f GCC-source-....tar.gz + + + +normal tail call +(call_insn/j 24 23 0 (parallel [ + (call (mem:SI (symbol_ref:SI ("cs0") [flags 0x403] ) [0 S4 A8]) + (const_int 256 [0x100])) + (use (const_int 0 [0x0])) + (use (reg:SI 125)) + (return) + ]) -1 (nil) + (expr_list:REG_EH_REGION (const_int 0 [0x0]) + (nil)) + (expr_list:REG_DEP_TRUE (use (reg:SI 6 r6)) + (expr_list:REG_DEP_TRUE (use (reg:SI 5 r5)) + (expr_list:REG_DEP_TRUE (use (reg:SI 4 r4)) + (expr_list:REG_DEP_TRUE (use (reg:SI 3 r3)) + (nil)))))) + +indirect tail call +(call_insn/j 25 24 0 (parallel [ + (call (mem:SI (reg/f:SI 129) [0 S4 A8]) + (const_int 256 [0x100])) + (use (const_int 0 [0x0])) + (use (reg:SI 130)) + (return) + ]) -1 (nil) + (nil) + (expr_list:REG_DEP_TRUE (use (reg:SI 6 r6)) + (expr_list:REG_DEP_TRUE (use (reg:SI 5 r5)) + (expr_list:REG_DEP_TRUE (use (reg:SI 4 r4)) + (expr_list:REG_DEP_TRUE (use (reg:SI 3 r3)) + (nil)))))) + + + +CFLAGS='-O0 -gdwarf-2 -g3' ../GCC/configure --disable-nls --disable-bootstrap --enable-languages=c --prefix=$PWD/INSTALL-DIR --enable-checking=tree,rtl,assert --disable-shared --disable-threads --with-headers --with-system-zlib --with-newlib --enable-version-specific-runtime-libs --disable-libssp --target=spu + +../toolchain/gcc/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --disable-shared --disable-threads --disable-checking --with-headers --with-system-zlib --with-newlib --enable-languages=c,c++,fortran --disable-nls --enable-version-specific-runtime-libs --disable-libssp --program-prefix=spu- --target=spu + + + + +$ cvs checkout CbC_project/GCC +$ mkdir tmp; cd tmp +$ wget http://www.bsc.es/projects/deepcomputing/linuxoncell/cellsimulator/sdk3.0/SRPMS/spu-gcc-4.1.1-107.src.rpm +$ rpm2cpio spu-gcc--4.1.1-107.src.rpm | cpio -i -v +$ tar xjvf gcc-r886.tar.bz2 +$ cat *.diff | patch -d ../CbC_project/GCC -p2 +$ cp toolchain/gcc/config.sub ../CbC_project/GCC/ +$ cp toolchain/gcc/gcc/config.gcc ../CbC_project/GCC/gcc/ +$ cd ../CbC_project/GCC +$ + + +change bit_merge to vec_merge in gcc/config/spu/spu.md +split0_completed; in recog.c, rtl.h, final.c +SPU_FLOAT_FORMAT +: diff -r 561a7518be6b -r 1b10fe6932e1 CbC-scripts/make_headers.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-scripts/make_headers.py Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,124 @@ +#!/usr/bin/env python3.0 + + +import sys +import re +import getopt + +reserved_words = [ "if", "for", "switch", "return", "while", "else", ] + +PATTERN = "([a-zA-Z_][\w\s]*\**)\s([a-zA-Z_]\w*)\s*\(([^{/;]*)\)\s*\{" +# TODO: 関数パラメータ内にコメントがあると正しく動かない! +# TODO: int * const * とか大丈夫? +PROG = re.compile(PATTERN, re.S) + +omit_static=False +add_extern="" + +def truncate_comments(data): + pass + +def check_reserved_word(decl): + """ return true if decl's type and name is not reserved word. """ + + if decl["name"] in reserved_words or decl["type"] in reserved_words: + return False + return True + +def read_decls(file): + declarators = [] + + # open the file and read all lines into a string. + try: + fo = open(file, 'r') + lines = fo.readlines() + data = "".join(lines) + truncate_comments(data) + except IOError: + print("cannot read file %s" % file) + return None + + # find all matched strings. + # moiter is iterator of MatchObject. + moiter = PROG.finditer(data) + for mo in moiter: + tmp = { "type": mo.group(1), + "name": mo.group(2), + "parms": mo.group(3), + "offset": mo.start() } + if check_reserved_word(tmp): + declarators.append(tmp) + + return declarators + +def debug_print(decl): + for (key,value) in list(decl.items()): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print("Type:\t{0:s}".format(decl["type"])) + print("Name:\t{0:s}".format(decl["name"])) + print("Params:\t{0:s}".format(decl["parms"])) + print("offset:\t{0:d}".format(decl["offset"])) + print("") + +def format_print(decl, file): + for (key,value) in list(decl.items()): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print("/* defined in file {0:s} at offset {1:d} */".format(file,decl["offset"])) + print("{3:s}{0:s} {1:s} ({2:s});".format(decl["type"],decl["name"],decl["parms"], add_extern)) + print("") + +def getoptions(): + global omit_static, add_extern + + try: + opts, args = getopt.getopt(sys.argv[1:], 'se', [ 'omit-static', 'add-extern' ]) + except getopt.GetoptError as err: + print(err) + usage() + sys.exit(2) + + for opt,a in opts: + if opt in ("-s", "--omit-static"): + omit_static=True + elif opt in ("-e", "--add-extern"): + add_extern="extern " + else: + print("unhandled option {0}".format(opt)) + usage() + + return args + +def usage(): + print( """\ +Usage: {0:s} OPION... [FILE]... +OPTIONS: + -s, --omit-static omit static functions + -e, --add-extern add extern to all function declarations + """.format(sys.argv[0])) + +def main(): + + # option handling. + args = getoptions() + + for file in args: + # read function declaration from each file. + decls = read_decls(file) + if decls==None or len(decls)==0: + # no function found. + print("{0} have no function definition!".format(file)) + continue + + for decl in decls: + if omit_static and 0 <= decl["type"].find("static"): + # static function is ignored. + continue + #debug_print(decl) + format_print(decl, file) + +main() + diff -r 561a7518be6b -r 1b10fe6932e1 CbC-scripts/make_headers.py2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-scripts/make_headers.py2 Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import re +import getopt + +reserved_words = [ "if", "for", "switch", "return", "while", "else", ] + +PATTERN = r"([a-zA-Z_][\w\s]*\**)\s([a-zA-Z_]\w*)\s*\(([^\{/;]*)\)\s*\{" +#PATTERN = r"([a-zA-Z_]\w*)\s+([a-zA-Z_]\w*)\s*\(([^;]*)\)\s*\{" +#PATTERN = r"((?:[a-zA-Z_]\w*)\s+)+?([a-zA-Z_]\w*)\s*\(([^;]*)\)\s*\{" +# TODO: 関数パラメータ内にコメントがあると正しく動かない! +PROG = re.compile(PATTERN, re.S) + +omit_static=False +add_extern="" + +def truncate_comments(data): + pass + +def check_reserved_word(decl): + """ return true if decl's type and name is not reserved word. """ + + if decl["name"] in reserved_words or decl["type"] in reserved_words: + return False + return True + +def read_decls(file): + declarators = [] + + # open the file and read all lines into a string. + try: + fo = open(file, 'r') + lines = fo.readlines() + data = "".join(lines) + truncate_comments(data) + except IOError: + print "cannot read file %s" % file + return None + + # find all matched strings. + # moiter is iterator of MatchObject. + moiter = PROG.finditer(data) + for mo in moiter: + tmp = { "type": mo.group(1), + "name": mo.group(2), + "parms": mo.group(3), + "offset": mo.start() } + if check_reserved_word(tmp): + declarators.append(tmp) + + return declarators + +def debug_print(decl): + for (key,value) in decl.items(): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print "Type:\t%s" % decl["type"] + print "Name:\t%s" % decl["name"] + print "Params:\t%s" % decl["parms"] + print "offset:\t%d" % decl["offset"] + print "" + #s = "%s %s ( %s );" % (decl["type"], decl["name"], decl["parms"]) + #print s, "/* offset: %d */" % decl["offset"] + +def format_print(decl, file): + for (key,value) in decl.items(): + if isinstance(value, str): + decl[key] = value.replace("\n"," ").replace("\t"," ") + + print "/* defined in file %s at offset %d */" % (file,decl["offset"]) + print "%s%s %s (%s);" % (add_extern, decl["type"],decl["name"],decl["parms"]) + print "" + +def getoptions(): + global omit_static, add_extern + + try: + opts, args = getopt.getopt(sys.argv[1:], 'se', [ 'omit-static', 'add-extern' ]) + except getopt.GetoptError: + print(err) + usage() + sys.exit(2) + + for opt,a in opts: + if opt in ("-s", "--omit-static"): + omit_static=True + elif opt in ("-e", "--add-extern"): + add_extern="extern " + else: + print("unhandled option {0}".format(opt)) + usage() + + return args + +def usage(): + print( """\ +Usage: {0:s} OPION... [FILE]... +OPTIONS: + -s, --omit-static omit static functions + -e, --add-extern add extern to all function declarations + """.format(sys.argv[0])) + +def main(): + # option handling. + args = getoptions() + + for file in args: + # read function declaration from each file. + decls = read_decls(file) + if decls==None or len(decls)==0: + # no function found. + print "%s have no function definition!" % file + continue + + for decl in decls: + if omit_static and 0 <= decl["type"].find("static"): + # static function is ignored. + continue + #debug_print(decl) + format_print(decl, file) + +main() + diff -r 561a7518be6b -r 1b10fe6932e1 configure diff -r 561a7518be6b -r 1b10fe6932e1 gcc/ChangeLog.CbC --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/ChangeLog.CbC Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,69 @@ +2009-08-20 Shinji KONO + + どうも、goto hoge(0),env; で、env を渡すのがよろしくない。 + goto hoge(0,env); + と言う形にして、hoge 側で env を設定するのはどうか? + + __code main_return2_1(int i,stack sp) { + goto (( (struct main_continuation *)sp)->main_ret)(0), + ((struct main_continuation *)sp)->env; + } + + を、 + + __code main_return2_1(int i,stack sp) { + goto (( (struct main_continuation *)sp)->main_ret)(0, + ((struct main_continuation *)sp)->env); + } + という形にする。 + + そうすれば、goto 文は、かなり簡単になる。 + +2009-08-20 Shinji KONO + +以下のようにすれば良いらしい... いっそ #define でも出来るが。 + + extern int printf(const char *, ...); + + void g( void (*ret)(int retval_,void *f) , void *fp) { + printf("g: fp = 0x%x\n",__builtin_frame_address(0)); + (*ret)(5,fp); + } + + int f() + { + + int retval = 1; + void (*ret)(int retval_,void *fp) ; + + ret = ({ + __label__ exit0; + volatile static flag = 0; + void __return_func(int retval_,void *fp) { + retval = retval_; + goto exit0; + } + if (flag) { + exit0: + printf("f1: fp = 0x%x\n",__builtin_frame_address(0)); + return retval; + } + __return_func; + }); + + printf("f0: fp = 0x%x\n",__builtin_frame_address(0)); + + g(ret,__builtin_frame_address(0)); + + printf("bad\n"); + + return retval; + } + + + int + main() + { + printf("%d\n",f()); + } + diff -r 561a7518be6b -r 1b10fe6932e1 gcc/Makefile.in diff -r 561a7518be6b -r 1b10fe6932e1 gcc/aclocal.m4 diff -r 561a7518be6b -r 1b10fe6932e1 gcc/c-decl.c --- a/gcc/c-decl.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/c-decl.c Sun Aug 21 07:53:12 2011 +0900 @@ -58,16 +58,23 @@ #include "hashtab.h" #include "langhooks-def.h" #include "pointer-set.h" +#include "gimple.h" +#ifndef noCbC +#include "cbc-tree.h" +tree cbc_env; +tree cbc_return_f; +location_t cbc_return; +#endif #include "plugin.h" #include "c-family/c-ada-spec.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context -{ NORMAL, /* Ordinary declaration */ - FUNCDEF, /* Function definition */ - PARM, /* Declaration of parm before function body */ - FIELD, /* Declaration inside struct or union */ - TYPENAME}; /* Typename (inside cast or sizeof) */ +{ NORMAL, /* Ordinary declaration */ + FUNCDEF, /* Function definition */ + PARM, /* Declaration of parm before function body */ + FIELD, /* Declaration inside struct or union */ + TYPENAME}; /* Typename (inside cast or sizeof) */ /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)). An object declared as @@ -189,20 +196,20 @@ invisible bit true. */ struct GTY((chain_next ("%h.prev"))) c_binding { - union GTY(()) { /* first so GTY desc can use decl */ + union GTY(()) { /* first so GTY desc can use decl */ tree GTY((tag ("0"))) type; /* the type in this scope */ struct c_label_vars * GTY((tag ("1"))) label; /* for warnings */ } GTY((desc ("TREE_CODE (%0.decl) == LABEL_DECL"))) u; - tree decl; /* the decl bound */ - tree id; /* the identifier it's bound to */ - struct c_binding *prev; /* the previous decl in this scope */ - struct c_binding *shadowed; /* the innermost decl shadowed by this one */ + tree decl; /* the decl bound */ + tree id; /* the identifier it's bound to */ + struct c_binding *prev; /* the previous decl in this scope */ + struct c_binding *shadowed; /* the innermost decl shadowed by this one */ unsigned int depth : 28; /* depth of this scope */ BOOL_BITFIELD invisible : 1; /* normal lookup should ignore this binding */ BOOL_BITFIELD nested : 1; /* do not set DECL_CONTEXT when popping */ BOOL_BITFIELD inner_comp : 1; /* incomplete array completed in inner scope */ - BOOL_BITFIELD in_struct : 1; /* currently defined as struct field */ - location_t locus; /* location for nested bindings */ + BOOL_BITFIELD in_struct : 1; /* currently defined as struct field */ + location_t locus; /* location for nested bindings */ }; #define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth) #define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth) @@ -245,7 +252,7 @@ chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))"))) lang_tree_node { union tree_node GTY ((tag ("0"), - desc ("tree_node_structure (&%h)"))) + desc ("tree_node_structure (&%h)"))) generic; struct lang_identifier GTY ((tag ("1"))) identifier; }; @@ -441,25 +448,25 @@ static GTY((deletable)) struct c_binding *binding_freelist; /* Append VAR to LIST in scope SCOPE. */ -#define SCOPE_LIST_APPEND(scope, list, decl) do { \ - struct c_scope *s_ = (scope); \ - tree d_ = (decl); \ - if (s_->list##_last) \ - BLOCK_CHAIN (s_->list##_last) = d_; \ - else \ - s_->list = d_; \ - s_->list##_last = d_; \ +#define SCOPE_LIST_APPEND(scope, list, decl) do { \ + struct c_scope *s_ = (scope); \ + tree d_ = (decl); \ + if (s_->list##_last) \ + BLOCK_CHAIN (s_->list##_last) = d_; \ + else \ + s_->list = d_; \ + s_->list##_last = d_; \ } while (0) /* Concatenate FROM in scope FSCOPE onto TO in scope TSCOPE. */ -#define SCOPE_LIST_CONCAT(tscope, to, fscope, from) do { \ - struct c_scope *t_ = (tscope); \ - struct c_scope *f_ = (fscope); \ - if (t_->to##_last) \ - BLOCK_CHAIN (t_->to##_last) = f_->from; \ - else \ - t_->to = f_->from; \ - t_->to##_last = f_->from##_last; \ +#define SCOPE_LIST_CONCAT(tscope, to, fscope, from) do { \ + struct c_scope *t_ = (tscope); \ + struct c_scope *f_ = (fscope); \ + if (t_->to##_last) \ + BLOCK_CHAIN (t_->to##_last) = f_->from; \ + else \ + t_->to = f_->from; \ + t_->to##_last = f_->from##_last; \ } while (0) /* A c_inline_static structure stores details of a static identifier @@ -530,9 +537,9 @@ static tree lookup_name_in_scope (tree, struct c_scope *); static tree c_make_fname_decl (location_t, tree, int); static tree grokdeclarator (const struct c_declarator *, - struct c_declspecs *, - enum decl_context, bool, tree *, tree *, tree *, - bool *, enum deprecated_states); + struct c_declspecs *, + enum decl_context, bool, tree *, tree *, tree *, + bool *, enum deprecated_states); static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); @@ -548,7 +555,7 @@ if (CAN_HAVE_LOCATION_P (t) && code != LABEL_EXPR) { if (!EXPR_HAS_LOCATION (t)) - SET_EXPR_LOCATION (t, input_location); + SET_EXPR_LOCATION (t, input_location); } if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) @@ -598,7 +605,7 @@ tree rid = ridpointers[C_RID_CODE (node)]; indent_to (file, indent + 4); fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"", - (void *) rid, IDENTIFIER_POINTER (rid)); + (void *) rid, IDENTIFIER_POINTER (rid)); } } @@ -687,12 +694,12 @@ labels, and add the LABEL_VARS value. */ static void bind_label (tree name, tree label, struct c_scope *scope, - struct c_label_vars *label_vars) + struct c_label_vars *label_vars) { struct c_binding *b; bind (name, label, scope, /*invisible=*/false, /*nested=*/false, - UNKNOWN_LOCATION); + UNKNOWN_LOCATION); scope->has_label_bindings = true; @@ -712,17 +719,17 @@ { tree type = TREE_TYPE (decl); if (type != error_mark_node - && TREE_CODE (type) == ARRAY_TYPE - && !DECL_EXTERNAL (decl) - && TYPE_DOMAIN (type) == 0) - { - warning_at (DECL_SOURCE_LOCATION (decl), - 0, "array %q+D assumed to have one element", decl); - - complete_array_type (&TREE_TYPE (decl), NULL_TREE, true); - - layout_decl (decl, 0); - } + && TREE_CODE (type) == ARRAY_TYPE + && !DECL_EXTERNAL (decl) + && TYPE_DOMAIN (type) == 0) + { + warning_at (DECL_SOURCE_LOCATION (decl), + 0, "array %q+D assumed to have one element", decl); + + complete_array_type (&TREE_TYPE (decl), NULL_TREE, true); + + layout_decl (decl, 0); + } } } @@ -732,7 +739,7 @@ void record_inline_static (location_t loc, tree func, tree decl, - enum c_inline_static_type type) + enum c_inline_static_type type) { struct c_inline_static *csi = ggc_alloc_c_inline_static (); csi->location = loc; @@ -754,21 +761,21 @@ for (csi = c_inline_statics; csi; csi = csi->next) { if (DECL_EXTERNAL (csi->function)) - switch (csi->type) - { - case csi_internal: - pedwarn (csi->location, 0, - "%qD is static but used in inline function %qD " - "which is not static", csi->static_decl, csi->function); - break; - case csi_modifiable: - pedwarn (csi->location, 0, - "%q+D is static but declared in inline function %qD " - "which is not static", csi->static_decl, csi->function); - break; - default: - gcc_unreachable (); - } + switch (csi->type) + { + case csi_internal: + pedwarn (csi->location, 0, + "%qD is static but used in inline function %qD " + "which is not static", csi->static_decl, csi->function); + break; + case csi_modifiable: + pedwarn (csi->location, 0, + "%q+D is static but declared in inline function %qD " + "which is not static", csi->static_decl, csi->function); + break; + default: + gcc_unreachable (); + } } c_inline_statics = NULL; } @@ -802,8 +809,8 @@ if (p->scope != scope) { /* This label or goto is defined in some other scope, or it is a - label which is not yet defined. There is nothing to - update. */ + label which is not yet defined. There is nothing to + update. */ return false; } @@ -837,11 +844,11 @@ scope = scope->outer) { for (b = scope->bindings; b; b = b->prev) - objc_volatilize_decl (b->decl); + objc_volatilize_decl (b->decl); /* Do not climb up past the current function. */ if (scope->function_body) - break; + break; } } @@ -851,8 +858,8 @@ global_bindings_p (void) { return (current_scope == file_scope && !c_override_global_bindings_to_false - ? -1 - : 0); + ? -1 + : 0); } void @@ -899,15 +906,15 @@ if (next_is_function_body) { /* This is the transition from the parameters to the top level - of the function body. These are the same scope - (C99 6.2.1p4,6) so we do not push another scope structure. - next_is_function_body is set only by store_parm_decls, which - in turn is called when and only when we are about to - encounter the opening curly brace for the function body. - - The outermost block of a function always gets a BLOCK node, - because the debugging output routines expect that each - function has at least one BLOCK. */ + of the function body. These are the same scope + (C99 6.2.1p4,6) so we do not push another scope structure. + next_is_function_body is set only by store_parm_decls, which + in turn is called when and only when we are about to + encounter the opening curly brace for the function body. + + The outermost block of a function always gets a BLOCK node, + because the debugging output routines expect that each + function has at least one BLOCK. */ current_scope->parm_flag = false; current_scope->function_body = true; current_scope->keep = true; @@ -919,39 +926,39 @@ /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ if (current_scope->outer) - current_scope->float_const_decimal64 - = current_scope->outer->float_const_decimal64; + current_scope->float_const_decimal64 + = current_scope->outer->float_const_decimal64; else - current_scope->float_const_decimal64 = false; + current_scope->float_const_decimal64 = false; } else { struct c_scope *scope; if (scope_freelist) - { - scope = scope_freelist; - scope_freelist = scope->outer; - } + { + scope = scope_freelist; + scope_freelist = scope->outer; + } else - scope = ggc_alloc_cleared_c_scope (); + scope = ggc_alloc_cleared_c_scope (); /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ if (current_scope) - scope->float_const_decimal64 = current_scope->float_const_decimal64; + scope->float_const_decimal64 = current_scope->float_const_decimal64; else - scope->float_const_decimal64 = false; + scope->float_const_decimal64 = false; scope->keep = keep_next_level_flag; scope->outer = current_scope; - scope->depth = current_scope ? (current_scope->depth + 1) : 0; + scope->depth = current_scope ? (current_scope->depth + 1) : 0; /* Check for scope depth overflow. Unlikely (2^28 == 268,435,456) but - possible. */ + possible. */ if (current_scope && scope->depth == 0) - { - scope->depth--; - sorry ("GCC supports only %u nested scopes", scope->depth); - } + { + scope->depth--; + sorry ("GCC supports only %u nested scopes", scope->depth); + } current_scope = scope; keep_next_level_flag = false; @@ -1020,7 +1027,7 @@ /* Don't search beyond the current function. */ if (s == current_function_scope) - break; + break; s = s->outer; } @@ -1064,7 +1071,7 @@ /* In each subblock, record that this is its superior. */ for (p = scope->blocks; p; p = BLOCK_CHAIN (p)) - BLOCK_SUPERCONTEXT (p) = block; + BLOCK_SUPERCONTEXT (p) = block; BLOCK_VARS (block) = 0; } @@ -1107,7 +1114,6 @@ } else warn_for_unused_label (p); - /* Labels go in BLOCK_VARS. */ DECL_CHAIN (p) = BLOCK_VARS (block); BLOCK_VARS (block) = p; @@ -1206,6 +1212,7 @@ DECL_EXTERNAL decl for debug info generation. */ tree extp = copy_node (p); + DECL_EXTERNAL (extp) = 1; TREE_STATIC (extp) = 0; TREE_PUBLIC (extp) = 1; @@ -1234,6 +1241,7 @@ set_type_context (TREE_TYPE (p), context); } + /* Fall through. */ /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have already been put there by store_parm_decls. Unused- @@ -1268,12 +1276,12 @@ else if (scope->outer) { if (block) - SCOPE_LIST_APPEND (scope->outer, blocks, block); + SCOPE_LIST_APPEND (scope->outer, blocks, block); /* If we did not make a block for the scope just exited, any - blocks made for inner scopes must be carried forward so they - will later become subblocks of something else. */ + blocks made for inner scopes must be carried forward so they + will later become subblocks of something else. */ else if (scope->blocks) - SCOPE_LIST_CONCAT (scope->outer, blocks, scope, blocks); + SCOPE_LIST_CONCAT (scope->outer, blocks, scope, blocks); } /* Pop the current scope, and free the structure for reuse. */ @@ -1303,7 +1311,7 @@ for (decl = visible_builtins; decl; decl = DECL_CHAIN (decl)) bind (DECL_NAME (decl), decl, file_scope, - /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl)); + /*invisible=*/false, /*nested=*/true, DECL_SOURCE_LOCATION (decl)); } void @@ -1348,7 +1356,7 @@ struct c_binding *b; if (!scope->has_label_bindings) - continue; + continue; for (b = scope->bindings; b != NULL; b = b->prev) { @@ -1381,7 +1389,7 @@ struct c_binding *b; if (!scope->has_label_bindings) - continue; + continue; for (b = scope->bindings; b != NULL; b = b->prev) { @@ -1441,7 +1449,7 @@ tagged type. */ TYPE_STUB_DECL (type) = pushdecl (build_decl (loc, - TYPE_DECL, NULL_TREE, type)); + TYPE_DECL, NULL_TREE, type)); /* An approximation for now, so we can tell this is a function-scope tag. This will be updated in pop_scope. */ @@ -1452,20 +1460,20 @@ struct c_binding *b = I_SYMBOL_BINDING (name); if (b != NULL - && b->decl != NULL_TREE - && TREE_CODE (b->decl) == TYPE_DECL - && (B_IN_CURRENT_SCOPE (b) - || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) - && (TYPE_MAIN_VARIANT (TREE_TYPE (b->decl)) - != TYPE_MAIN_VARIANT (type))) - { - warning_at (loc, OPT_Wc___compat, - ("using %qD as both a typedef and a tag is " - "invalid in C++"), - b->decl); - if (b->locus != UNKNOWN_LOCATION) - inform (b->locus, "originally defined here"); - } + && b->decl != NULL_TREE + && TREE_CODE (b->decl) == TYPE_DECL + && (B_IN_CURRENT_SCOPE (b) + || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) + && (TYPE_MAIN_VARIANT (TREE_TYPE (b->decl)) + != TYPE_MAIN_VARIANT (type))) + { + warning_at (loc, OPT_Wc___compat, + ("using %qD as both a typedef and a tag is " + "invalid in C++"), + b->decl); + if (b->locus != UNKNOWN_LOCATION) + inform (b->locus, "originally defined here"); + } } } @@ -1494,12 +1502,12 @@ while (oldargs || newargs) { if (!oldargs - || !newargs - || !TREE_VALUE (oldargs) - || !TREE_VALUE (newargs) - || TYPE_MODE (TREE_VALUE (oldargs)) - != TYPE_MODE (TREE_VALUE (newargs))) - return 0; + || !newargs + || !TREE_VALUE (oldargs) + || !TREE_VALUE (newargs) + || TYPE_MODE (TREE_VALUE (oldargs)) + != TYPE_MODE (TREE_VALUE (newargs))) + return 0; oldargs = TREE_CHAIN (oldargs); newargs = TREE_CHAIN (newargs); @@ -1514,7 +1522,7 @@ diagnostics. */ static void diagnose_arglist_conflict (tree newdecl, tree olddecl, - tree newtype, tree oldtype) + tree newtype, tree oldtype) { tree t; @@ -1532,19 +1540,19 @@ tree type = TREE_VALUE (t); if (TREE_CHAIN (t) == 0 - && TYPE_MAIN_VARIANT (type) != void_type_node) - { - inform (input_location, "a parameter list with an ellipsis can%'t match " - "an empty parameter name list declaration"); - break; - } + && TYPE_MAIN_VARIANT (type) != void_type_node) + { + inform (input_location, "a parameter list with an ellipsis can%'t match " + "an empty parameter name list declaration"); + break; + } if (c_type_promotes_to (type) != type) - { - inform (input_location, "an argument type that has a default promotion can%'t match " - "an empty parameter name list declaration"); - break; - } + { + inform (input_location, "an argument type that has a default promotion can%'t match " + "an empty parameter name list declaration"); + break; + } } } @@ -1570,38 +1578,38 @@ tree newargtype = TREE_VALUE (newargs); if (oldargtype == error_mark_node || newargtype == error_mark_node) - return false; + return false; oldargtype = TYPE_MAIN_VARIANT (oldargtype); newargtype = TYPE_MAIN_VARIANT (newargtype); if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype)) - break; + break; /* Reaching the end of just one list means the two decls don't - agree on the number of arguments. */ + agree on the number of arguments. */ if (END_OF_ARGLIST (oldargtype)) - { - error ("prototype for %q+D declares more arguments " - "than previous old-style definition", newdecl); - return false; - } + { + error ("prototype for %q+D declares more arguments " + "than previous old-style definition", newdecl); + return false; + } else if (END_OF_ARGLIST (newargtype)) - { - error ("prototype for %q+D declares fewer arguments " - "than previous old-style definition", newdecl); - return false; - } + { + error ("prototype for %q+D declares fewer arguments " + "than previous old-style definition", newdecl); + return false; + } /* Type for passing arg must be consistent with that declared - for the arg. */ + for the arg. */ else if (!comptypes (oldargtype, newargtype)) - { - error ("prototype for %q+D declares argument %d" - " with incompatible type", - newdecl, i); - return false; - } + { + error ("prototype for %q+D declares argument %d" + " with incompatible type", + newdecl, i); + return false; + } oldargs = TREE_CHAIN (oldargs); newargs = TREE_CHAIN (newargs); @@ -1611,7 +1619,7 @@ /* If we get here, no errors were found, but do issue a warning for this poor-style construct. */ warning (0, "prototype for %q+D follows non-prototype definition", - newdecl); + newdecl); return true; #undef END_OF_ARGLIST } @@ -1642,7 +1650,7 @@ static bool diagnose_mismatched_decls (tree newdecl, tree olddecl, - tree *newtypep, tree *oldtypep) + tree *newtypep, tree *oldtypep) { tree newtype, oldtype; bool pedwarned = false; @@ -1650,7 +1658,7 @@ bool retval = true; #define DECL_EXTERN_INLINE(DECL) (DECL_DECLARED_INLINE_P (DECL) \ - && DECL_EXTERNAL (DECL)) + && DECL_EXTERNAL (DECL)) /* If we have error_mark_node for either decl or type, just discard the previous decl - we're in an error cascade already. */ @@ -1666,18 +1674,18 @@ if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) { if (!(TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl) - && !C_DECL_DECLARED_BUILTIN (olddecl))) - { - error ("%q+D redeclared as different kind of symbol", newdecl); - locate_old_decl (olddecl); - } + && DECL_BUILT_IN (olddecl) + && !C_DECL_DECLARED_BUILTIN (olddecl))) + { + error ("%q+D redeclared as different kind of symbol", newdecl); + locate_old_decl (olddecl); + } else if (TREE_PUBLIC (newdecl)) - warning (0, "built-in function %q+D declared as non-function", - newdecl); + warning (0, "built-in function %q+D declared as non-function", + newdecl); else - warning (OPT_Wshadow, "declaration of %q+D shadows " - "a built-in function", newdecl); + warning (OPT_Wshadow, "declaration of %q+D shadows " + "a built-in function", newdecl); return false; } @@ -1693,98 +1701,98 @@ if (!comptypes (oldtype, newtype)) { if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl)) - { - /* Accept harmless mismatch in function types. - This is for the ffs and fprintf builtins. */ - tree trytype = match_builtin_function_types (newtype, oldtype); - - if (trytype && comptypes (newtype, trytype)) - *oldtypep = oldtype = trytype; - else - { - /* If types don't match for a built-in, throw away the - built-in. No point in calling locate_old_decl here, it - won't print anything. */ - warning (0, "conflicting types for built-in function %q+D", - newdecl); - return false; - } - } + && DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl)) + { + /* Accept harmless mismatch in function types. + This is for the ffs and fprintf builtins. */ + tree trytype = match_builtin_function_types (newtype, oldtype); + + if (trytype && comptypes (newtype, trytype)) + *oldtypep = oldtype = trytype; + else + { + /* If types don't match for a built-in, throw away the + built-in. No point in calling locate_old_decl here, it + won't print anything. */ + warning (0, "conflicting types for built-in function %q+D", + newdecl); + return false; + } + } else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_IS_BUILTIN (olddecl)) - { - /* A conflicting function declaration for a predeclared - function that isn't actually built in. Objective C uses - these. The new declaration silently overrides everything - but the volatility (i.e. noreturn) indication. See also - below. FIXME: Make Objective C use normal builtins. */ - TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - return false; - } + && DECL_IS_BUILTIN (olddecl)) + { + /* A conflicting function declaration for a predeclared + function that isn't actually built in. Objective C uses + these. The new declaration silently overrides everything + but the volatility (i.e. noreturn) indication. See also + below. FIXME: Make Objective C use normal builtins. */ + TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); + return false; + } /* Permit void foo (...) to match int foo (...) if the latter is - the definition and implicit int was used. See - c-torture/compile/920625-2.c. */ + the definition and implicit int was used. See + c-torture/compile/920625-2.c. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) - && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node - && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node - && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl)) - { - pedwarned = pedwarn (input_location, 0, - "conflicting types for %q+D", newdecl); - /* Make sure we keep void as the return type. */ - TREE_TYPE (newdecl) = *newtypep = newtype = oldtype; - C_FUNCTION_IMPLICIT_INT (newdecl) = 0; - } + && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node + && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node + && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl)) + { + pedwarned = pedwarn (input_location, 0, + "conflicting types for %q+D", newdecl); + /* Make sure we keep void as the return type. */ + TREE_TYPE (newdecl) = *newtypep = newtype = oldtype; + C_FUNCTION_IMPLICIT_INT (newdecl) = 0; + } /* Permit void foo (...) to match an earlier call to foo (...) with - no declared type (thus, implicitly int). */ + no declared type (thus, implicitly int). */ else if (TREE_CODE (newdecl) == FUNCTION_DECL - && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node - && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node - && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl)) - { - pedwarned = pedwarn (input_location, 0, - "conflicting types for %q+D", newdecl); - /* Make sure we keep void as the return type. */ - TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype; - } + && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node + && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node + && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl)) + { + pedwarned = pedwarn (input_location, 0, + "conflicting types for %q+D", newdecl); + /* Make sure we keep void as the return type. */ + TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype; + } else - { - int new_quals = TYPE_QUALS (newtype); - int old_quals = TYPE_QUALS (oldtype); - - if (new_quals != old_quals) - { - addr_space_t new_addr = DECODE_QUAL_ADDR_SPACE (new_quals); - addr_space_t old_addr = DECODE_QUAL_ADDR_SPACE (old_quals); - if (new_addr != old_addr) - { - if (ADDR_SPACE_GENERIC_P (new_addr)) - error ("conflicting named address spaces (generic vs %s) " - "for %q+D", - c_addr_space_name (old_addr), newdecl); - else if (ADDR_SPACE_GENERIC_P (old_addr)) - error ("conflicting named address spaces (%s vs generic) " - "for %q+D", - c_addr_space_name (new_addr), newdecl); - else - error ("conflicting named address spaces (%s vs %s) " - "for %q+D", - c_addr_space_name (new_addr), - c_addr_space_name (old_addr), - newdecl); - } - - if (CLEAR_QUAL_ADDR_SPACE (new_quals) - != CLEAR_QUAL_ADDR_SPACE (old_quals)) - error ("conflicting type qualifiers for %q+D", newdecl); - } - else - error ("conflicting types for %q+D", newdecl); - diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype); - locate_old_decl (olddecl); - return false; - } + { + int new_quals = TYPE_QUALS (newtype); + int old_quals = TYPE_QUALS (oldtype); + + if (new_quals != old_quals) + { + addr_space_t new_addr = DECODE_QUAL_ADDR_SPACE (new_quals); + addr_space_t old_addr = DECODE_QUAL_ADDR_SPACE (old_quals); + if (new_addr != old_addr) + { + if (ADDR_SPACE_GENERIC_P (new_addr)) + error ("conflicting named address spaces (generic vs %s) " + "for %q+D", + c_addr_space_name (old_addr), newdecl); + else if (ADDR_SPACE_GENERIC_P (old_addr)) + error ("conflicting named address spaces (%s vs generic) " + "for %q+D", + c_addr_space_name (new_addr), newdecl); + else + error ("conflicting named address spaces (%s vs %s) " + "for %q+D", + c_addr_space_name (new_addr), + c_addr_space_name (old_addr), + newdecl); + } + + if (CLEAR_QUAL_ADDR_SPACE (new_quals) + != CLEAR_QUAL_ADDR_SPACE (old_quals)) + error ("conflicting type qualifiers for %q+D", newdecl); + } + else + error ("conflicting types for %q+D", newdecl); + diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype); + locate_old_decl (olddecl); + return false; + } } /* Redeclaration of a type is a constraint violation (6.7.2.3p1), @@ -1808,10 +1816,10 @@ } if (DECL_IN_SYSTEM_HEADER (newdecl) - || DECL_IN_SYSTEM_HEADER (olddecl) - || TREE_NO_WARNING (newdecl) - || TREE_NO_WARNING (olddecl)) - return true; /* Allow OLDDECL to continue in use. */ + || DECL_IN_SYSTEM_HEADER (olddecl) + || TREE_NO_WARNING (newdecl) + || TREE_NO_WARNING (olddecl)) + return true; /* Allow OLDDECL to continue in use. */ if (pedantic && !flag_isoc1x) { @@ -1844,9 +1852,9 @@ else if (TREE_CODE (newdecl) == FUNCTION_DECL) { /* If you declare a built-in function name as static, or - define the built-in with an old-style definition (so we - can't validate the argument list) the built-in definition is - overridden, but optionally warn this was a bad choice of name. */ + define the built-in with an old-style definition (so we + can't validate the argument list) the built-in definition is + overridden, but optionally warn this was a bad choice of name. */ if (DECL_BUILT_IN (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl) && (!TREE_PUBLIC (newdecl) @@ -1860,33 +1868,33 @@ } if (DECL_INITIAL (newdecl)) - { - if (DECL_INITIAL (olddecl)) - { - /* If both decls are in the same TU and the new declaration - isn't overriding an extern inline reject the new decl. - In c99, no overriding is allowed in the same translation - unit. */ - if ((!DECL_EXTERN_INLINE (olddecl) - || DECL_EXTERN_INLINE (newdecl) - || (!flag_gnu89_inline - && (!DECL_DECLARED_INLINE_P (olddecl) - || !lookup_attribute ("gnu_inline", - DECL_ATTRIBUTES (olddecl))) - && (!DECL_DECLARED_INLINE_P (newdecl) - || !lookup_attribute ("gnu_inline", - DECL_ATTRIBUTES (newdecl)))) - ) - && same_translation_unit_p (newdecl, olddecl)) - { - error ("redefinition of %q+D", newdecl); - locate_old_decl (olddecl); - return false; - } - } - } + { + if (DECL_INITIAL (olddecl)) + { + /* If both decls are in the same TU and the new declaration + isn't overriding an extern inline reject the new decl. + In c99, no overriding is allowed in the same translation + unit. */ + if ((!DECL_EXTERN_INLINE (olddecl) + || DECL_EXTERN_INLINE (newdecl) + || (!flag_gnu89_inline + && (!DECL_DECLARED_INLINE_P (olddecl) + || !lookup_attribute ("gnu_inline", + DECL_ATTRIBUTES (olddecl))) + && (!DECL_DECLARED_INLINE_P (newdecl) + || !lookup_attribute ("gnu_inline", + DECL_ATTRIBUTES (newdecl)))) + ) + && same_translation_unit_p (newdecl, olddecl)) + { + error ("redefinition of %q+D", newdecl); + locate_old_decl (olddecl); + return false; + } + } + } /* If we have a prototype after an old-style function definition, - the argument types must be checked specially. */ + the argument types must be checked specially. */ else if (DECL_INITIAL (olddecl) && !prototype_p (oldtype) && prototype_p (newtype) && TYPE_ACTUAL_ARG_TYPES (oldtype) @@ -1896,172 +1904,172 @@ return false; } /* A non-static declaration (even an "extern") followed by a - static declaration is undefined behavior per C99 6.2.2p3-5,7. - The same is true for a static forward declaration at block - scope followed by a non-static declaration/definition at file - scope. Static followed by non-static at the same scope is - not undefined behavior, and is the most convenient way to get - some effects (see e.g. what unwind-dw2-fde-glibc.c does to - the definition of _Unwind_Find_FDE in unwind-dw2-fde.c), but - we do diagnose it if -Wtraditional. */ + static declaration is undefined behavior per C99 6.2.2p3-5,7. + The same is true for a static forward declaration at block + scope followed by a non-static declaration/definition at file + scope. Static followed by non-static at the same scope is + not undefined behavior, and is the most convenient way to get + some effects (see e.g. what unwind-dw2-fde-glibc.c does to + the definition of _Unwind_Find_FDE in unwind-dw2-fde.c), but + we do diagnose it if -Wtraditional. */ if (TREE_PUBLIC (olddecl) && !TREE_PUBLIC (newdecl)) - { - /* Two exceptions to the rule. If olddecl is an extern - inline, or a predeclared function that isn't actually - built in, newdecl silently overrides olddecl. The latter - occur only in Objective C; see also above. (FIXME: Make - Objective C use normal builtins.) */ - if (!DECL_IS_BUILTIN (olddecl) - && !DECL_EXTERN_INLINE (olddecl)) - { - error ("static declaration of %q+D follows " - "non-static declaration", newdecl); - locate_old_decl (olddecl); - } - return false; - } + { + /* Two exceptions to the rule. If olddecl is an extern + inline, or a predeclared function that isn't actually + built in, newdecl silently overrides olddecl. The latter + occur only in Objective C; see also above. (FIXME: Make + Objective C use normal builtins.) */ + if (!DECL_IS_BUILTIN (olddecl) + && !DECL_EXTERN_INLINE (olddecl)) + { + error ("static declaration of %q+D follows " + "non-static declaration", newdecl); + locate_old_decl (olddecl); + } + return false; + } else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl)) - { - if (DECL_CONTEXT (olddecl)) - { - error ("non-static declaration of %q+D follows " - "static declaration", newdecl); - locate_old_decl (olddecl); - return false; - } - else if (warn_traditional) - { - warned |= warning (OPT_Wtraditional, - "non-static declaration of %q+D " - "follows static declaration", newdecl); - } - } + { + if (DECL_CONTEXT (olddecl)) + { + error ("non-static declaration of %q+D follows " + "static declaration", newdecl); + locate_old_decl (olddecl); + return false; + } + else if (warn_traditional) + { + warned |= warning (OPT_Wtraditional, + "non-static declaration of %q+D " + "follows static declaration", newdecl); + } + } /* Make sure gnu_inline attribute is either not present, or - present on all inline decls. */ + present on all inline decls. */ if (DECL_DECLARED_INLINE_P (olddecl) - && DECL_DECLARED_INLINE_P (newdecl)) - { - bool newa = lookup_attribute ("gnu_inline", - DECL_ATTRIBUTES (newdecl)) != NULL; - bool olda = lookup_attribute ("gnu_inline", - DECL_ATTRIBUTES (olddecl)) != NULL; - if (newa != olda) - { - error_at (input_location, "% attribute present on %q+D", - newa ? newdecl : olddecl); - error_at (DECL_SOURCE_LOCATION (newa ? olddecl : newdecl), - "but not here"); - } - } + && DECL_DECLARED_INLINE_P (newdecl)) + { + bool newa = lookup_attribute ("gnu_inline", + DECL_ATTRIBUTES (newdecl)) != NULL; + bool olda = lookup_attribute ("gnu_inline", + DECL_ATTRIBUTES (olddecl)) != NULL; + if (newa != olda) + { + error_at (input_location, "% attribute present on %q+D", + newa ? newdecl : olddecl); + error_at (DECL_SOURCE_LOCATION (newa ? olddecl : newdecl), + "but not here"); + } + } } else if (TREE_CODE (newdecl) == VAR_DECL) { /* Only variables can be thread-local, and all declarations must - agree on this property. */ + agree on this property. */ if (C_DECL_THREADPRIVATE_P (olddecl) && !DECL_THREAD_LOCAL_P (newdecl)) - { - /* Nothing to check. Since OLDDECL is marked threadprivate - and NEWDECL does not have a thread-local attribute, we - will merge the threadprivate attribute into NEWDECL. */ - ; - } + { + /* Nothing to check. Since OLDDECL is marked threadprivate + and NEWDECL does not have a thread-local attribute, we + will merge the threadprivate attribute into NEWDECL. */ + ; + } else if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl)) - { - if (DECL_THREAD_LOCAL_P (newdecl)) - error ("thread-local declaration of %q+D follows " - "non-thread-local declaration", newdecl); - else - error ("non-thread-local declaration of %q+D follows " - "thread-local declaration", newdecl); - - locate_old_decl (olddecl); - return false; - } + { + if (DECL_THREAD_LOCAL_P (newdecl)) + error ("thread-local declaration of %q+D follows " + "non-thread-local declaration", newdecl); + else + error ("non-thread-local declaration of %q+D follows " + "thread-local declaration", newdecl); + + locate_old_decl (olddecl); + return false; + } /* Multiple initialized definitions are not allowed (6.9p3,5). */ if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl)) - { - error ("redefinition of %q+D", newdecl); - locate_old_decl (olddecl); - return false; - } + { + error ("redefinition of %q+D", newdecl); + locate_old_decl (olddecl); + return false; + } /* Objects declared at file scope: if the first declaration had - external linkage (even if it was an external reference) the - second must have external linkage as well, or the behavior is - undefined. If the first declaration had internal linkage, then - the second must too, or else be an external reference (in which - case the composite declaration still has internal linkage). - As for function declarations, we warn about the static-then- - extern case only for -Wtraditional. See generally 6.2.2p3-5,7. */ + external linkage (even if it was an external reference) the + second must have external linkage as well, or the behavior is + undefined. If the first declaration had internal linkage, then + the second must too, or else be an external reference (in which + case the composite declaration still has internal linkage). + As for function declarations, we warn about the static-then- + extern case only for -Wtraditional. See generally 6.2.2p3-5,7. */ if (DECL_FILE_SCOPE_P (newdecl) - && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl)) - { - if (DECL_EXTERNAL (newdecl)) - { - if (!DECL_FILE_SCOPE_P (olddecl)) - { - error ("extern declaration of %q+D follows " - "declaration with no linkage", newdecl); - locate_old_decl (olddecl); - return false; - } - else if (warn_traditional) - { - warned |= warning (OPT_Wtraditional, - "non-static declaration of %q+D " - "follows static declaration", newdecl); - } - } - else - { - if (TREE_PUBLIC (newdecl)) - error ("non-static declaration of %q+D follows " - "static declaration", newdecl); - else - error ("static declaration of %q+D follows " - "non-static declaration", newdecl); - - locate_old_decl (olddecl); - return false; - } - } + && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl)) + { + if (DECL_EXTERNAL (newdecl)) + { + if (!DECL_FILE_SCOPE_P (olddecl)) + { + error ("extern declaration of %q+D follows " + "declaration with no linkage", newdecl); + locate_old_decl (olddecl); + return false; + } + else if (warn_traditional) + { + warned |= warning (OPT_Wtraditional, + "non-static declaration of %q+D " + "follows static declaration", newdecl); + } + } + else + { + if (TREE_PUBLIC (newdecl)) + error ("non-static declaration of %q+D follows " + "static declaration", newdecl); + else + error ("static declaration of %q+D follows " + "non-static declaration", newdecl); + + locate_old_decl (olddecl); + return false; + } + } /* Two objects with the same name declared at the same block - scope must both be external references (6.7p3). */ + scope must both be external references (6.7p3). */ else if (!DECL_FILE_SCOPE_P (newdecl)) - { - if (DECL_EXTERNAL (newdecl)) - { - /* Extern with initializer at block scope, which will - already have received an error. */ - } - else if (DECL_EXTERNAL (olddecl)) - { - error ("declaration of %q+D with no linkage follows " - "extern declaration", newdecl); - locate_old_decl (olddecl); - } - else - { - error ("redeclaration of %q+D with no linkage", newdecl); - locate_old_decl (olddecl); - } - - return false; - } + { + if (DECL_EXTERNAL (newdecl)) + { + /* Extern with initializer at block scope, which will + already have received an error. */ + } + else if (DECL_EXTERNAL (olddecl)) + { + error ("declaration of %q+D with no linkage follows " + "extern declaration", newdecl); + locate_old_decl (olddecl); + } + else + { + error ("redeclaration of %q+D with no linkage", newdecl); + locate_old_decl (olddecl); + } + + return false; + } /* C++ does not permit a decl to appear multiple times at file - scope. */ + scope. */ if (warn_cxx_compat - && DECL_FILE_SCOPE_P (newdecl) - && !DECL_EXTERNAL (newdecl) - && !DECL_EXTERNAL (olddecl)) - warned |= warning_at (DECL_SOURCE_LOCATION (newdecl), - OPT_Wc___compat, - ("duplicate declaration of %qD is " - "invalid in C++"), - newdecl); + && DECL_FILE_SCOPE_P (newdecl) + && !DECL_EXTERNAL (newdecl) + && !DECL_EXTERNAL (olddecl)) + warned |= warning_at (DECL_SOURCE_LOCATION (newdecl), + OPT_Wc___compat, + ("duplicate declaration of %qD is " + "invalid in C++"), + newdecl); } /* warnings */ @@ -2071,70 +2079,70 @@ && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) { warned |= warning (0, "redeclaration of %q+D with different visibility " - "(old visibility preserved)", newdecl); + "(old visibility preserved)", newdecl); } if (TREE_CODE (newdecl) == FUNCTION_DECL) { /* Diagnose inline __attribute__ ((noinline)) which is silly. */ if (DECL_DECLARED_INLINE_P (newdecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) - { - warned |= warning (OPT_Wattributes, - "inline declaration of %qD follows " - "declaration with attribute noinline", newdecl); - } + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) + { + warned |= warning (OPT_Wattributes, + "inline declaration of %qD follows " + "declaration with attribute noinline", newdecl); + } else if (DECL_DECLARED_INLINE_P (olddecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) - { - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute " - "noinline follows inline declaration ", newdecl); - } + && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) + { + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute " + "noinline follows inline declaration ", newdecl); + } } else /* PARM_DECL, VAR_DECL */ { /* Redeclaration of a parameter is a constraint violation (this is - not explicitly stated, but follows from C99 6.7p3 [no more than - one declaration of the same identifier with no linkage in the - same scope, except type tags] and 6.2.2p6 [parameters have no - linkage]). We must check for a forward parameter declaration, - indicated by TREE_ASM_WRITTEN on the old declaration - this is - an extension, the mandatory diagnostic for which is handled by - mark_forward_parm_decls. */ + not explicitly stated, but follows from C99 6.7p3 [no more than + one declaration of the same identifier with no linkage in the + same scope, except type tags] and 6.2.2p6 [parameters have no + linkage]). We must check for a forward parameter declaration, + indicated by TREE_ASM_WRITTEN on the old declaration - this is + an extension, the mandatory diagnostic for which is handled by + mark_forward_parm_decls. */ if (TREE_CODE (newdecl) == PARM_DECL - && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl))) - { - error ("redefinition of parameter %q+D", newdecl); - locate_old_decl (olddecl); - return false; - } + && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl))) + { + error ("redefinition of parameter %q+D", newdecl); + locate_old_decl (olddecl); + return false; + } } /* Optional warning for completely redundant decls. */ if (!warned && !pedwarned && warn_redundant_decls /* Don't warn about a function declaration followed by a - definition. */ + definition. */ && !(TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)) + && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)) /* Don't warn about redundant redeclarations of builtins. */ && !(TREE_CODE (newdecl) == FUNCTION_DECL - && !DECL_BUILT_IN (newdecl) - && DECL_BUILT_IN (olddecl) - && !C_DECL_DECLARED_BUILTIN (olddecl)) + && !DECL_BUILT_IN (newdecl) + && DECL_BUILT_IN (olddecl) + && !C_DECL_DECLARED_BUILTIN (olddecl)) /* Don't warn about an extern followed by a definition. */ && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl)) /* Don't warn about forward parameter decls. */ && !(TREE_CODE (newdecl) == PARM_DECL - && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)) + && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)) /* Don't warn about a variable definition following a declaration. */ && !(TREE_CODE (newdecl) == VAR_DECL - && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))) + && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))) { warned = warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D", - newdecl); + newdecl); } /* Report location of previous decl/defn. */ @@ -2155,7 +2163,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) { bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_INITIAL (newdecl) != 0); + && DECL_INITIAL (newdecl) != 0); bool new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL && prototype_p (TREE_TYPE (newdecl))); bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL @@ -2171,8 +2179,8 @@ struct c_binding *b, **here; for (here = ¤t_scope->bindings; *here; here = &(*here)->prev) - if ((*here)->decl == olddecl) - goto found; + if ((*here)->decl == olddecl) + goto found; gcc_unreachable (); found: @@ -2196,11 +2204,11 @@ if (!comptypes (oldtype, TREE_TYPE (newdecl))) { if (TREE_TYPE (newdecl) != error_mark_node) - layout_type (TREE_TYPE (newdecl)); + layout_type (TREE_TYPE (newdecl)); if (TREE_CODE (newdecl) != FUNCTION_DECL - && TREE_CODE (newdecl) != TYPE_DECL - && TREE_CODE (newdecl) != CONST_DECL) - layout_decl (newdecl, 0); + && TREE_CODE (newdecl) != TYPE_DECL + && TREE_CODE (newdecl) != CONST_DECL) + layout_decl (newdecl, 0); } else { @@ -2209,10 +2217,10 @@ DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl); DECL_MODE (newdecl) = DECL_MODE (olddecl); if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) - { - DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); - DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl); - } + { + DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl); + } } /* Keep the old rtl since we can safely use it. */ @@ -2239,12 +2247,12 @@ && !DECL_IN_SYSTEM_HEADER (newdecl) ) DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl); else if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS) - && DECL_IN_SYSTEM_HEADER (newdecl) - && !DECL_IN_SYSTEM_HEADER (olddecl)) + && DECL_IN_SYSTEM_HEADER (newdecl) + && !DECL_IN_SYSTEM_HEADER (olddecl)) DECL_SOURCE_LOCATION (olddecl) = DECL_SOURCE_LOCATION (newdecl); else if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) - || (old_is_prototype && !new_is_prototype - && !C_DECL_BUILTIN_PROTOTYPE (olddecl))) + || (old_is_prototype && !new_is_prototype + && !C_DECL_BUILTIN_PROTOTYPE (olddecl))) DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl); /* Merge the initialization information. */ @@ -2261,52 +2269,52 @@ if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)) { /* Merge the section attribute. - We want to issue an error if the sections conflict but that - must be done later in decl_attributes since we are called - before attributes are assigned. */ + We want to issue an error if the sections conflict but that + must be done later in decl_attributes since we are called + before attributes are assigned. */ if (DECL_SECTION_NAME (newdecl) == NULL_TREE) - DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); + DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); /* Copy the assembler name. - Currently, it can only be defined in the prototype. */ + Currently, it can only be defined in the prototype. */ COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); /* Use visibility of whichever declaration had it specified */ if (DECL_VISIBILITY_SPECIFIED (olddecl)) - { - DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); - DECL_VISIBILITY_SPECIFIED (newdecl) = 1; - } + { + DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); + DECL_VISIBILITY_SPECIFIED (newdecl) = 1; + } if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl); - DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); - DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); - DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) - |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); - TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); - DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl); - TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); - DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl); - DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); - } + { + DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl); + DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); + DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) + |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); + TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); + DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); + DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl); + TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); + DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl); + DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); + } /* Merge the storage class information. */ merge_weak (newdecl, olddecl); /* For functions, static overrides non-static. */ if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); - /* This is since we don't automatically - copy the attributes of NEWDECL into OLDDECL. */ - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - /* If this clears `static', clear it in the identifier too. */ - if (!TREE_PUBLIC (olddecl)) - TREE_PUBLIC (DECL_NAME (olddecl)) = 0; - } + { + TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); + /* This is since we don't automatically + copy the attributes of NEWDECL into OLDDECL. */ + TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); + /* If this clears `static', clear it in the identifier too. */ + if (!TREE_PUBLIC (olddecl)) + TREE_PUBLIC (DECL_NAME (olddecl)) = 0; + } } /* In c99, 'extern' declaration before (or after) 'inline' means this @@ -2315,10 +2323,10 @@ if (TREE_CODE (newdecl) == FUNCTION_DECL && !flag_gnu89_inline && (DECL_DECLARED_INLINE_P (newdecl) - || DECL_DECLARED_INLINE_P (olddecl)) + || DECL_DECLARED_INLINE_P (olddecl)) && (!DECL_DECLARED_INLINE_P (newdecl) - || !DECL_DECLARED_INLINE_P (olddecl) - || !DECL_EXTERNAL (olddecl)) + || !DECL_DECLARED_INLINE_P (olddecl) + || !DECL_EXTERNAL (olddecl)) && DECL_EXTERNAL (newdecl) && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl)) && !current_function_decl) @@ -2332,10 +2340,10 @@ /* An extern decl does not override previous storage class. */ TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); if (!DECL_EXTERNAL (newdecl)) - { - DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); - DECL_COMMON (newdecl) = DECL_COMMON (olddecl); - } + { + DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); + DECL_COMMON (newdecl) = DECL_COMMON (olddecl); + } } else { @@ -2346,53 +2354,53 @@ if (TREE_CODE (newdecl) == FUNCTION_DECL) { /* If we're redefining a function previously defined as extern - inline, make sure we emit debug info for the inline before we - throw it away, in case it was inlined into a function that - hasn't been written out yet. */ + inline, make sure we emit debug info for the inline before we + throw it away, in case it was inlined into a function that + hasn't been written out yet. */ if (new_is_definition && DECL_INITIAL (olddecl)) - /* The new defn must not be inline. */ - DECL_UNINLINABLE (newdecl) = 1; + /* The new defn must not be inline. */ + DECL_UNINLINABLE (newdecl) = 1; else - { - /* If either decl says `inline', this fn is inline, unless - its definition was passed already. */ - if (DECL_DECLARED_INLINE_P (newdecl) - || DECL_DECLARED_INLINE_P (olddecl)) - DECL_DECLARED_INLINE_P (newdecl) = 1; - - DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) - = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); - - DECL_DISREGARD_INLINE_LIMITS (newdecl) - = DECL_DISREGARD_INLINE_LIMITS (olddecl) - = (DECL_DISREGARD_INLINE_LIMITS (newdecl) - || DECL_DISREGARD_INLINE_LIMITS (olddecl)); - } + { + /* If either decl says `inline', this fn is inline, unless + its definition was passed already. */ + if (DECL_DECLARED_INLINE_P (newdecl) + || DECL_DECLARED_INLINE_P (olddecl)) + DECL_DECLARED_INLINE_P (newdecl) = 1; + + DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) + = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); + + DECL_DISREGARD_INLINE_LIMITS (newdecl) + = DECL_DISREGARD_INLINE_LIMITS (olddecl) + = (DECL_DISREGARD_INLINE_LIMITS (newdecl) + || DECL_DISREGARD_INLINE_LIMITS (olddecl)); + } if (DECL_BUILT_IN (olddecl)) - { - /* If redeclaring a builtin function, it stays built in. - But it gets tagged as having been declared. */ - DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl); - DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); - C_DECL_DECLARED_BUILTIN (newdecl) = 1; - if (new_is_prototype) - C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0; - else - C_DECL_BUILTIN_PROTOTYPE (newdecl) - = C_DECL_BUILTIN_PROTOTYPE (olddecl); - } + { + /* If redeclaring a builtin function, it stays built in. + But it gets tagged as having been declared. */ + DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl); + DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); + C_DECL_DECLARED_BUILTIN (newdecl) = 1; + if (new_is_prototype) + C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0; + else + C_DECL_BUILTIN_PROTOTYPE (newdecl) + = C_DECL_BUILTIN_PROTOTYPE (olddecl); + } /* Preserve function specific target and optimization options */ if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl) - && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl)) - DECL_FUNCTION_SPECIFIC_TARGET (newdecl) - = DECL_FUNCTION_SPECIFIC_TARGET (olddecl); + && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl)) + DECL_FUNCTION_SPECIFIC_TARGET (newdecl) + = DECL_FUNCTION_SPECIFIC_TARGET (olddecl); if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl) - && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)) - DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl) - = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl); + && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)) + DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl) + = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl); /* Also preserve various other info from the definition. */ if (!new_is_definition) @@ -2438,8 +2446,8 @@ olddecl_arguments = DECL_ARGUMENTS (olddecl); memcpy ((char *) olddecl + sizeof (struct tree_common), - (char *) newdecl + sizeof (struct tree_common), - sizeof (struct tree_decl_common) - sizeof (struct tree_common)); + (char *) newdecl + sizeof (struct tree_common), + sizeof (struct tree_decl_common) - sizeof (struct tree_common)); switch (TREE_CODE (olddecl)) { case FUNCTION_DECL: @@ -2450,16 +2458,16 @@ case RESULT_DECL: case CONST_DECL: case TYPE_DECL: - memcpy ((char *) olddecl + sizeof (struct tree_decl_common), - (char *) newdecl + sizeof (struct tree_decl_common), - tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common)); - break; + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common)); + break; default: - memcpy ((char *) olddecl + sizeof (struct tree_decl_common), - (char *) newdecl + sizeof (struct tree_decl_common), - sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common)); + memcpy ((char *) olddecl + sizeof (struct tree_decl_common), + (char *) newdecl + sizeof (struct tree_decl_common), + sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common)); } DECL_UID (olddecl) = olddecl_uid; DECL_CONTEXT (olddecl) = olddecl_context; @@ -2472,8 +2480,8 @@ flags and attributes. */ if (DECL_RTL_SET_P (olddecl) && (TREE_CODE (olddecl) == FUNCTION_DECL - || (TREE_CODE (olddecl) == VAR_DECL - && TREE_STATIC (olddecl)))) + || (TREE_CODE (olddecl) == VAR_DECL + && TREE_STATIC (olddecl)))) make_decl_rtl (olddecl); /* If we changed a function from DECL_EXTERNAL to !DECL_EXTERNAL, @@ -2526,35 +2534,35 @@ for (b = I_SYMBOL_BINDING (DECL_NAME (new_decl)); b; b = b->shadowed) if (b->decl && b->decl != new_decl && !b->invisible) { - tree old_decl = b->decl; - - if (old_decl == error_mark_node) - { - warning (OPT_Wshadow, "declaration of %q+D shadows previous " - "non-variable", new_decl); - break; - } - else if (TREE_CODE (old_decl) == PARM_DECL) - warning (OPT_Wshadow, "declaration of %q+D shadows a parameter", - new_decl); - else if (DECL_FILE_SCOPE_P (old_decl)) - warning (OPT_Wshadow, "declaration of %q+D shadows a global " - "declaration", new_decl); - else if (TREE_CODE (old_decl) == FUNCTION_DECL - && DECL_BUILT_IN (old_decl)) - { - warning (OPT_Wshadow, "declaration of %q+D shadows " - "a built-in function", new_decl); - break; - } - else - warning (OPT_Wshadow, "declaration of %q+D shadows a previous local", - new_decl); - - warning_at (DECL_SOURCE_LOCATION (old_decl), OPT_Wshadow, - "shadowed declaration is here"); - - break; + tree old_decl = b->decl; + + if (old_decl == error_mark_node) + { + warning (OPT_Wshadow, "declaration of %q+D shadows previous " + "non-variable", new_decl); + break; + } + else if (TREE_CODE (old_decl) == PARM_DECL) + warning (OPT_Wshadow, "declaration of %q+D shadows a parameter", + new_decl); + else if (DECL_FILE_SCOPE_P (old_decl)) + warning (OPT_Wshadow, "declaration of %q+D shadows a global " + "declaration", new_decl); + else if (TREE_CODE (old_decl) == FUNCTION_DECL + && DECL_BUILT_IN (old_decl)) + { + warning (OPT_Wshadow, "declaration of %q+D shadows " + "a built-in function", new_decl); + break; + } + else + warning (OPT_Wshadow, "declaration of %q+D shadows a previous local", + new_decl); + + warning_at (DECL_SOURCE_LOCATION (old_decl), OPT_Wshadow, + "shadowed declaration is here"); + + break; } } @@ -2580,14 +2588,14 @@ unless they have initializers (which generate code). */ if (current_function_decl && ((TREE_CODE (x) != FUNCTION_DECL && TREE_CODE (x) != VAR_DECL) - || DECL_INITIAL (x) || !DECL_EXTERNAL (x))) + || DECL_INITIAL (x) || !DECL_EXTERNAL (x))) DECL_CONTEXT (x) = current_function_decl; /* Anonymous decls are just inserted in the scope. */ if (!name) { bind (name, x, scope, /*invisible=*/false, /*nested=*/false, - locus); + locus); return x; } @@ -2606,49 +2614,49 @@ tree visdecl = b->decl; tree vistype = TREE_TYPE (visdecl); if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE - && COMPLETE_TYPE_P (TREE_TYPE (x))) - b->inner_comp = false; + && COMPLETE_TYPE_P (TREE_TYPE (x))) + b->inner_comp = false; b_use = b; b_ext = b; /* If this is an external linkage declaration, we should check - for compatibility with the type in the external scope before - setting the type at this scope based on the visible - information only. */ + for compatibility with the type in the external scope before + setting the type at this scope based on the visible + information only. */ if (TREE_PUBLIC (x) && TREE_PUBLIC (visdecl)) - { - while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext)) - b_ext = b_ext->shadowed; - if (b_ext) - { - b_use = b_ext; - if (b_use->u.type) - TREE_TYPE (b_use->decl) = b_use->u.type; - } - } + { + while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext)) + b_ext = b_ext->shadowed; + if (b_ext) + { + b_use = b_ext; + if (b_use->u.type) + TREE_TYPE (b_use->decl) = b_use->u.type; + } + } if (duplicate_decls (x, b_use->decl)) - { - if (b_use != b) - { - /* Save the updated type in the external scope and - restore the proper type for this scope. */ - tree thistype; - if (comptypes (vistype, type)) - thistype = composite_type (vistype, type); - else - thistype = TREE_TYPE (b_use->decl); - b_use->u.type = TREE_TYPE (b_use->decl); - if (TREE_CODE (b_use->decl) == FUNCTION_DECL - && DECL_BUILT_IN (b_use->decl)) - thistype - = build_type_attribute_variant (thistype, - TYPE_ATTRIBUTES - (b_use->u.type)); - TREE_TYPE (b_use->decl) = thistype; - } - return b_use->decl; - } + { + if (b_use != b) + { + /* Save the updated type in the external scope and + restore the proper type for this scope. */ + tree thistype; + if (comptypes (vistype, type)) + thistype = composite_type (vistype, type); + else + thistype = TREE_TYPE (b_use->decl); + b_use->u.type = TREE_TYPE (b_use->decl); + if (TREE_CODE (b_use->decl) == FUNCTION_DECL + && DECL_BUILT_IN (b_use->decl)) + thistype + = build_type_attribute_variant (thistype, + TYPE_ATTRIBUTES + (b_use->u.type)); + TREE_TYPE (b_use->decl) = thistype; + } + return b_use->decl; + } else - goto skip_external_and_shadow_checks; + goto skip_external_and_shadow_checks; } /* All declarations with external linkage, and all external @@ -2670,106 +2678,106 @@ tree visdecl = 0; bool type_saved = false; if (b && !B_IN_EXTERNAL_SCOPE (b) - && (TREE_CODE (b->decl) == FUNCTION_DECL - || TREE_CODE (b->decl) == VAR_DECL) - && DECL_FILE_SCOPE_P (b->decl)) - { - visdecl = b->decl; - vistype = TREE_TYPE (visdecl); - } + && (TREE_CODE (b->decl) == FUNCTION_DECL + || TREE_CODE (b->decl) == VAR_DECL) + && DECL_FILE_SCOPE_P (b->decl)) + { + visdecl = b->decl; + vistype = TREE_TYPE (visdecl); + } if (scope != file_scope - && !DECL_IN_SYSTEM_HEADER (x)) - warning (OPT_Wnested_externs, "nested extern declaration of %qD", x); + && !DECL_IN_SYSTEM_HEADER (x)) + warning (OPT_Wnested_externs, "nested extern declaration of %qD", x); while (b && !B_IN_EXTERNAL_SCOPE (b)) - { - /* If this decl might be modified, save its type. This is - done here rather than when the decl is first bound - because the type may change after first binding, through - being completed or through attributes being added. If we - encounter multiple such decls, only the first should have - its type saved; the others will already have had their - proper types saved and the types will not have changed as - their scopes will not have been re-entered. */ - if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved) - { - b->u.type = TREE_TYPE (b->decl); - type_saved = true; - } - if (B_IN_FILE_SCOPE (b) - && TREE_CODE (b->decl) == VAR_DECL - && TREE_STATIC (b->decl) - && TREE_CODE (TREE_TYPE (b->decl)) == ARRAY_TYPE - && !TYPE_DOMAIN (TREE_TYPE (b->decl)) - && TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) - && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) - && !integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) - { - /* Array type completed in inner scope, which should be - diagnosed if the completion does not have size 1 and - it does not get completed in the file scope. */ - b->inner_comp = true; - } - b = b->shadowed; - } + { + /* If this decl might be modified, save its type. This is + done here rather than when the decl is first bound + because the type may change after first binding, through + being completed or through attributes being added. If we + encounter multiple such decls, only the first should have + its type saved; the others will already have had their + proper types saved and the types will not have changed as + their scopes will not have been re-entered. */ + if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved) + { + b->u.type = TREE_TYPE (b->decl); + type_saved = true; + } + if (B_IN_FILE_SCOPE (b) + && TREE_CODE (b->decl) == VAR_DECL + && TREE_STATIC (b->decl) + && TREE_CODE (TREE_TYPE (b->decl)) == ARRAY_TYPE + && !TYPE_DOMAIN (TREE_TYPE (b->decl)) + && TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) + && !integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) + { + /* Array type completed in inner scope, which should be + diagnosed if the completion does not have size 1 and + it does not get completed in the file scope. */ + b->inner_comp = true; + } + b = b->shadowed; + } /* If a matching external declaration has been found, set its - type to the composite of all the types of that declaration. - After the consistency checks, it will be reset to the - composite of the visible types only. */ + type to the composite of all the types of that declaration. + After the consistency checks, it will be reset to the + composite of the visible types only. */ if (b && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl)) - && b->u.type) - TREE_TYPE (b->decl) = b->u.type; + && b->u.type) + TREE_TYPE (b->decl) = b->u.type; /* The point of the same_translation_unit_p check here is, - we want to detect a duplicate decl for a construct like - foo() { extern bar(); } ... static bar(); but not if - they are in different translation units. In any case, - the static does not go in the externals scope. */ + we want to detect a duplicate decl for a construct like + foo() { extern bar(); } ... static bar(); but not if + they are in different translation units. In any case, + the static does not go in the externals scope. */ if (b - && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl)) - && duplicate_decls (x, b->decl)) - { - tree thistype; - if (vistype) - { - if (comptypes (vistype, type)) - thistype = composite_type (vistype, type); - else - thistype = TREE_TYPE (b->decl); - } - else - thistype = type; - b->u.type = TREE_TYPE (b->decl); - if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl)) - thistype - = build_type_attribute_variant (thistype, - TYPE_ATTRIBUTES (b->u.type)); - TREE_TYPE (b->decl) = thistype; - bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true, - locus); - return b->decl; - } + && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl)) + && duplicate_decls (x, b->decl)) + { + tree thistype; + if (vistype) + { + if (comptypes (vistype, type)) + thistype = composite_type (vistype, type); + else + thistype = TREE_TYPE (b->decl); + } + else + thistype = type; + b->u.type = TREE_TYPE (b->decl); + if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl)) + thistype + = build_type_attribute_variant (thistype, + TYPE_ATTRIBUTES (b->u.type)); + TREE_TYPE (b->decl) = thistype; + bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true, + locus); + return b->decl; + } else if (TREE_PUBLIC (x)) - { - if (visdecl && !b && duplicate_decls (x, visdecl)) - { - /* An external declaration at block scope referring to a - visible entity with internal linkage. The composite - type will already be correct for this scope, so we - just need to fall through to make the declaration in - this scope. */ - nested = true; - x = visdecl; - } - else - { - bind (name, x, external_scope, /*invisible=*/true, - /*nested=*/false, locus); - nested = true; - } - } + { + if (visdecl && !b && duplicate_decls (x, visdecl)) + { + /* An external declaration at block scope referring to a + visible entity with internal linkage. The composite + type will already be correct for this scope, so we + just need to fall through to make the declaration in + this scope. */ + nested = true; + x = visdecl; + } + else + { + bind (name, x, external_scope, /*invisible=*/true, + /*nested=*/false, locus); + nested = true; + } + } } if (TREE_CODE (x) != PARM_DECL) @@ -2796,16 +2804,16 @@ tree element = TREE_TYPE (x); while (TREE_CODE (element) == ARRAY_TYPE) - element = TREE_TYPE (element); + element = TREE_TYPE (element); element = TYPE_MAIN_VARIANT (element); if ((TREE_CODE (element) == RECORD_TYPE - || TREE_CODE (element) == UNION_TYPE) - && (TREE_CODE (x) != TYPE_DECL - || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE) - && !COMPLETE_TYPE_P (element)) - C_TYPE_INCOMPLETE_VARS (element) - = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element)); + || TREE_CODE (element) == UNION_TYPE) + && (TREE_CODE (x) != TYPE_DECL + || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE) + && !COMPLETE_TYPE_P (element)) + C_TYPE_INCOMPLETE_VARS (element) + = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element)); } return x; } @@ -2829,7 +2837,7 @@ if (TREE_PUBLIC (x)) { bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false, - UNKNOWN_LOCATION); + UNKNOWN_LOCATION); nested = true; } if (file_scope) @@ -2846,21 +2854,26 @@ bool warned; if (flag_isoc99) - warned = pedwarn (input_location, OPT_Wimplicit_function_declaration, - "implicit declaration of function %qE", id); + warned = pedwarn (input_location, OPT_Wimplicit_function_declaration, + "implicit declaration of function %qE", id); else - warned = warning (OPT_Wimplicit_function_declaration, - G_("implicit declaration of function %qE"), id); + warned = warning (OPT_Wimplicit_function_declaration, + G_("implicit declaration of function %qE"), id); if (olddecl && warned) - locate_old_decl (olddecl); + locate_old_decl (olddecl); } } /* Generate an implicit declaration for identifier FUNCTIONID at LOC as a function of type int (). */ +#ifndef noCbC +tree +implicitly_declare (location_t loc, tree functionid, int fun) +#else tree implicitly_declare (location_t loc, tree functionid) +#endif { struct c_binding *b; tree decl = 0; @@ -2869,74 +2882,79 @@ for (b = I_SYMBOL_BINDING (functionid); b; b = b->shadowed) { if (B_IN_SCOPE (b, external_scope)) - { - decl = b->decl; - break; - } + { + decl = b->decl; + break; + } } if (decl) { if (decl == error_mark_node) - return decl; + return decl; /* FIXME: Objective-C has weird not-really-builtin functions - which are supposed to be visible automatically. They wind up - in the external scope because they're pushed before the file - scope gets created. Catch this here and rebind them into the - file scope. */ + which are supposed to be visible automatically. They wind up + in the external scope because they're pushed before the file + scope gets created. Catch this here and rebind them into the + file scope. */ if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl)) - { - bind (functionid, decl, file_scope, - /*invisible=*/false, /*nested=*/true, - DECL_SOURCE_LOCATION (decl)); - return decl; - } + { + bind (functionid, decl, file_scope, + /*invisible=*/false, /*nested=*/true, + DECL_SOURCE_LOCATION (decl)); + return decl; + } else - { - tree newtype = default_function_type; - if (b->u.type) - TREE_TYPE (decl) = b->u.type; - /* Implicit declaration of a function already declared - (somehow) in a different scope, or as a built-in. - If this is the first time this has happened, warn; - then recycle the old declaration but with the new type. */ - if (!C_DECL_IMPLICIT (decl)) - { - implicit_decl_warning (functionid, decl); - C_DECL_IMPLICIT (decl) = 1; - } - if (DECL_BUILT_IN (decl)) - { - newtype = build_type_attribute_variant (newtype, - TYPE_ATTRIBUTES - (TREE_TYPE (decl))); - if (!comptypes (newtype, TREE_TYPE (decl))) - { - warning_at (loc, 0, "incompatible implicit declaration of " - "built-in function %qD", decl); - newtype = TREE_TYPE (decl); - } - } - else - { - if (!comptypes (newtype, TREE_TYPE (decl))) - { - error_at (loc, "incompatible implicit declaration of function %qD", decl); - locate_old_decl (decl); - } - } - b->u.type = TREE_TYPE (decl); - TREE_TYPE (decl) = newtype; - bind (functionid, decl, current_scope, - /*invisible=*/false, /*nested=*/true, - DECL_SOURCE_LOCATION (decl)); - return decl; - } + { + tree newtype = default_function_type; + if (b->u.type) + TREE_TYPE (decl) = b->u.type; + /* Implicit declaration of a function already declared + (somehow) in a different scope, or as a built-in. + If this is the first time this has happened, warn; + then recycle the old declaration but with the new type. */ + if (!C_DECL_IMPLICIT (decl)) + { + implicit_decl_warning (functionid, decl); + C_DECL_IMPLICIT (decl) = 1; + } + if (DECL_BUILT_IN (decl)) + { + newtype = build_type_attribute_variant (newtype, + TYPE_ATTRIBUTES + (TREE_TYPE (decl))); + if (!comptypes (newtype, TREE_TYPE (decl))) + { + warning_at (loc, 0, "incompatible implicit declaration of " + "built-in function %qD", decl); + newtype = TREE_TYPE (decl); + } + } + else + { + if (!comptypes (newtype, TREE_TYPE (decl))) + { + error_at (loc, "incompatible implicit declaration of function %qD", decl); + locate_old_decl (decl); + } + } + b->u.type = TREE_TYPE (decl); + TREE_TYPE (decl) = newtype; + bind (functionid, decl, current_scope, + /*invisible=*/false, /*nested=*/true, + DECL_SOURCE_LOCATION (decl)); + return decl; + } } /* Not seen before. */ +#ifndef noCbC + decl = build_decl (loc, FUNCTION_DECL, functionid, + fun==RID_CbC_CODE?build_function_type (void_type_node, NULL_TREE):default_function_type); +#else decl = build_decl (loc, FUNCTION_DECL, functionid, default_function_type); +#endif DECL_EXTERNAL (decl) = 1; TREE_PUBLIC (decl) = 1; C_DECL_IMPLICIT (decl) = 1; @@ -2990,11 +3008,11 @@ } /* If we are parsing old-style parameter decls, current_function_decl - will be nonnull but current_function_scope will be null. */ + will be nonnull but current_function_scope will be null. */ scope = current_function_scope ? current_function_scope : current_scope; } bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false, - UNKNOWN_LOCATION); + UNKNOWN_LOCATION); } /* Subroutine of lookup_label, declare_label, define_label: construct a @@ -3003,7 +3021,7 @@ static tree make_label (location_t location, tree name, bool defining, - struct c_label_vars **p_label_vars) + struct c_label_vars **p_label_vars) { tree label = build_decl (location, LABEL_DECL, name, void_type_node); struct c_label_vars *label_vars; @@ -3043,13 +3061,13 @@ using __label__. */ label = I_LABEL_DECL (name); if (label && (DECL_CONTEXT (label) == current_function_decl - || C_DECLARED_LABEL_FLAG (label))) + || C_DECLARED_LABEL_FLAG (label))) { /* If the label has only been declared, update its apparent - location to point here, for better diagnostics if it - turns out not to have been defined. */ + location to point here, for better diagnostics if it + turns out not to have been defined. */ if (DECL_INITIAL (label) == NULL_TREE) - DECL_SOURCE_LOCATION (label) = input_location; + DECL_SOURCE_LOCATION (label) = input_location; return label; } @@ -3070,10 +3088,10 @@ { if (variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) error_at (goto_loc, - "jump into scope of identifier with variably modified type"); + "jump into scope of identifier with variably modified type"); else warning_at (goto_loc, OPT_Wjump_misses_init, - "jump skips variable initialization"); + "jump skips variable initialization"); inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label); inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl); } @@ -3196,7 +3214,7 @@ } /* We also need to warn about decls defined in any scopes - between the scope of the label and the scope of the goto. */ + between the scope of the label and the scope of the goto. */ for (scope = label_vars->label_bindings.scope; scope != g->goto_bindings.scope; scope = scope->outer) @@ -3217,11 +3235,11 @@ } if (g->goto_bindings.stmt_exprs > 0) - { - error_at (g->loc, "jump into statement expression"); - inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", - label); - } + { + error_at (g->loc, "jump into statement expression"); + inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", + label); + } } /* Now that the label is defined, we will issue warnings about @@ -3245,9 +3263,9 @@ if (label && ((DECL_CONTEXT (label) == current_function_decl - && DECL_INITIAL (label) != 0) - || (DECL_CONTEXT (label) != current_function_decl - && C_DECLARED_LABEL_FLAG (label)))) + && DECL_INITIAL (label) != 0) + || (DECL_CONTEXT (label) != current_function_decl + && C_DECLARED_LABEL_FLAG (label)))) { error_at (location, "duplicate label %qD", label); locate_old_decl (label); @@ -3258,13 +3276,13 @@ struct c_label_vars *label_vars = I_LABEL_BINDING (name)->u.label; /* The label has been used or declared already in this function, - but not defined. Update its location to point to this - definition. */ + but not defined. Update its location to point to this + definition. */ DECL_SOURCE_LOCATION (label) = location; set_spot_bindings (&label_vars->label_bindings, true); /* Issue warnings as required about any goto statements from - earlier in the function. */ + earlier in the function. */ check_earlier_gotos (label, label_vars); } else @@ -3280,8 +3298,8 @@ if (!in_system_header && lookup_name (name)) warning_at (location, OPT_Wtraditional, - "traditional C lacks a separate namespace " - "for labels, identifier %qE conflicts", name); + "traditional C lacks a separate namespace " + "for labels, identifier %qE conflicts", name); /* Mark label as having been defined. */ DECL_INITIAL (label) = error_mark_node; @@ -3315,7 +3333,7 @@ bool c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings, - location_t switch_loc, location_t case_loc) + location_t switch_loc, location_t case_loc) { bool saw_error; struct c_scope *scope; @@ -3333,24 +3351,24 @@ continue; for (b = scope->bindings; b != NULL; b = b->prev) - { - if (decl_jump_unsafe (b->decl)) - { - if (variably_modified_type_p (TREE_TYPE (b->decl), NULL_TREE)) - { - saw_error = true; - error_at (case_loc, - ("switch jumps into scope of identifier with " - "variably modified type")); - } - else - warning_at (case_loc, OPT_Wjump_misses_init, - "switch jumps over variable initialization"); - inform (switch_loc, "switch starts here"); - inform (DECL_SOURCE_LOCATION (b->decl), "%qD declared here", - b->decl); - } - } + { + if (decl_jump_unsafe (b->decl)) + { + if (variably_modified_type_p (TREE_TYPE (b->decl), NULL_TREE)) + { + saw_error = true; + error_at (case_loc, + ("switch jumps into scope of identifier with " + "variably modified type")); + } + else + warning_at (case_loc, OPT_Wjump_misses_init, + "switch jumps over variable initialization"); + inform (switch_loc, "switch starts here"); + inform (DECL_SOURCE_LOCATION (b->decl), "%qD declared here", + b->decl); + } + } } if (switch_bindings->stmt_exprs > 0) @@ -3374,7 +3392,7 @@ static tree lookup_tag (enum tree_code code, tree name, int thislevel_only, - location_t *ploc) + location_t *ploc) { struct c_binding *b = I_TAG_BINDING (name); int thislevel = 0; @@ -3387,12 +3405,12 @@ if (thislevel_only || TREE_CODE (b->decl) != code) { /* For our purposes, a tag in the external scope is the same as - a tag in the file scope. (Primarily relevant to Objective-C - and its builtin structure tags, which get pushed before the - file scope is created.) */ + a tag in the file scope. (Primarily relevant to Objective-C + and its builtin structure tags, which get pushed before the + file scope is created.) */ if (B_IN_CURRENT_SCOPE (b) - || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) - thislevel = 1; + || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) + thislevel = 1; } if (thislevel_only && !thislevel) @@ -3405,11 +3423,11 @@ pending_invalid_xref_location = input_location; /* If in the same binding level as a declaration as a tag - of a different type, this must not be allowed to - shadow that tag, so give the error immediately. - (For example, "struct foo; union foo;" is invalid.) */ + of a different type, this must not be allowed to + shadow that tag, so give the error immediately. + (For example, "struct foo; union foo;" is invalid.) */ if (thislevel) - pending_xref_error (); + pending_xref_error (); } if (ploc != NULL) @@ -3428,7 +3446,7 @@ { if (pending_invalid_xref != 0) error_at (pending_invalid_xref_location, "%qE defined as wrong kind of tag", - pending_invalid_xref); + pending_invalid_xref); pending_invalid_xref = 0; } @@ -3497,7 +3515,7 @@ /* Even in C99, which has a real boolean type. */ pushdecl (build_decl (UNKNOWN_LOCATION, TYPE_DECL, get_identifier ("_Bool"), - boolean_type_node)); + boolean_type_node)); input_location = save_loc; @@ -3523,7 +3541,7 @@ size_t length = strlen (name); type = build_array_type (char_type_node, - build_index_type (size_int (length))); + build_index_type (size_int (length))); type = c_build_qualified_type (type, TYPE_QUAL_CONST); decl = build_decl (loc, VAR_DECL, id, type); @@ -3552,7 +3570,7 @@ { DECL_CONTEXT (decl) = current_function_decl; bind (id, decl, current_function_scope, - /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); + /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); } finish_decl (decl, loc, init, NULL_TREE, NULL_TREE); @@ -3573,7 +3591,7 @@ gcc_assert (!I_SYMBOL_BINDING (id)); bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false, - UNKNOWN_LOCATION); + UNKNOWN_LOCATION); /* Builtins in the implementation namespace are made visible without needing to be explicitly declared. See push_file_scope. */ @@ -3599,7 +3617,7 @@ gcc_assert (!I_SYMBOL_BINDING (id)); bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false, - UNKNOWN_LOCATION); + UNKNOWN_LOCATION); /* Builtins in the implementation namespace are made visible without needing to be explicitly declared. See push_file_scope. */ @@ -3701,14 +3719,26 @@ } } else - { - if (warned != 1 && !in_system_header) - { - pedwarn (input_location, 0, - "useless type name in empty declaration"); - warned = 1; - } - } + { + pending_invalid_xref = 0; + t = lookup_tag (code, name, 1, NULL); + + if (t == 0) + { + t = make_node (code); + pushtag (input_location, name, t); + } + } + } + else + { + if (warned != 1 && !in_system_header) + { + pedwarn (input_location, 0, + "useless type name in empty declaration"); + warned = 1; + } + } } else if (warned != 1 && !in_system_header && declspecs->typedef_p) { @@ -3749,9 +3779,9 @@ } if (!warned && !in_system_header && (declspecs->const_p - || declspecs->volatile_p - || declspecs->restrict_p - || declspecs->address_space)) + || declspecs->volatile_p + || declspecs->restrict_p + || declspecs->address_space)) { warning (0, "useless type qualifier in empty declaration"); warned = 2; @@ -3760,7 +3790,7 @@ if (warned != 1) { if (!found_tag) - pedwarn (input_location, 0, "empty declaration"); + pedwarn (input_location, 0, "empty declaration"); } } @@ -3773,24 +3803,24 @@ quals_from_declspecs (const struct c_declspecs *specs) { int quals = ((specs->const_p ? TYPE_QUAL_CONST : 0) - | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0) - | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0) - | (ENCODE_QUAL_ADDR_SPACE (specs->address_space))); + | (specs->volatile_p ? TYPE_QUAL_VOLATILE : 0) + | (specs->restrict_p ? TYPE_QUAL_RESTRICT : 0) + | (ENCODE_QUAL_ADDR_SPACE (specs->address_space))); gcc_assert (!specs->type - && !specs->decl_attr - && specs->typespec_word == cts_none - && specs->storage_class == csc_none - && !specs->typedef_p - && !specs->explicit_signed_p - && !specs->deprecated_p - && !specs->long_p - && !specs->long_long_p - && !specs->short_p - && !specs->signed_p - && !specs->unsigned_p - && !specs->complex_p - && !specs->inline_p - && !specs->thread_p); + && !specs->decl_attr + && specs->typespec_word == cts_none + && specs->storage_class == csc_none + && !specs->typedef_p + && !specs->explicit_signed_p + && !specs->deprecated_p + && !specs->long_p + && !specs->long_long_p + && !specs->short_p + && !specs->signed_p + && !specs->unsigned_p + && !specs->complex_p + && !specs->inline_p + && !specs->thread_p); return quals; } @@ -3806,11 +3836,11 @@ struct c_declarator * build_array_declarator (location_t loc, - tree expr, struct c_declspecs *quals, bool static_p, - bool vla_unspec_p) + tree expr, struct c_declspecs *quals, bool static_p, + bool vla_unspec_p) { struct c_declarator *declarator = XOBNEW (&parser_obstack, - struct c_declarator); + struct c_declarator); declarator->id_loc = loc; declarator->kind = cdk_array; declarator->declarator = 0; @@ -3830,23 +3860,23 @@ if (!flag_isoc99) { if (static_p || quals != NULL) - pedwarn (loc, OPT_pedantic, - "ISO C90 does not support % or type " - "qualifiers in parameter array declarators"); + pedwarn (loc, OPT_pedantic, + "ISO C90 does not support % or type " + "qualifiers in parameter array declarators"); if (vla_unspec_p) - pedwarn (loc, OPT_pedantic, - "ISO C90 does not support %<[*]%> array declarators"); + pedwarn (loc, OPT_pedantic, + "ISO C90 does not support %<[*]%> array declarators"); } if (vla_unspec_p) { if (!current_scope->parm_flag) - { - /* C99 6.7.5.2p4 */ - error_at (loc, "%<[*]%> not allowed in other than " - "function prototype scope"); - declarator->u.array.vla_unspec_p = false; - return NULL; - } + { + /* C99 6.7.5.2p4 */ + error_at (loc, "%<[*]%> not allowed in other than " + "function prototype scope"); + declarator->u.array.vla_unspec_p = false; + return NULL; + } current_scope->had_vla_unspec = true; } return declarator; @@ -3858,7 +3888,7 @@ struct c_declarator * set_array_declarator_inner (struct c_declarator *decl, - struct c_declarator *inner) + struct c_declarator *inner) { decl->declarator = inner; return decl; @@ -3885,9 +3915,9 @@ { complete_array_type (&type, elt, false); DECL_SIZE (decl) - = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type)); + = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type)); DECL_SIZE_UNIT (decl) - = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type)); + = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type)); } } @@ -3899,7 +3929,7 @@ tree groktypename (struct c_type_name *type_name, tree *expr, - bool *expr_const_operands) + bool *expr_const_operands) { tree type; tree attrs = type_name->specs->attrs; @@ -3907,8 +3937,8 @@ type_name->specs->attrs = NULL_TREE; type = grokdeclarator (type_name->declarator, type_name->specs, TYPENAME, - false, NULL, &attrs, expr, expr_const_operands, - DEPRECATED_NORMAL); + false, NULL, &attrs, expr, expr_const_operands, + DEPRECATED_NORMAL); /* Apply attributes. */ decl_attributes (&type, attrs, 0); @@ -3933,7 +3963,7 @@ tree start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, - bool initialized, tree attributes) + bool initialized, tree attributes) { tree decl; tree tem; @@ -3946,8 +3976,8 @@ deprecated_state = DEPRECATED_SUPPRESS; decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized, NULL, &attributes, &expr, NULL, - deprecated_state); + NORMAL, initialized, NULL, &attributes, &expr, NULL, + deprecated_state); if (!decl) return 0; @@ -3964,64 +3994,64 @@ switch (TREE_CODE (decl)) { case TYPE_DECL: - error ("typedef %qD is initialized (use __typeof__ instead)", decl); - initialized = 0; - break; + error ("typedef %qD is initialized (use __typeof__ instead)", decl); + initialized = 0; + break; case FUNCTION_DECL: - error ("function %qD is initialized like a variable", decl); - initialized = 0; - break; + error ("function %qD is initialized like a variable", decl); + initialized = 0; + break; case PARM_DECL: - /* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE. */ - error ("parameter %qD is initialized", decl); - initialized = 0; - break; + /* DECL_INITIAL in a PARM_DECL is really DECL_ARG_TYPE. */ + error ("parameter %qD is initialized", decl); + initialized = 0; + break; default: - /* Don't allow initializations for incomplete types except for - arrays which might be completed by the initialization. */ - - /* This can happen if the array size is an undefined macro. - We already gave a warning, so we don't need another one. */ - if (TREE_TYPE (decl) == error_mark_node) - initialized = 0; - else if (COMPLETE_TYPE_P (TREE_TYPE (decl))) - { - /* A complete type is ok if size is fixed. */ - - if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST - || C_DECL_VARIABLE_SIZE (decl)) - { - error ("variable-sized object may not be initialized"); - initialized = 0; - } - } - else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) - { - error ("variable %qD has initializer but incomplete type", decl); - initialized = 0; - } - else if (C_DECL_VARIABLE_SIZE (decl)) - { - /* Although C99 is unclear about whether incomplete arrays - of VLAs themselves count as VLAs, it does not make - sense to permit them to be initialized given that - ordinary VLAs may not be initialized. */ - error ("variable-sized object may not be initialized"); - initialized = 0; - } + /* Don't allow initializations for incomplete types except for + arrays which might be completed by the initialization. */ + + /* This can happen if the array size is an undefined macro. + We already gave a warning, so we don't need another one. */ + if (TREE_TYPE (decl) == error_mark_node) + initialized = 0; + else if (COMPLETE_TYPE_P (TREE_TYPE (decl))) + { + /* A complete type is ok if size is fixed. */ + + if (TREE_CODE (TYPE_SIZE (TREE_TYPE (decl))) != INTEGER_CST + || C_DECL_VARIABLE_SIZE (decl)) + { + error ("variable-sized object may not be initialized"); + initialized = 0; + } + } + else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) + { + error ("variable %qD has initializer but incomplete type", decl); + initialized = 0; + } + else if (C_DECL_VARIABLE_SIZE (decl)) + { + /* Although C99 is unclear about whether incomplete arrays + of VLAs themselves count as VLAs, it does not make + sense to permit them to be initialized given that + ordinary VLAs may not be initialized. */ + error ("variable-sized object may not be initialized"); + initialized = 0; + } } if (initialized) { if (current_scope == file_scope) - TREE_STATIC (decl) = 1; + TREE_STATIC (decl) = 1; /* Tell 'pushdecl' this is an initialized decl - even though we don't yet have the initializer expression. - Also tell 'finish_decl' it may store the real initializer. */ + even though we don't yet have the initializer expression. + Also tell 'finish_decl' it may store the real initializer. */ DECL_INITIAL (decl) = error_mark_node; } @@ -4057,12 +4087,12 @@ && !flag_gnu89_inline && TREE_CODE (decl) == FUNCTION_DECL && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl)) - || current_function_decl)) + || current_function_decl)) { if (declspecs->storage_class == csc_auto && current_scope != file_scope) - ; + ; else if (declspecs->storage_class != csc_static) - DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl); + DECL_EXTERNAL (decl) = !DECL_EXTERNAL (decl); } if (TREE_CODE (decl) == FUNCTION_DECL @@ -4071,7 +4101,7 @@ struct c_declarator *ce = declarator; if (ce->kind == cdk_pointer) - ce = declarator->declarator; + ce = declarator->declarator; if (ce->kind == cdk_function) { tree args = ce->u.arg_info->parms; @@ -4090,7 +4120,7 @@ && DECL_UNINLINABLE (decl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl))) warning (OPT_Wattributes, "inline function %q+D given attribute noinline", - decl); + decl); /* C99 6.7.4p3: An inline definition of a function with external linkage shall not contain a definition of a modifiable object @@ -4102,7 +4132,7 @@ && DECL_DECLARED_INLINE_P (current_function_decl) && DECL_EXTERNAL (current_function_decl)) record_inline_static (input_location, current_function_decl, - decl, csi_modifiable); + decl, csi_modifiable); if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL @@ -4161,7 +4191,7 @@ void finish_decl (tree decl, location_t init_loc, tree init, - tree origtype, tree asmspec_tree) + tree origtype, tree asmspec_tree) { tree type; bool was_incomplete = (DECL_SIZE (decl) == 0); @@ -4193,8 +4223,8 @@ store_init_value (init_loc, decl, init, origtype); if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == FIELD_DECL)) + || TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == FIELD_DECL)) objc_check_decl (decl); type = TREE_TYPE (decl); @@ -4205,65 +4235,65 @@ && TREE_CODE (decl) != TYPE_DECL) { bool do_default - = (TREE_STATIC (decl) - /* Even if pedantic, an external linkage array - may have incomplete type at first. */ - ? pedantic && !TREE_PUBLIC (decl) - : !DECL_EXTERNAL (decl)); + = (TREE_STATIC (decl) + /* Even if pedantic, an external linkage array + may have incomplete type at first. */ + ? pedantic && !TREE_PUBLIC (decl) + : !DECL_EXTERNAL (decl)); int failure - = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl), - do_default); + = complete_array_type (&TREE_TYPE (decl), DECL_INITIAL (decl), + do_default); /* Get the completed type made by complete_array_type. */ type = TREE_TYPE (decl); switch (failure) - { - case 1: - error ("initializer fails to determine size of %q+D", decl); - break; - - case 2: - if (do_default) - error ("array size missing in %q+D", decl); - /* If a `static' var's size isn't known, - make it extern as well as static, so it does not get - allocated. - If it is not `static', then do not mark extern; - finish_incomplete_decl will give it a default size - and it will get allocated. */ - else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) - DECL_EXTERNAL (decl) = 1; - break; - - case 3: - error ("zero or negative size array %q+D", decl); - break; - - case 0: - /* For global variables, update the copy of the type that - exists in the binding. */ - if (TREE_PUBLIC (decl)) - { - struct c_binding *b_ext = I_SYMBOL_BINDING (DECL_NAME (decl)); - while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext)) - b_ext = b_ext->shadowed; - if (b_ext) - { - if (b_ext->u.type) - b_ext->u.type = composite_type (b_ext->u.type, type); - else - b_ext->u.type = type; - } - } - break; - - default: - gcc_unreachable (); - } + { + case 1: + error ("initializer fails to determine size of %q+D", decl); + break; + + case 2: + if (do_default) + error ("array size missing in %q+D", decl); + /* If a `static' var's size isn't known, + make it extern as well as static, so it does not get + allocated. + If it is not `static', then do not mark extern; + finish_incomplete_decl will give it a default size + and it will get allocated. */ + else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) + DECL_EXTERNAL (decl) = 1; + break; + + case 3: + error ("zero or negative size array %q+D", decl); + break; + + case 0: + /* For global variables, update the copy of the type that + exists in the binding. */ + if (TREE_PUBLIC (decl)) + { + struct c_binding *b_ext = I_SYMBOL_BINDING (DECL_NAME (decl)); + while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext)) + b_ext = b_ext->shadowed; + if (b_ext) + { + if (b_ext->u.type) + b_ext->u.type = composite_type (b_ext->u.type, type); + else + b_ext->u.type = type; + } + } + break; + + default: + gcc_unreachable (); + } if (DECL_INITIAL (decl)) - TREE_TYPE (DECL_INITIAL (decl)) = type; + TREE_TYPE (DECL_INITIAL (decl)) = type; layout_decl (decl, 0); } @@ -4271,42 +4301,42 @@ if (TREE_CODE (decl) == VAR_DECL) { if (init && TREE_CODE (init) == CONSTRUCTOR) - add_flexible_array_elts_to_size (decl, init); + add_flexible_array_elts_to_size (decl, init); if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node - && COMPLETE_TYPE_P (TREE_TYPE (decl))) - layout_decl (decl, 0); + && COMPLETE_TYPE_P (TREE_TYPE (decl))) + layout_decl (decl, 0); if (DECL_SIZE (decl) == 0 - /* Don't give an error if we already gave one earlier. */ - && TREE_TYPE (decl) != error_mark_node - && (TREE_STATIC (decl) - /* A static variable with an incomplete type - is an error if it is initialized. - Also if it is not file scope. - Otherwise, let it through, but if it is not `extern' - then it may cause an error message later. */ - ? (DECL_INITIAL (decl) != 0 - || !DECL_FILE_SCOPE_P (decl)) - /* An automatic variable with an incomplete type - is an error. */ - : !DECL_EXTERNAL (decl))) - { - error ("storage size of %q+D isn%'t known", decl); - TREE_TYPE (decl) = error_mark_node; - } + /* Don't give an error if we already gave one earlier. */ + && TREE_TYPE (decl) != error_mark_node + && (TREE_STATIC (decl) + /* A static variable with an incomplete type + is an error if it is initialized. + Also if it is not file scope. + Otherwise, let it through, but if it is not `extern' + then it may cause an error message later. */ + ? (DECL_INITIAL (decl) != 0 + || !DECL_FILE_SCOPE_P (decl)) + /* An automatic variable with an incomplete type + is an error. */ + : !DECL_EXTERNAL (decl))) + { + error ("storage size of %q+D isn%'t known", decl); + TREE_TYPE (decl) = error_mark_node; + } if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) - && DECL_SIZE (decl) != 0) - { - if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) - constant_expression_warning (DECL_SIZE (decl)); - else - { - error ("storage size of %q+D isn%'t constant", decl); - TREE_TYPE (decl) = error_mark_node; - } - } + && DECL_SIZE (decl) != 0) + { + if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) + constant_expression_warning (DECL_SIZE (decl)); + else + { + error ("storage size of %q+D isn%'t constant", decl); + TREE_TYPE (decl) = error_mark_node; + } + } if (TREE_USED (type)) { @@ -4321,7 +4351,7 @@ if (TREE_CODE (decl) == FUNCTION_DECL && asmspec) { if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) - set_builtin_user_assembler_name (decl, asmspec); + set_builtin_user_assembler_name (decl, asmspec); set_user_assembler_name (decl, asmspec); } @@ -4336,98 +4366,98 @@ { /* Determine the ELF visibility. */ if (TREE_PUBLIC (decl)) - c_determine_visibility (decl); + c_determine_visibility (decl); /* This is a no-op in c-lang.c or something real in objc-act.c. */ if (c_dialect_objc ()) - objc_check_decl (decl); + objc_check_decl (decl); if (asmspec) - { - /* If this is not a static variable, issue a warning. - It doesn't make any sense to give an ASMSPEC for an - ordinary, non-register local variable. Historically, - GCC has accepted -- but ignored -- the ASMSPEC in - this case. */ - if (!DECL_FILE_SCOPE_P (decl) - && TREE_CODE (decl) == VAR_DECL - && !C_DECL_REGISTER (decl) - && !TREE_STATIC (decl)) - warning (0, "ignoring asm-specifier for non-static local " - "variable %q+D", decl); - else - set_user_assembler_name (decl, asmspec); - } + { + /* If this is not a static variable, issue a warning. + It doesn't make any sense to give an ASMSPEC for an + ordinary, non-register local variable. Historically, + GCC has accepted -- but ignored -- the ASMSPEC in + this case. */ + if (!DECL_FILE_SCOPE_P (decl) + && TREE_CODE (decl) == VAR_DECL + && !C_DECL_REGISTER (decl) + && !TREE_STATIC (decl)) + warning (0, "ignoring asm-specifier for non-static local " + "variable %q+D", decl); + else + set_user_assembler_name (decl, asmspec); + } if (DECL_FILE_SCOPE_P (decl)) - { - if (DECL_INITIAL (decl) == NULL_TREE - || DECL_INITIAL (decl) == error_mark_node) - /* Don't output anything - when a tentative file-scope definition is seen. - But at end of compilation, do output code for them. */ - DECL_DEFER_OUTPUT (decl) = 1; - rest_of_decl_compilation (decl, true, 0); - } + { + if (DECL_INITIAL (decl) == NULL_TREE + || DECL_INITIAL (decl) == error_mark_node) + /* Don't output anything + when a tentative file-scope definition is seen. + But at end of compilation, do output code for them. */ + DECL_DEFER_OUTPUT (decl) = 1; + rest_of_decl_compilation (decl, true, 0); + } else - { - /* In conjunction with an ASMSPEC, the `register' - keyword indicates that we should place the variable - in a particular register. */ - if (asmspec && C_DECL_REGISTER (decl)) - { - DECL_HARD_REGISTER (decl) = 1; - /* This cannot be done for a structure with volatile - fields, on which DECL_REGISTER will have been - reset. */ - if (!DECL_REGISTER (decl)) - error ("cannot put object with volatile field into register"); - } - - if (TREE_CODE (decl) != FUNCTION_DECL) - { - /* If we're building a variable sized type, and we might be - reachable other than via the top of the current binding - level, then create a new BIND_EXPR so that we deallocate - the object at the right time. */ - /* Note that DECL_SIZE can be null due to errors. */ - if (DECL_SIZE (decl) - && !TREE_CONSTANT (DECL_SIZE (decl)) - && STATEMENT_LIST_HAS_LABEL (cur_stmt_list)) - { - tree bind; - bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); - TREE_SIDE_EFFECTS (bind) = 1; - add_stmt (bind); - BIND_EXPR_BODY (bind) = push_stmt_list (); - } - add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), - DECL_EXPR, decl)); - } - } + { + /* In conjunction with an ASMSPEC, the `register' + keyword indicates that we should place the variable + in a particular register. */ + if (asmspec && C_DECL_REGISTER (decl)) + { + DECL_HARD_REGISTER (decl) = 1; + /* This cannot be done for a structure with volatile + fields, on which DECL_REGISTER will have been + reset. */ + if (!DECL_REGISTER (decl)) + error ("cannot put object with volatile field into register"); + } + + if (TREE_CODE (decl) != FUNCTION_DECL) + { + /* If we're building a variable sized type, and we might be + reachable other than via the top of the current binding + level, then create a new BIND_EXPR so that we deallocate + the object at the right time. */ + /* Note that DECL_SIZE can be null due to errors. */ + if (DECL_SIZE (decl) + && !TREE_CONSTANT (DECL_SIZE (decl)) + && STATEMENT_LIST_HAS_LABEL (cur_stmt_list)) + { + tree bind; + bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); + TREE_SIDE_EFFECTS (bind) = 1; + add_stmt (bind); + BIND_EXPR_BODY (bind) = push_stmt_list (); + } + add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), + DECL_EXPR, decl)); + } + } if (!DECL_FILE_SCOPE_P (decl)) - { - /* Recompute the RTL of a local array now - if it used to be an incomplete type. */ - if (was_incomplete - && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) - { - /* If we used it already as memory, it must stay in memory. */ - TREE_ADDRESSABLE (decl) = TREE_USED (decl); - /* If it's still incomplete now, no init will save it. */ - if (DECL_SIZE (decl) == 0) - DECL_INITIAL (decl) = 0; - } - } + { + /* Recompute the RTL of a local array now + if it used to be an incomplete type. */ + if (was_incomplete + && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) + { + /* If we used it already as memory, it must stay in memory. */ + TREE_ADDRESSABLE (decl) = TREE_USED (decl); + /* If it's still incomplete now, no init will save it. */ + if (DECL_SIZE (decl) == 0) + DECL_INITIAL (decl) = 0; + } + } } if (TREE_CODE (decl) == TYPE_DECL) { if (!DECL_FILE_SCOPE_P (decl) - && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) - add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); + && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) + add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl), 0); } @@ -4489,7 +4519,7 @@ { tree attrs = parm->attrs; tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, - NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL); + NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL); decl_attributes (&decl, attrs, 0); @@ -4506,7 +4536,7 @@ tree decl; decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL, - &attrs, NULL, NULL, DEPRECATED_NORMAL); + &attrs, NULL, NULL, DEPRECATED_NORMAL); decl_attributes (&decl, attrs, 0); decl = pushdecl (decl); @@ -4525,7 +4555,7 @@ if (pedantic && !current_scope->warned_forward_parm_decls) { pedwarn (input_location, OPT_pedantic, - "ISO C forbids forward parameter declarations"); + "ISO C forbids forward parameter declarations"); current_scope->warned_forward_parm_decls = true; } @@ -4568,7 +4598,7 @@ if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type)) { int failure = complete_array_type (&TREE_TYPE (decl), - DECL_INITIAL (decl), true); + DECL_INITIAL (decl), true); gcc_assert (!failure); type = TREE_TYPE (decl); @@ -4615,7 +4645,7 @@ && (type_name->specs->typespec_kind == ctsk_tagdef || type_name->specs->typespec_kind == ctsk_tagfirstref)) warning_at (loc, OPT_Wc___compat, - "defining a type in a compound literal is invalid in C++"); + "defining a type in a compound literal is invalid in C++"); } /* Determine whether TYPE is a structure with a flexible array member, @@ -4634,10 +4664,10 @@ while (DECL_CHAIN (x) != NULL_TREE) x = DECL_CHAIN (x); if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE - && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE - && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE - && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE) - return true; + && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE + && TYPE_DOMAIN (TREE_TYPE (x)) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE) + return true; return false; case UNION_TYPE: for (x = TYPE_FIELDS (type); x != NULL_TREE; x = DECL_CHAIN (x)) @@ -4660,8 +4690,8 @@ unsigned int max_width; unsigned HOST_WIDE_INT w; const char *name = (orig_name - ? identifier_to_locale (IDENTIFIER_POINTER (orig_name)) - : _("")); + ? identifier_to_locale (IDENTIFIER_POINTER (orig_name)) + : _("")); /* Detect and ignore out of range field width and process valid field widths. */ @@ -4673,29 +4703,29 @@ else { if (TREE_CODE (*width) != INTEGER_CST) - { - *width = c_fully_fold (*width, false, NULL); - if (TREE_CODE (*width) == INTEGER_CST) - pedwarn (input_location, OPT_pedantic, - "bit-field %qs width not an integer constant expression", - name); - } + { + *width = c_fully_fold (*width, false, NULL); + if (TREE_CODE (*width) == INTEGER_CST) + pedwarn (input_location, OPT_pedantic, + "bit-field %qs width not an integer constant expression", + name); + } if (TREE_CODE (*width) != INTEGER_CST) - { - error ("bit-field %qs width not an integer constant", name); - *width = integer_one_node; - } + { + error ("bit-field %qs width not an integer constant", name); + *width = integer_one_node; + } constant_expression_warning (*width); if (tree_int_cst_sgn (*width) < 0) - { - error ("negative width in bit-field %qs", name); - *width = integer_one_node; - } + { + error ("negative width in bit-field %qs", name); + *width = integer_one_node; + } else if (integer_zerop (*width) && orig_name) - { - error ("zero width for bit-field %qs", name); - *width = integer_one_node; - } + { + error ("zero width for bit-field %qs", name); + *width = integer_one_node; + } } /* Detect invalid bit-field type. */ @@ -4713,7 +4743,7 @@ && type_mv != unsigned_type_node && type_mv != boolean_type_node) pedwarn (input_location, OPT_pedantic, - "type of bit-field %qs is a GCC extension", name); + "type of bit-field %qs is a GCC extension", name); max_width = TYPE_PRECISION (*type); @@ -4730,9 +4760,9 @@ { struct lang_type *lt = TYPE_LANG_SPECIFIC (*type); if (!lt - || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) - || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) - warning (0, "%qs is narrower than values of its type", name); + || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type)) + || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type))) + warning (0, "%qs is narrower than values of its type", name); } } @@ -4748,48 +4778,48 @@ if (!flag_isoc99 && pedantic && warn_vla != 0) { if (const_size) - { - if (name) - pedwarn (input_location, OPT_Wvla, - "ISO C90 forbids array %qE whose size " - "can%'t be evaluated", - name); - else - pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array whose size " - "can%'t be evaluated"); - } + { + if (name) + pedwarn (input_location, OPT_Wvla, + "ISO C90 forbids array %qE whose size " + "can%'t be evaluated", + name); else - { - if (name) - pedwarn (input_location, OPT_Wvla, - "ISO C90 forbids variable length array %qE", - name); - else - pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array"); - } + pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array whose size " + "can%'t be evaluated"); + } + else + { + if (name) + pedwarn (input_location, OPT_Wvla, + "ISO C90 forbids variable length array %qE", + name); + else + pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array"); + } } else if (warn_vla > 0) { if (const_size) { - if (name) - warning (OPT_Wvla, - "the size of array %qE can" - "%'t be evaluated", name); - else - warning (OPT_Wvla, - "the size of array can %'t be evaluated"); - } + if (name) + warning (OPT_Wvla, + "the size of array %qE can" + "%'t be evaluated", name); + else + warning (OPT_Wvla, + "the size of array can %'t be evaluated"); + } else - { - if (name) - warning (OPT_Wvla, - "variable length array %qE is used", - name); - else - warning (OPT_Wvla, - "variable length array is used"); - } + { + if (name) + warning (OPT_Wvla, + "variable length array %qE is used", + name); + else + warning (OPT_Wvla, + "variable length array is used"); + } } } @@ -4862,10 +4892,10 @@ static tree grokdeclarator (const struct c_declarator *declarator, - struct c_declspecs *declspecs, - enum decl_context decl_context, bool initialized, tree *width, - tree *decl_attrs, tree *expr, bool *expr_const_operands, - enum deprecated_states deprecated_state) + struct c_declspecs *declspecs, + enum decl_context decl_context, bool initialized, tree *width, + tree *decl_attrs, tree *expr, bool *expr_const_operands, + enum deprecated_states deprecated_state) { tree type = declspecs->type; bool threadp = declspecs->thread_p; @@ -4913,38 +4943,38 @@ while (decl) switch (decl->kind) - { - case cdk_array: - loc = decl->id_loc; - /* FALL THRU. */ - - case cdk_function: - case cdk_pointer: - funcdef_syntax = (decl->kind == cdk_function); - decl = decl->declarator; - break; - - case cdk_attrs: - decl = decl->declarator; - break; - - case cdk_id: - loc = decl->id_loc; - if (decl->u.id) - name = decl->u.id; - decl = 0; - break; - - default: - gcc_unreachable (); - } + { + case cdk_array: + loc = decl->id_loc; + /* FALL THRU. */ + + case cdk_function: + case cdk_pointer: + funcdef_syntax = (decl->kind == cdk_function); + decl = decl->declarator; + break; + + case cdk_attrs: + decl = decl->declarator; + break; + + case cdk_id: + loc = decl->id_loc; + if (decl->u.id) + name = decl->u.id; + decl = 0; + break; + + default: + gcc_unreachable (); + } if (name == 0) { - gcc_assert (decl_context == PARM - || decl_context == TYPENAME - || (decl_context == FIELD - && declarator->kind == cdk_id)); - gcc_assert (!initialized); + gcc_assert (decl_context == PARM + || decl_context == TYPENAME + || (decl_context == FIELD + && declarator->kind == cdk_id)); + gcc_assert (!initialized); } } @@ -4968,9 +4998,9 @@ && variably_modified_type_p (type, NULL_TREE)) { if (name) - error_at (loc, "variably modified %qE at file scope", name); + error_at (loc, "variably modified %qE at file scope", name); else - error_at (loc, "variably modified field at file scope"); + error_at (loc, "variably modified field at file scope"); type = integer_type_node; } @@ -4981,21 +5011,21 @@ if (declspecs->default_int_p && !in_system_header) { /* Issue a warning if this is an ISO C 99 program or if - -Wreturn-type and this is a function, or if -Wimplicit; - prefer the former warning since it is more explicit. */ + -Wreturn-type and this is a function, or if -Wimplicit; + prefer the former warning since it is more explicit. */ if ((warn_implicit_int || warn_return_type || flag_isoc99) - && funcdef_flag) - warn_about_return_type = 1; + && funcdef_flag) + warn_about_return_type = 1; else - { - if (name) - pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int, - "type defaults to % in declaration of %qE", - name); - else - pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, - "type defaults to % in type name"); - } + { + if (name) + pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int, + "type defaults to % in declaration of %qE", + name); + else + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int, + "type defaults to % in type name"); + } } /* Adjust the type if a bit-field is being declared, @@ -5027,82 +5057,82 @@ if (pedantic && !flag_isoc99) { if (constp > 1) - pedwarn (loc, OPT_pedantic, "duplicate %"); + pedwarn (loc, OPT_pedantic, "duplicate %"); if (restrictp > 1) - pedwarn (loc, OPT_pedantic, "duplicate %"); + pedwarn (loc, OPT_pedantic, "duplicate %"); if (volatilep > 1) - pedwarn (loc, OPT_pedantic, "duplicate %"); + pedwarn (loc, OPT_pedantic, "duplicate %"); } if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2) error_at (loc, "conflicting named address spaces (%s vs %s)", - c_addr_space_name (as1), c_addr_space_name (as2)); + c_addr_space_name (as1), c_addr_space_name (as2)); if (!flag_gen_aux_info && (TYPE_QUALS (element_type))) type = TYPE_MAIN_VARIANT (type); type_quals = ((constp ? TYPE_QUAL_CONST : 0) - | (restrictp ? TYPE_QUAL_RESTRICT : 0) - | (volatilep ? TYPE_QUAL_VOLATILE : 0) - | ENCODE_QUAL_ADDR_SPACE (address_space)); + | (restrictp ? TYPE_QUAL_RESTRICT : 0) + | (volatilep ? TYPE_QUAL_VOLATILE : 0) + | ENCODE_QUAL_ADDR_SPACE (address_space)); /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ if (funcdef_flag && (threadp - || storage_class == csc_auto - || storage_class == csc_register - || storage_class == csc_typedef)) + || storage_class == csc_auto + || storage_class == csc_register + || storage_class == csc_typedef)) { if (storage_class == csc_auto) - pedwarn (loc, - (current_scope == file_scope) ? 0 : OPT_pedantic, - "function definition declared %"); + pedwarn (loc, + (current_scope == file_scope) ? 0 : OPT_pedantic, + "function definition declared %"); if (storage_class == csc_register) - error_at (loc, "function definition declared %"); + error_at (loc, "function definition declared %"); if (storage_class == csc_typedef) - error_at (loc, "function definition declared %"); + error_at (loc, "function definition declared %"); if (threadp) - error_at (loc, "function definition declared %<__thread%>"); + error_at (loc, "function definition declared %<__thread%>"); threadp = false; if (storage_class == csc_auto - || storage_class == csc_register - || storage_class == csc_typedef) - storage_class = csc_none; + || storage_class == csc_register + || storage_class == csc_typedef) + storage_class = csc_none; } else if (decl_context != NORMAL && (storage_class != csc_none || threadp)) { if (decl_context == PARM && storage_class == csc_register) - ; + ; else - { - switch (decl_context) - { - case FIELD: - if (name) - error_at (loc, "storage class specified for structure " - "field %qE", name); - else - error_at (loc, "storage class specified for structure field"); - break; - case PARM: - if (name) - error_at (loc, "storage class specified for parameter %qE", - name); - else - error_at (loc, "storage class specified for unnamed parameter"); - break; - default: - error_at (loc, "storage class specified for typename"); - break; - } - storage_class = csc_none; - threadp = false; - } + { + switch (decl_context) + { + case FIELD: + if (name) + error_at (loc, "storage class specified for structure " + "field %qE", name); + else + error_at (loc, "storage class specified for structure field"); + break; + case PARM: + if (name) + error_at (loc, "storage class specified for parameter %qE", + name); + else + error_at (loc, "storage class specified for unnamed parameter"); + break; + default: + error_at (loc, "storage class specified for typename"); + break; + } + storage_class = csc_none; + threadp = false; + } } else if (storage_class == csc_extern - && initialized - && !funcdef_flag) + && initialized + && !funcdef_flag) { /* 'extern' with initialization is invalid if not at file scope. */ if (current_scope == file_scope) @@ -5111,31 +5141,31 @@ and C++ intersection. */ if (!(warn_cxx_compat && constp)) warning_at (loc, 0, "%qE initialized and declared %", - name); + name); } else - error_at (loc, "%qE has both % and initializer", name); + error_at (loc, "%qE has both % and initializer", name); } else if (current_scope == file_scope) { if (storage_class == csc_auto) - error_at (loc, "file-scope declaration of %qE specifies %", - name); + error_at (loc, "file-scope declaration of %qE specifies %", + name); if (pedantic && storage_class == csc_register) - pedwarn (input_location, OPT_pedantic, - "file-scope declaration of %qE specifies %", name); + pedwarn (input_location, OPT_pedantic, + "file-scope declaration of %qE specifies %", name); } else { if (storage_class == csc_extern && funcdef_flag) - error_at (loc, "nested function %qE declared %", name); + error_at (loc, "nested function %qE declared %", name); else if (threadp && storage_class == csc_none) - { - error_at (loc, "function-scope %qE implicitly auto and declared " - "%<__thread%>", - name); - threadp = false; - } + { + error_at (loc, "function-scope %qE implicitly auto and declared " + "%<__thread%>", + name); + threadp = false; + } } /* Now figure out the structure of the declarator proper. @@ -5151,38 +5181,38 @@ while (declarator && declarator->kind != cdk_id) { if (type == error_mark_node) - { - declarator = declarator->declarator; - continue; - } + { + declarator = declarator->declarator; + continue; + } /* Each level of DECLARATOR is either a cdk_array (for ...[..]), - a cdk_pointer (for *...), - a cdk_function (for ...(...)), - a cdk_attrs (for nested attributes), - or a cdk_id (for the name being declared - or the place in an absolute declarator - where the name was omitted). - For the last case, we have just exited the loop. - - At this point, TYPE is the type of elements of an array, - or for a function to return, or for a pointer to point to. - After this sequence of ifs, TYPE is the type of the - array or function or pointer, and DECLARATOR has had its - outermost layer removed. */ + a cdk_pointer (for *...), + a cdk_function (for ...(...)), + a cdk_attrs (for nested attributes), + or a cdk_id (for the name being declared + or the place in an absolute declarator + where the name was omitted). + For the last case, we have just exited the loop. + + At this point, TYPE is the type of elements of an array, + or for a function to return, or for a pointer to point to. + After this sequence of ifs, TYPE is the type of the + array or function or pointer, and DECLARATOR has had its + outermost layer removed. */ if (array_ptr_quals != TYPE_UNQUALIFIED - || array_ptr_attrs != NULL_TREE - || array_parm_static) - { - /* Only the innermost declarator (making a parameter be of - array type which is converted to pointer type) - may have static or type qualifiers. */ - error_at (loc, "static or type qualifiers in non-parameter array declarator"); - array_ptr_quals = TYPE_UNQUALIFIED; - array_ptr_attrs = NULL_TREE; - array_parm_static = 0; - } + || array_ptr_attrs != NULL_TREE + || array_parm_static) + { + /* Only the innermost declarator (making a parameter be of + array type which is converted to pointer type) + may have static or type qualifiers. */ + error_at (loc, "static or type qualifiers in non-parameter array declarator"); + array_ptr_quals = TYPE_UNQUALIFIED; + array_ptr_attrs = NULL_TREE; + array_parm_static = 0; + } switch (declarator->kind) { @@ -5242,7 +5272,6 @@ "functions"); type = error_mark_node; } - if (pedantic && !in_system_header && flexible_array_type_p (type)) pedwarn (loc, OPT_pedantic, "invalid use of structure with flexible array member"); @@ -5532,6 +5561,7 @@ really_funcdef = (t->kind == cdk_id); } + /* Declaring a function type. Make sure we have a valid type for the function to return. */ if (type == error_mark_node) @@ -5595,7 +5625,16 @@ } type_quals = TYPE_UNQUALIFIED; - type = build_function_type (type, arg_types); +#ifndef noCbC + if ( declspecs->typespec_word == cts_CbC_code ) + { + type = build_code_segment_type (type, arg_types); + } + else +#endif + { + type = build_function_type (type, arg_types); + } declarator = declarator->declarator; /* Set the TYPE_CONTEXTs for each tagged type which is local to @@ -5614,7 +5653,6 @@ { /* Merge any constancy or volatility into the target type for the pointer. */ - if (pedantic && TREE_CODE (type) == FUNCTION_TYPE && type_quals) pedwarn (loc, OPT_pedantic, @@ -5628,16 +5666,13 @@ emitted early enough to dominate all the possible later uses and late enough for the variables on which it depends to have been assigned. - This is expected to happen automatically when the pointed-to type has a name/declaration of it's own, but special attention is required if the type is anonymous. - We handle the NORMAL and FIELD contexts here by attaching an artificial TYPE_DECL to such pointed-to type. This forces the sizes evaluation at a safe point and ensures it is not deferred until e.g. within a deeper conditional context. - We expect nothing to be needed here for PARM or TYPENAME. Pushing a TYPE_DECL at this point for TYPENAME would actually be incorrect, as we might be in the middle of an expression @@ -5663,6 +5698,7 @@ that were given inside the `*'. */ type_quals = declarator->u.pointer_quals; + declarator = declarator->declarator; break; } @@ -5681,51 +5717,51 @@ if (!ADDR_SPACE_GENERIC_P (address_space)) { if (decl_context == NORMAL) - { - switch (storage_class) - { - case csc_auto: - error ("%qs combined with % qualifier for %qE", - c_addr_space_name (address_space), name); - break; - case csc_register: - error ("%qs combined with % qualifier for %qE", - c_addr_space_name (address_space), name); - break; - case csc_none: - if (current_function_scope) - { - error ("%qs specified for auto variable %qE", - c_addr_space_name (address_space), name); - break; - } - break; - case csc_static: - case csc_extern: - case csc_typedef: - break; - default: - gcc_unreachable (); - } - } + { + switch (storage_class) + { + case csc_auto: + error ("%qs combined with % qualifier for %qE", + c_addr_space_name (address_space), name); + break; + case csc_register: + error ("%qs combined with % qualifier for %qE", + c_addr_space_name (address_space), name); + break; + case csc_none: + if (current_function_scope) + { + error ("%qs specified for auto variable %qE", + c_addr_space_name (address_space), name); + break; + } + break; + case csc_static: + case csc_extern: + case csc_typedef: + break; + default: + gcc_unreachable (); + } + } else if (decl_context == PARM && TREE_CODE (type) != ARRAY_TYPE) - { - if (name) - error ("%qs specified for parameter %qE", - c_addr_space_name (address_space), name); - else - error ("%qs specified for unnamed parameter", - c_addr_space_name (address_space)); - } + { + if (name) + error ("%qs specified for parameter %qE", + c_addr_space_name (address_space), name); + else + error ("%qs specified for unnamed parameter", + c_addr_space_name (address_space)); + } else if (decl_context == FIELD) - { - if (name) - error ("%qs specified for structure field %qE", - c_addr_space_name (address_space), name); - else - error ("%qs specified for structure field", - c_addr_space_name (address_space)); - } + { + if (name) + error ("%qs specified for structure field %qE", + c_addr_space_name (address_space), name); + else + error ("%qs specified for structure field", + c_addr_space_name (address_space)); + } } /* Check the type and width of a bit-field. */ @@ -5740,11 +5776,11 @@ && TREE_OVERFLOW (TYPE_SIZE_UNIT (type))) { if (name) - error_at (loc, "size of array %qE is too large", name); + error_at (loc, "size of array %qE is too large", name); else - error_at (loc, "size of unnamed array is too large"); + error_at (loc, "size of unnamed array is too large"); /* If we proceed with the array type as it is, we'll eventually - crash in tree_low_cst(). */ + crash in tree_low_cst(). */ type = error_mark_node; } @@ -5754,36 +5790,36 @@ { tree decl; if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && type_quals) - pedwarn (loc, OPT_pedantic, - "ISO C forbids qualified function types"); + && type_quals) + pedwarn (loc, OPT_pedantic, + "ISO C forbids qualified function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals); decl = build_decl (declarator->id_loc, - TYPE_DECL, declarator->u.id, type); + TYPE_DECL, declarator->u.id, type); if (declspecs->explicit_signed_p) - C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; + C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; if (declspecs->inline_p) - pedwarn (loc, 0,"typedef %q+D declared %", decl); + pedwarn (loc, 0,"typedef %q+D declared %", decl); if (warn_cxx_compat && declarator->u.id != NULL_TREE) - { - struct c_binding *b = I_TAG_BINDING (declarator->u.id); - - if (b != NULL - && b->decl != NULL_TREE - && (B_IN_CURRENT_SCOPE (b) - || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) - && TYPE_MAIN_VARIANT (b->decl) != TYPE_MAIN_VARIANT (type)) - { - warning_at (declarator->id_loc, OPT_Wc___compat, - ("using %qD as both a typedef and a tag is " - "invalid in C++"), - decl); - if (b->locus != UNKNOWN_LOCATION) - inform (b->locus, "originally defined here"); - } - } + { + struct c_binding *b = I_TAG_BINDING (declarator->u.id); + + if (b != NULL + && b->decl != NULL_TREE + && (B_IN_CURRENT_SCOPE (b) + || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b))) + && TYPE_MAIN_VARIANT (b->decl) != TYPE_MAIN_VARIANT (type)) + { + warning_at (declarator->id_loc, OPT_Wc___compat, + ("using %qD as both a typedef and a tag is " + "invalid in C++"), + decl); + if (b->locus != UNKNOWN_LOCATION) + inform (b->locus, "originally defined here"); + } + } return decl; } @@ -5794,15 +5830,15 @@ if (decl_context == TYPENAME) { /* Note that the grammar rejects storage classes in typenames - and fields. */ + and fields. */ gcc_assert (storage_class == csc_none && !threadp - && !declspecs->inline_p); + && !declspecs->inline_p); if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && type_quals) - pedwarn (loc, OPT_pedantic, - "ISO C forbids const or volatile function types"); + && type_quals) + pedwarn (loc, OPT_pedantic, + "ISO C forbids const or volatile function types"); if (type_quals) - type = c_build_qualified_type (type, type_quals); + type = c_build_qualified_type (type, type_quals); return type; } @@ -5811,7 +5847,7 @@ { /* C99 6.7.2.1p8 */ pedwarn (loc, OPT_pedantic, "a member of a structure or union cannot " - "have a variably modified type"); + "have a variably modified type"); } /* Aside from typedefs and type names (handle above), @@ -5822,10 +5858,10 @@ if (VOID_TYPE_P (type) && decl_context != PARM && !((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE) - && (storage_class == csc_extern - || (current_scope == file_scope - && !(storage_class == csc_static - || storage_class == csc_register))))) + && (storage_class == csc_extern + || (current_scope == file_scope + && !(storage_class == csc_static + || storage_class == csc_register))))) { error_at (loc, "variable or field %qE declared void", name); type = integer_type_node; @@ -5839,93 +5875,93 @@ if (decl_context == PARM) { - tree promoted_type; - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Transfer const-ness of array into that of type pointed to. */ - type = TREE_TYPE (type); - if (type_quals) - type = c_build_qualified_type (type, type_quals); - type = build_pointer_type (type); - type_quals = array_ptr_quals; - if (type_quals) - type = c_build_qualified_type (type, type_quals); - - /* We don't yet implement attributes in this context. */ - if (array_ptr_attrs != NULL_TREE) - warning_at (loc, OPT_Wattributes, - "attributes in parameter array declarator ignored"); - - size_varies = false; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - if (type_quals) - pedwarn (loc, OPT_pedantic, - "ISO C forbids qualified function types"); - if (type_quals) - type = c_build_qualified_type (type, type_quals); - type = build_pointer_type (type); - type_quals = TYPE_UNQUALIFIED; - } - else if (type_quals) - type = c_build_qualified_type (type, type_quals); - - decl = build_decl (declarator->id_loc, - PARM_DECL, declarator->u.id, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - if (type == error_mark_node) - promoted_type = type; - else - promoted_type = c_type_promotes_to (type); - - DECL_ARG_TYPE (decl) = promoted_type; - if (declspecs->inline_p) - pedwarn (loc, 0, "parameter %q+D declared %", decl); + tree promoted_type; + + /* A parameter declared as an array of T is really a pointer to T. + One declared as a function is really a pointer to a function. */ + + if (TREE_CODE (type) == ARRAY_TYPE) + { + /* Transfer const-ness of array into that of type pointed to. */ + type = TREE_TYPE (type); + if (type_quals) + type = c_build_qualified_type (type, type_quals); + type = build_pointer_type (type); + type_quals = array_ptr_quals; + if (type_quals) + type = c_build_qualified_type (type, type_quals); + + /* We don't yet implement attributes in this context. */ + if (array_ptr_attrs != NULL_TREE) + warning_at (loc, OPT_Wattributes, + "attributes in parameter array declarator ignored"); + + size_varies = false; + } + else if (TREE_CODE (type) == FUNCTION_TYPE) + { + if (type_quals) + pedwarn (loc, OPT_pedantic, + "ISO C forbids qualified function types"); + if (type_quals) + type = c_build_qualified_type (type, type_quals); + type = build_pointer_type (type); + type_quals = TYPE_UNQUALIFIED; + } + else if (type_quals) + type = c_build_qualified_type (type, type_quals); + + decl = build_decl (declarator->id_loc, + PARM_DECL, declarator->u.id, type); + if (size_varies) + C_DECL_VARIABLE_SIZE (decl) = 1; + + /* Compute the type actually passed in the parmlist, + for the case where there is no prototype. + (For example, shorts and chars are passed as ints.) + When there is a prototype, this is overridden later. */ + + if (type == error_mark_node) + promoted_type = type; + else + promoted_type = c_type_promotes_to (type); + + DECL_ARG_TYPE (decl) = promoted_type; + if (declspecs->inline_p) + pedwarn (loc, 0, "parameter %q+D declared %", decl); } else if (decl_context == FIELD) { - /* Note that the grammar rejects storage classes in typenames - and fields. */ - gcc_assert (storage_class == csc_none && !threadp - && !declspecs->inline_p); - - /* Structure field. It may not be a function. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error_at (loc, "field %qE declared as a function", name); - type = build_pointer_type (type); - } - else if (TREE_CODE (type) != ERROR_MARK - && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type)) - { - if (name) - error_at (loc, "field %qE has incomplete type", name); - else - error_at (loc, "unnamed field has incomplete type"); - type = error_mark_node; - } - type = c_build_qualified_type (type, type_quals); - decl = build_decl (declarator->id_loc, - FIELD_DECL, declarator->u.id, type); - DECL_NONADDRESSABLE_P (decl) = bitfield; - if (bitfield && !declarator->u.id) - TREE_NO_WARNING (decl) = 1; - - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; + /* Note that the grammar rejects storage classes in typenames + and fields. */ + gcc_assert (storage_class == csc_none && !threadp + && !declspecs->inline_p); + + /* Structure field. It may not be a function. */ + + if (TREE_CODE (type) == FUNCTION_TYPE) + { + error_at (loc, "field %qE declared as a function", name); + type = build_pointer_type (type); + } + else if (TREE_CODE (type) != ERROR_MARK + && !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type)) + { + if (name) + error_at (loc, "field %qE has incomplete type", name); + else + error_at (loc, "unnamed field has incomplete type"); + type = error_mark_node; + } + type = c_build_qualified_type (type, type_quals); + decl = build_decl (declarator->id_loc, + FIELD_DECL, declarator->u.id, type); + DECL_NONADDRESSABLE_P (decl) = bitfield; + if (bitfield && !declarator->u.id) + TREE_NO_WARNING (decl) = 1; + + if (size_varies) + C_DECL_VARIABLE_SIZE (decl) = 1; } else if (TREE_CODE (type) == FUNCTION_TYPE) { @@ -5953,6 +5989,7 @@ } } + decl = build_decl (declarator->id_loc, FUNCTION_DECL, declarator->u.id, type); decl = build_decl_attribute_variant (decl, decl_attr); @@ -6003,76 +6040,76 @@ } else { - /* It's a variable. */ - /* An uninitialized decl with `extern' is a reference. */ - int extern_ref = !initialized && storage_class == csc_extern; - - type = c_build_qualified_type (type, type_quals); - - /* C99 6.2.2p7: It is invalid (compile-time undefined - behavior) to create an 'extern' declaration for a - variable if there is a global declaration that is - 'static' and the global declaration is not visible. - (If the static declaration _is_ currently visible, - the 'extern' declaration is taken to refer to that decl.) */ - if (extern_ref && current_scope != file_scope) - { - tree global_decl = identifier_global_value (declarator->u.id); - tree visible_decl = lookup_name (declarator->u.id); - - if (global_decl - && global_decl != visible_decl - && TREE_CODE (global_decl) == VAR_DECL - && !TREE_PUBLIC (global_decl)) - error_at (loc, "variable previously declared % " - "redeclared %"); - } - - decl = build_decl (declarator->id_loc, - VAR_DECL, declarator->u.id, type); - if (size_varies) - C_DECL_VARIABLE_SIZE (decl) = 1; - - if (declspecs->inline_p) - pedwarn (loc, 0, "variable %q+D declared %", decl); - - /* At file scope, an initialized extern declaration may follow - a static declaration. In that case, DECL_EXTERNAL will be - reset later in start_decl. */ - DECL_EXTERNAL (decl) = (storage_class == csc_extern); - - /* At file scope, the presence of a `static' or `register' storage - class specifier, or the absence of all storage class specifiers - makes this declaration a definition (perhaps tentative). Also, - the absence of `static' makes it public. */ - if (current_scope == file_scope) - { - TREE_PUBLIC (decl) = storage_class != csc_static; - TREE_STATIC (decl) = !extern_ref; - } - /* Not at file scope, only `static' makes a static definition. */ - else - { - TREE_STATIC (decl) = (storage_class == csc_static); - TREE_PUBLIC (decl) = extern_ref; - } - - if (threadp) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + /* It's a variable. */ + /* An uninitialized decl with `extern' is a reference. */ + int extern_ref = !initialized && storage_class == csc_extern; + + type = c_build_qualified_type (type, type_quals); + + /* C99 6.2.2p7: It is invalid (compile-time undefined + behavior) to create an 'extern' declaration for a + variable if there is a global declaration that is + 'static' and the global declaration is not visible. + (If the static declaration _is_ currently visible, + the 'extern' declaration is taken to refer to that decl.) */ + if (extern_ref && current_scope != file_scope) + { + tree global_decl = identifier_global_value (declarator->u.id); + tree visible_decl = lookup_name (declarator->u.id); + + if (global_decl + && global_decl != visible_decl + && TREE_CODE (global_decl) == VAR_DECL + && !TREE_PUBLIC (global_decl)) + error_at (loc, "variable previously declared % " + "redeclared %"); + } + + decl = build_decl (declarator->id_loc, + VAR_DECL, declarator->u.id, type); + if (size_varies) + C_DECL_VARIABLE_SIZE (decl) = 1; + + if (declspecs->inline_p) + pedwarn (loc, 0, "variable %q+D declared %", decl); + + /* At file scope, an initialized extern declaration may follow + a static declaration. In that case, DECL_EXTERNAL will be + reset later in start_decl. */ + DECL_EXTERNAL (decl) = (storage_class == csc_extern); + + /* At file scope, the presence of a `static' or `register' storage + class specifier, or the absence of all storage class specifiers + makes this declaration a definition (perhaps tentative). Also, + the absence of `static' makes it public. */ + if (current_scope == file_scope) + { + TREE_PUBLIC (decl) = storage_class != csc_static; + TREE_STATIC (decl) = !extern_ref; + } + /* Not at file scope, only `static' makes a static definition. */ + else + { + TREE_STATIC (decl) = (storage_class == csc_static); + TREE_PUBLIC (decl) = extern_ref; + } + + if (threadp) + DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); } if ((storage_class == csc_extern - || (storage_class == csc_none - && TREE_CODE (type) == FUNCTION_TYPE - && !funcdef_flag)) - && variably_modified_type_p (type, NULL_TREE)) + || (storage_class == csc_none + && TREE_CODE (type) == FUNCTION_TYPE + && !funcdef_flag)) + && variably_modified_type_p (type, NULL_TREE)) { - /* C99 6.7.5.2p2 */ - if (TREE_CODE (type) == FUNCTION_TYPE) - error_at (loc, "non-nested function with variably modified type"); - else - error_at (loc, "object with variably modified type must have " - "no linkage"); + /* C99 6.7.5.2p2 */ + if (TREE_CODE (type) == FUNCTION_TYPE) + error_at (loc, "non-nested function with variably modified type"); + else + error_at (loc, "object with variably modified type must have " + "no linkage"); } /* Record `register' declaration for warnings on & @@ -6080,8 +6117,8 @@ if (storage_class == csc_register) { - C_DECL_REGISTER (decl) = 1; - DECL_REGISTER (decl) = 1; + C_DECL_REGISTER (decl) = 1; + DECL_REGISTER (decl) = 1; } /* Record constancy and volatility. */ @@ -6092,17 +6129,17 @@ will be ignored, and would even crash the compiler. Of course, this only makes sense on VAR,PARM, and RESULT decl's. */ if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)) - && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == RESULT_DECL)) + && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL + || TREE_CODE (decl) == RESULT_DECL)) { - /* It is not an error for a structure with volatile fields to - be declared register, but reset DECL_REGISTER since it - cannot actually go in a register. */ - int was_reg = C_DECL_REGISTER (decl); - C_DECL_REGISTER (decl) = 0; - DECL_REGISTER (decl) = 0; - c_mark_addressable (decl); - C_DECL_REGISTER (decl) = was_reg; + /* It is not an error for a structure with volatile fields to + be declared register, but reset DECL_REGISTER since it + cannot actually go in a register. */ + int was_reg = C_DECL_REGISTER (decl); + C_DECL_REGISTER (decl) = 0; + DECL_REGISTER (decl) = 0; + c_mark_addressable (decl); + C_DECL_REGISTER (decl) = was_reg; } /* This is the earliest point at which we might know the assembler @@ -6110,17 +6147,17 @@ gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)); if (warn_cxx_compat - && TREE_CODE (decl) == VAR_DECL - && TREE_PUBLIC (decl) - && TREE_STATIC (decl) - && (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE - || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) - && TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE) + && TREE_CODE (decl) == VAR_DECL + && TREE_PUBLIC (decl) + && TREE_STATIC (decl) + && (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE + || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) + && TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE) warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, - ("non-local variable %qD with anonymous type is " - "questionable in C++"), - decl); + ("non-local variable %qD with anonymous type is " + "questionable in C++"), + decl); return decl; } @@ -6154,7 +6191,7 @@ if (arg_types == 0 && !funcdef_flag && !in_system_header) warning (OPT_Wstrict_prototypes, - "function declaration isn%'t a prototype"); + "function declaration isn%'t a prototype"); if (arg_types == error_mark_node) return 0; /* don't set TYPE_ARG_TYPES in this case */ @@ -6168,7 +6205,6 @@ } else arg_info->parms = arg_info->types; - arg_info->types = 0; return 0; } @@ -6179,13 +6215,13 @@ const char *errmsg; /* If there is a parameter of incomplete type in a definition, - this is an error. In a declaration this is valid, and a - struct or union type may be completed later, before any calls - or definition of the function. In the case where the tag was - first declared within the parameter list, a warning has - already been given. If a parameter has void type, then - however the function cannot be defined or called, so - warn. */ + this is an error. In a declaration this is valid, and a + struct or union type may be completed later, before any calls + or definition of the function. In the case where the tag was + first declared within the parameter list, a warning has + already been given. If a parameter has void type, then + however the function cannot be defined or called, so + warn. */ for (parm = arg_info->parms, typelt = arg_types, parmno = 1; parm; @@ -6294,19 +6330,19 @@ (by 'const' or 'volatile'), or has a storage class specifier ('register'), then the behavior is undefined; issue an error. Typedefs for 'void' are OK (see DR#157). */ - if (b->prev == 0 /* one binding */ + if (b->prev == 0 /* one binding */ && TREE_CODE (b->decl) == PARM_DECL /* which is a parameter */ && !DECL_NAME (b->decl) /* anonymous */ && VOID_TYPE_P (TREE_TYPE (b->decl))) /* of void type */ { if (TREE_THIS_VOLATILE (b->decl) - || TREE_READONLY (b->decl) - || C_DECL_REGISTER (b->decl)) - error ("% as only parameter may not be qualified"); + || TREE_READONLY (b->decl) + || C_DECL_REGISTER (b->decl)) + error ("% as only parameter may not be qualified"); /* There cannot be an ellipsis. */ if (ellipsis) - error ("% must be the only parameter"); + error ("% must be the only parameter"); arg_info->types = void_list_node; return arg_info; @@ -6480,33 +6516,33 @@ if (ref && TREE_CODE (ref) == code) { if (C_TYPE_DEFINED_IN_STRUCT (ref) - && loc != UNKNOWN_LOCATION - && warn_cxx_compat) - { - switch (code) - { - case ENUMERAL_TYPE: - warning_at (loc, OPT_Wc___compat, - ("enum type defined in struct or union " - "is not visible in C++")); - inform (refloc, "enum type defined here"); - break; - case RECORD_TYPE: - warning_at (loc, OPT_Wc___compat, - ("struct defined in struct or union " - "is not visible in C++")); - inform (refloc, "struct defined here"); - break; - case UNION_TYPE: - warning_at (loc, OPT_Wc___compat, - ("union defined in struct or union " - "is not visible in C++")); - inform (refloc, "union defined here"); - break; - default: - gcc_unreachable(); - } - } + && loc != UNKNOWN_LOCATION + && warn_cxx_compat) + { + switch (code) + { + case ENUMERAL_TYPE: + warning_at (loc, OPT_Wc___compat, + ("enum type defined in struct or union " + "is not visible in C++")); + inform (refloc, "enum type defined here"); + break; + case RECORD_TYPE: + warning_at (loc, OPT_Wc___compat, + ("struct defined in struct or union " + "is not visible in C++")); + inform (refloc, "struct defined here"); + break; + case UNION_TYPE: + warning_at (loc, OPT_Wc___compat, + ("union defined in struct or union " + "is not visible in C++")); + inform (refloc, "union defined here"); + break; + default: + gcc_unreachable(); + } + } ret.spec = ref; return ret; @@ -6521,7 +6557,7 @@ if (code == ENUMERAL_TYPE) { /* Give the type a default layout like unsigned int - to avoid crashing if it does not get defined. */ + to avoid crashing if it does not get defined. */ SET_TYPE_MODE (ref, TYPE_MODE (unsigned_type_node)); TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); TYPE_USER_ALIGN (ref) = 0; @@ -6559,7 +6595,7 @@ tree start_struct (location_t loc, enum tree_code code, tree name, - struct c_struct_parse_info **enclosing_struct_parse_info) + struct c_struct_parse_info **enclosing_struct_parse_info) { /* If there is already a tag defined at this scope (as a forward reference), just return it. */ @@ -6572,28 +6608,28 @@ if (ref && TREE_CODE (ref) == code) { if (TYPE_SIZE (ref)) - { - if (code == UNION_TYPE) - error_at (loc, "redefinition of %", name); - else - error_at (loc, "redefinition of %", name); - if (refloc != UNKNOWN_LOCATION) - inform (refloc, "originally defined here"); - /* Don't create structures using a name already in use. */ - ref = NULL_TREE; - } + { + if (code == UNION_TYPE) + error_at (loc, "redefinition of %", name); + else + error_at (loc, "redefinition of %", name); + if (refloc != UNKNOWN_LOCATION) + inform (refloc, "originally defined here"); + /* Don't create structures using a name already in use. */ + ref = NULL_TREE; + } else if (C_TYPE_BEING_DEFINED (ref)) - { - if (code == UNION_TYPE) - error_at (loc, "nested redefinition of %", name); - else - error_at (loc, "nested redefinition of %", name); - /* Don't bother to report "originally defined here" for a - nested redefinition; the original definition should be - obvious. */ - /* Don't create structures that contain themselves. */ - ref = NULL_TREE; - } + { + if (code == UNION_TYPE) + error_at (loc, "nested redefinition of %", name); + else + error_at (loc, "nested redefinition of %", name); + /* Don't bother to report "originally defined here" for a + nested redefinition; the original definition should be + obvious. */ + /* Don't create structures that contain themselves. */ + ref = NULL_TREE; + } } /* Otherwise create a forward-reference just so the tag is in scope. */ @@ -6619,10 +6655,10 @@ sizeof anyhow. */ if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) warning_at (loc, OPT_Wc___compat, - "defining type in %qs expression is invalid in C++", - (in_sizeof - ? "sizeof" - : (in_typeof ? "typeof" : "alignof"))); + "defining type in %qs expression is invalid in C++", + (in_sizeof + ? "sizeof" + : (in_typeof ? "typeof" : "alignof"))); return ref; } @@ -6640,8 +6676,8 @@ tree grokfield (location_t loc, - struct c_declarator *declarator, struct c_declspecs *declspecs, - tree width, tree *decl_attrs) + struct c_declarator *declarator, struct c_declspecs *declspecs, + tree width, tree *decl_attrs) { tree value; @@ -6671,7 +6707,7 @@ tree type = declspecs->type; bool type_ok = (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE); + || TREE_CODE (type) == UNION_TYPE); bool ok = false; if (type_ok) @@ -6683,6 +6719,8 @@ else ok = false; } + + if (!ok) { pedwarn (loc, 0, "declaration does not declare anything"); @@ -6700,8 +6738,8 @@ } value = grokdeclarator (declarator, declspecs, FIELD, false, - width ? &width : NULL, decl_attrs, NULL, NULL, - DEPRECATED_NORMAL); + width ? &width : NULL, decl_attrs, NULL, NULL, + DEPRECATED_NORMAL); finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE); DECL_INITIAL (value) = width; @@ -6709,20 +6747,20 @@ if (warn_cxx_compat && DECL_NAME (value) != NULL_TREE) { /* If we currently have a binding for this field, set the - in_struct field in the binding, so that we warn about lookups - which find it. */ + in_struct field in the binding, so that we warn about lookups + which find it. */ struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (value)); if (b != NULL) - { - /* If the in_struct field is not yet set, push it on a list - to be cleared when this struct is finished. */ - if (!b->in_struct) - { - VEC_safe_push (c_binding_ptr, heap, - struct_parse_info->fields, b); - b->in_struct = 1; - } - } + { + /* If the in_struct field is not yet set, push it on a list + to be cleared when this struct is finished. */ + if (!b->in_struct) + { + VEC_safe_push (c_binding_ptr, heap, + struct_parse_info->fields, b); + b->in_struct = 1; + } + } } return value; @@ -6906,7 +6944,7 @@ && fieldlist != NULL_TREE) { /* Use a pointer_set using the name of the typedef. We can use - a pointer_set because identifiers are interned. */ + a pointer_set because identifiers are interned. */ struct pointer_set_t *tset = pointer_set_create (); FOR_EACH_VEC_ELT (tree, struct_parse_info->typedefs_seen, ix, x) @@ -6925,7 +6963,6 @@ the typedef name is used. */ } } - pointer_set_destroy (tset); } @@ -6945,7 +6982,7 @@ tree finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, - struct c_struct_parse_info *enclosing_struct_parse_info) + struct c_struct_parse_info *enclosing_struct_parse_info) { tree x; bool toplevel = file_scope == current_scope; @@ -6971,22 +7008,22 @@ } if (x == 0) - { - if (TREE_CODE (t) == UNION_TYPE) - { - if (fieldlist) - pedwarn (loc, OPT_pedantic, "union has no named members"); - else - pedwarn (loc, OPT_pedantic, "union has no members"); - } - else - { - if (fieldlist) - pedwarn (loc, OPT_pedantic, "struct has no named members"); - else - pedwarn (loc, OPT_pedantic, "struct has no members"); - } - } + { + if (TREE_CODE (t) == UNION_TYPE) + { + if (fieldlist) + pedwarn (loc, OPT_pedantic, "union has no named members"); + else + pedwarn (loc, OPT_pedantic, "union has no members"); + } + else + { + if (fieldlist) + pedwarn (loc, OPT_pedantic, "struct has no named members"); + else + pedwarn (loc, OPT_pedantic, "struct has no members"); + } + } } /* Install struct as DECL_CONTEXT of each field decl. @@ -7000,13 +7037,13 @@ for (x = fieldlist; x; x = DECL_CHAIN (x)) { if (TREE_TYPE (x) == error_mark_node) - continue; + continue; DECL_CONTEXT (x) = t; /* If any field is const, the structure type is pseudo-const. */ if (TREE_READONLY (x)) - C_TYPE_FIELDS_READONLY (t) = 1; + C_TYPE_FIELDS_READONLY (t) = 1; else { /* A field that is pseudo-const makes the structure likewise. */ @@ -7017,26 +7054,26 @@ } /* Any field that is volatile means variables of this type must be - treated in some ways as volatile. */ + treated in some ways as volatile. */ if (TREE_THIS_VOLATILE (x)) - C_TYPE_FIELDS_VOLATILE (t) = 1; + C_TYPE_FIELDS_VOLATILE (t) = 1; /* Any field of nominal variable size implies structure is too. */ if (C_DECL_VARIABLE_SIZE (x)) - C_TYPE_VARIABLE_SIZE (t) = 1; + C_TYPE_VARIABLE_SIZE (t) = 1; if (DECL_INITIAL (x)) - { - unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1); - DECL_SIZE (x) = bitsize_int (width); - DECL_BIT_FIELD (x) = 1; - SET_DECL_C_BIT_FIELD (x); - } + { + unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1); + DECL_SIZE (x) = bitsize_int (width); + DECL_BIT_FIELD (x) = 1; + SET_DECL_C_BIT_FIELD (x); + } if (TYPE_PACKED (t) - && (DECL_BIT_FIELD (x) - || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)) - DECL_PACKED (x) = 1; + && (DECL_BIT_FIELD (x) + || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)) + DECL_PACKED (x) = 1; /* Detect flexible array member in an invalid context. */ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE @@ -7065,9 +7102,9 @@ } if (pedantic && TREE_CODE (t) == RECORD_TYPE - && flexible_array_type_p (TREE_TYPE (x))) - pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic, - "invalid use of structure with flexible array member"); + && flexible_array_type_p (TREE_TYPE (x))) + pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic, + "invalid use of structure with flexible array member"); if (DECL_NAME (x) || TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE @@ -7089,19 +7126,19 @@ tree *fieldlistp = &fieldlist; while (*fieldlistp) if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp) - && TREE_TYPE (*fieldlistp) != error_mark_node) - { - unsigned HOST_WIDE_INT width - = tree_low_cst (DECL_INITIAL (*fieldlistp), 1); - tree type = TREE_TYPE (*fieldlistp); - if (width != TYPE_PRECISION (type)) - { - TREE_TYPE (*fieldlistp) - = c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type)); - DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp)); - } - DECL_INITIAL (*fieldlistp) = 0; - } + && TREE_TYPE (*fieldlistp) != error_mark_node) + { + unsigned HOST_WIDE_INT width + = tree_low_cst (DECL_INITIAL (*fieldlistp), 1); + tree type = TREE_TYPE (*fieldlistp); + if (width != TYPE_PRECISION (type)) + { + TREE_TYPE (*fieldlistp) + = c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type)); + DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp)); + } + DECL_INITIAL (*fieldlistp) = 0; + } else fieldlistp = &DECL_CHAIN (*fieldlistp); } @@ -7119,9 +7156,9 @@ for (x = fieldlist; x; x = DECL_CHAIN (x)) { - if (len > 15 || DECL_NAME (x) == NULL) - break; - len += 1; + if (len > 15 || DECL_NAME (x) == NULL) + break; + len += 1; } if (len > 15) @@ -7189,16 +7226,16 @@ { tree decl = TREE_VALUE (x); if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - layout_array_type (TREE_TYPE (decl)); + layout_array_type (TREE_TYPE (decl)); if (TREE_CODE (decl) != TYPE_DECL) - { - layout_decl (decl, 0); - if (c_dialect_objc ()) - objc_check_decl (decl); - rest_of_decl_compilation (decl, toplevel, 0); - if (!toplevel) - expand_decl (decl); - } + { + layout_decl (decl, 0); + if (c_dialect_objc ()) + objc_check_decl (decl); + rest_of_decl_compilation (decl, toplevel, 0); + if (!toplevel) + expand_decl (decl); + } } C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0; @@ -7215,7 +7252,7 @@ to be bound now. */ if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE)) add_stmt (build_stmt (loc, - DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t))); + DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t))); if (warn_cxx_compat) warn_cxx_compat_finish_struct (fieldlist); @@ -7283,10 +7320,10 @@ /* This enum is a named one that has been declared already. */ error_at (loc, "redeclaration of %", name); if (enumloc != UNKNOWN_LOCATION) - inform (enumloc, "originally defined here"); + inform (enumloc, "originally defined here"); /* Completely replace its old definition. - The old enumerators remain defined, however. */ + The old enumerators remain defined, however. */ TYPE_VALUES (enumtype) = 0; } @@ -7301,10 +7338,10 @@ as C++ doesn't permit statement exprs within sizeof anyhow. */ if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) warning_at (loc, OPT_Wc___compat, - "defining type in %qs expression is invalid in C++", - (in_sizeof - ? "sizeof" - : (in_typeof ? "typeof" : "alignof"))); + "defining type in %qs expression is invalid in C++", + (in_sizeof + ? "sizeof" + : (in_typeof ? "typeof" : "alignof"))); return enumtype; } @@ -7334,13 +7371,13 @@ { minnode = maxnode = TREE_VALUE (values); for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair)) - { - tree value = TREE_VALUE (pair); - if (tree_int_cst_lt (maxnode, value)) - maxnode = value; - if (tree_int_cst_lt (value, minnode)) - minnode = value; - } + { + tree value = TREE_VALUE (pair); + if (tree_int_cst_lt (maxnode, value)) + maxnode = value; + if (tree_int_cst_lt (value, minnode)) + minnode = value; + } } /* Construct the final type of this enumeration. It is the same @@ -7349,16 +7386,16 @@ the values are negative. */ unsign = (tree_int_cst_sgn (minnode) >= 0); precision = MAX (tree_int_cst_min_precision (minnode, unsign), - tree_int_cst_min_precision (maxnode, unsign)); + tree_int_cst_min_precision (maxnode, unsign)); if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node)) { tem = c_common_type_for_size (precision, unsign); if (tem == NULL) - { - warning (0, "enumeration values exceed range of largest integer"); - tem = long_long_integer_type_node; - } + { + warning (0, "enumeration values exceed range of largest integer"); + tem = long_long_integer_type_node; + } } else tem = unsign ? unsigned_type_node : integer_type_node; @@ -7373,7 +7410,7 @@ if (TYPE_PRECISION (enumtype)) { if (precision > TYPE_PRECISION (enumtype)) - error ("specified mode too small for enumeral values"); + error ("specified mode too small for enumeral values"); } else TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem); @@ -7383,36 +7420,36 @@ if (values != error_mark_node) { /* Change the type of the enumerators to be the enum type. We - need to do this irrespective of the size of the enum, for - proper type checking. Replace the DECL_INITIALs of the - enumerators, and the value slots of the list, with copies - that have the enum type; they cannot be modified in place - because they may be shared (e.g. integer_zero_node) Finally, - change the purpose slots to point to the names of the decls. */ + need to do this irrespective of the size of the enum, for + proper type checking. Replace the DECL_INITIALs of the + enumerators, and the value slots of the list, with copies + that have the enum type; they cannot be modified in place + because they may be shared (e.g. integer_zero_node) Finally, + change the purpose slots to point to the names of the decls. */ for (pair = values; pair; pair = TREE_CHAIN (pair)) - { - tree enu = TREE_PURPOSE (pair); - tree ini = DECL_INITIAL (enu); - - TREE_TYPE (enu) = enumtype; - - /* The ISO C Standard mandates enumerators to have type int, - even though the underlying type of an enum type is - unspecified. However, GCC allows enumerators of any - integer type as an extensions. build_enumerator() - converts any enumerators that fit in an int to type int, - to avoid promotions to unsigned types when comparing - integers with enumerators that fit in the int range. - When -pedantic is given, build_enumerator() would have - already warned about those that don't fit. Here we - convert the rest to the enumerator type. */ - if (TREE_TYPE (ini) != integer_type_node) - ini = convert (enumtype, ini); - - DECL_INITIAL (enu) = ini; - TREE_PURPOSE (pair) = DECL_NAME (enu); - TREE_VALUE (pair) = ini; - } + { + tree enu = TREE_PURPOSE (pair); + tree ini = DECL_INITIAL (enu); + + TREE_TYPE (enu) = enumtype; + + /* The ISO C Standard mandates enumerators to have type int, + even though the underlying type of an enum type is + unspecified. However, GCC allows enumerators of any + integer type as an extensions. build_enumerator() + converts any enumerators that fit in an int to type int, + to avoid promotions to unsigned types when comparing + integers with enumerators that fit in the int range. + When -pedantic is given, build_enumerator() would have + already warned about those that don't fit. Here we + convert the rest to the enumerator type. */ + if (TREE_TYPE (ini) != integer_type_node) + ini = convert (enumtype, ini); + + DECL_INITIAL (enu) = ini; + TREE_PURPOSE (pair) = DECL_NAME (enu); + TREE_VALUE (pair) = ini; + } TYPE_VALUES (enumtype) = values; } @@ -7428,7 +7465,7 @@ for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem)) { if (tem == enumtype) - continue; + continue; TYPE_VALUES (tem) = TYPE_VALUES (enumtype); TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); @@ -7473,37 +7510,37 @@ if (value != 0) { /* Don't issue more errors for error_mark_node (i.e. an - undeclared identifier) - just ignore the value expression. */ + undeclared identifier) - just ignore the value expression. */ if (value == error_mark_node) - value = 0; + value = 0; else if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) - { - error_at (loc, "enumerator value for %qE is not an integer constant", - name); - value = 0; - } + { + error_at (loc, "enumerator value for %qE is not an integer constant", + name); + value = 0; + } else - { - if (TREE_CODE (value) != INTEGER_CST) - { - value = c_fully_fold (value, false, NULL); - if (TREE_CODE (value) == INTEGER_CST) - pedwarn (loc, OPT_pedantic, - "enumerator value for %qE is not an integer " - "constant expression", name); - } - if (TREE_CODE (value) != INTEGER_CST) - { - error ("enumerator value for %qE is not an integer constant", - name); - value = 0; - } - else - { - value = default_conversion (value); - constant_expression_warning (value); - } - } + { + if (TREE_CODE (value) != INTEGER_CST) + { + value = c_fully_fold (value, false, NULL); + if (TREE_CODE (value) == INTEGER_CST) + pedwarn (loc, OPT_pedantic, + "enumerator value for %qE is not an integer " + "constant expression", name); + } + if (TREE_CODE (value) != INTEGER_CST) + { + error ("enumerator value for %qE is not an integer constant", + name); + value = 0; + } + else + { + value = default_conversion (value); + constant_expression_warning (value); + } + } } /* Default based on previous value. */ @@ -7513,7 +7550,7 @@ { value = the_enum->enum_next_value; if (the_enum->enum_overflow) - error_at (loc, "overflow in enumeration values"); + error_at (loc, "overflow in enumeration values"); } /* Even though the underlying type of an enum is unspecified, the type of enumeration constants is explicitly defined as int @@ -7521,7 +7558,7 @@ an extension. */ else if (!int_fits_type_p (value, integer_type_node)) pedwarn (loc, OPT_pedantic, - "ISO C restricts enumerator values to range of %"); + "ISO C restricts enumerator values to range of %"); /* The ISO C Standard mandates enumerators to have type int, even though the underlying type of an enum type is unspecified. @@ -7545,10 +7582,10 @@ type = TREE_TYPE (value); type = c_common_type_for_size (MAX (TYPE_PRECISION (type), - TYPE_PRECISION (integer_type_node)), - (TYPE_PRECISION (type) - >= TYPE_PRECISION (integer_type_node) - && TYPE_UNSIGNED (type))); + TYPE_PRECISION (integer_type_node)), + (TYPE_PRECISION (type) + >= TYPE_PRECISION (integer_type_node) + && TYPE_UNSIGNED (type))); decl = build_decl (decl_loc, CONST_DECL, name, type); DECL_INITIAL (decl) = convert (type, value); @@ -7557,6 +7594,68 @@ return tree_cons (decl, value, NULL_TREE); } +#ifndef noCbC +#define CbC_STACK_SIZE (1024 * 8) +static void cbc_set_codesegment(tree fndecl){ + tree args; + tree *nextp; +// tree itype; +// tree icst; +// tree padding_array; +// tree list; + int padding_size = CbC_STACK_SIZE; + + //CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) = 1; + //CbC_IS_CODE_SEGMENT(fndecl) = 1; + + nextp = & TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + for (args = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); args; + args = TREE_CHAIN (args)) + { + tree type = args ? TREE_VALUE (args) : 0; + tree type_size; + unsigned int size; + + if (type == void_type_node) + break; + + type_size = TYPE_SIZE (type); + size = TREE_INT_CST_LOW (type_size); + padding_size -= size; + + nextp = & TREE_CHAIN(args); + } + + /* error check. */ + if (padding_size<0) + { + error ("CbC: too many arguments on code segment %qE", fndecl); + return ; + } + else if (padding_size==0) + return ; + +#if 0 + /* itype is integer_type that means last index. */ + icst = build_int_cst (NULL_TREE, padding_size-1); + itype = build_index_type (icst); + + /* create array_type node. */ + padding_array = build_array_type (integer_type_node, itype); + + /* add array_type to this function's argument list + before void_type_node. */ + if (!args) + args = build_tree_list(NULL_TREE, void_type_node); + list = build_tree_list(NULL_TREE, padding_array); + TREE_CHAIN(list) = args; + *nextp = list; +#endif + + return ; +} +#endif + /* Create the FUNCTION_DECL for a function definition. DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of @@ -7572,7 +7671,7 @@ int start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, - tree attributes) + tree attributes) { tree decl1, old_decl; tree restype, resdecl; @@ -7590,7 +7689,17 @@ c_break_label = c_cont_label = size_zero_node; decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, - &attributes, NULL, NULL, DEPRECATED_NORMAL); + &attributes, NULL, NULL, DEPRECATED_NORMAL); + +#ifndef noCbC + cbc_return_f = NULL_TREE; + cbc_env = NULL_TREE; + if ( declspecs->typespec_word == cts_CbC_code ) + { + cbc_set_codesegment(decl1); + //CbC_IS_CODE_SEGMENT(TREE_TYPE(decl1)) = 1; + } +#endif /* If the declarator is not suitable for a function definition, cause a syntax error. */ @@ -7605,18 +7714,18 @@ && DECL_UNINLINABLE (decl1) && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1))) warning_at (loc, OPT_Wattributes, - "inline function %qD given attribute noinline", - decl1); + "inline function %qD given attribute noinline", + decl1); /* Handle gnu_inline attribute. */ if (declspecs->inline_p && !flag_gnu89_inline && TREE_CODE (decl1) == FUNCTION_DECL && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1)) - || current_function_decl)) + || current_function_decl)) { if (declspecs->storage_class != csc_static) - DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1); + DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1); } announce_function (decl1); @@ -7626,14 +7735,14 @@ error_at (loc, "return type is an incomplete type"); /* Make it return void instead. */ TREE_TYPE (decl1) - = build_function_type (void_type_node, - TYPE_ARG_TYPES (TREE_TYPE (decl1))); + = build_function_type (void_type_node, + TYPE_ARG_TYPES (TREE_TYPE (decl1))); } if (warn_about_return_type) pedwarn_c99 (loc, flag_isoc99 ? 0 - : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int), - "return type defaults to %"); + : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int), + "return type defaults to %"); /* Make the init_value nonzero so pushdecl knows this is not tentative. error_mark_node is replaced below (in pop_scope) with the BLOCK. */ @@ -7654,47 +7763,47 @@ if (!prototype_p (TREE_TYPE (decl1))) { if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE - && comptypes (TREE_TYPE (TREE_TYPE (decl1)), - TREE_TYPE (TREE_TYPE (old_decl)))) - { - TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl), - TREE_TYPE (decl1)); - current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl); - current_function_prototype_built_in - = C_DECL_BUILTIN_PROTOTYPE (old_decl); - current_function_prototype_arg_types - = TYPE_ARG_TYPES (TREE_TYPE (decl1)); - } + && comptypes (TREE_TYPE (TREE_TYPE (decl1)), + TREE_TYPE (TREE_TYPE (old_decl)))) + { + TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl), + TREE_TYPE (decl1)); + current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl); + current_function_prototype_built_in + = C_DECL_BUILTIN_PROTOTYPE (old_decl); + current_function_prototype_arg_types + = TYPE_ARG_TYPES (TREE_TYPE (decl1)); + } if (TREE_PUBLIC (decl1)) - { - /* If there is an external prototype declaration of this - function, record its location but do not copy information - to this decl. This may be an invisible declaration - (built-in or in a scope which has finished) or simply - have more refined argument types than any declaration - found above. */ - struct c_binding *b; - for (b = I_SYMBOL_BINDING (DECL_NAME (decl1)); b; b = b->shadowed) - if (B_IN_SCOPE (b, external_scope)) - break; - if (b) - { - tree ext_decl, ext_type; - ext_decl = b->decl; - ext_type = b->u.type ? b->u.type : TREE_TYPE (ext_decl); - if (TREE_CODE (ext_type) == FUNCTION_TYPE - && comptypes (TREE_TYPE (TREE_TYPE (decl1)), - TREE_TYPE (ext_type))) - { - current_function_prototype_locus - = DECL_SOURCE_LOCATION (ext_decl); - current_function_prototype_built_in - = C_DECL_BUILTIN_PROTOTYPE (ext_decl); - current_function_prototype_arg_types - = TYPE_ARG_TYPES (ext_type); - } - } - } + { + /* If there is an external prototype declaration of this + function, record its location but do not copy information + to this decl. This may be an invisible declaration + (built-in or in a scope which has finished) or simply + have more refined argument types than any declaration + found above. */ + struct c_binding *b; + for (b = I_SYMBOL_BINDING (DECL_NAME (decl1)); b; b = b->shadowed) + if (B_IN_SCOPE (b, external_scope)) + break; + if (b) + { + tree ext_decl, ext_type; + ext_decl = b->decl; + ext_type = b->u.type ? b->u.type : TREE_TYPE (ext_decl); + if (TREE_CODE (ext_type) == FUNCTION_TYPE + && comptypes (TREE_TYPE (TREE_TYPE (decl1)), + TREE_TYPE (ext_type))) + { + current_function_prototype_locus + = DECL_SOURCE_LOCATION (ext_decl); + current_function_prototype_built_in + = C_DECL_BUILTIN_PROTOTYPE (ext_decl); + current_function_prototype_arg_types + = TYPE_ARG_TYPES (ext_type); + } + } + } } /* Optionally warn of old-fashioned def with no previous prototype. */ @@ -7703,15 +7812,15 @@ && !prototype_p (TREE_TYPE (decl1)) && C_DECL_ISNT_PROTOTYPE (old_decl)) warning_at (loc, OPT_Wstrict_prototypes, - "function declaration isn%'t a prototype"); + "function declaration isn%'t a prototype"); /* Optionally warn of any global def with no previous prototype. */ else if (warn_missing_prototypes - && old_decl != error_mark_node - && TREE_PUBLIC (decl1) - && !MAIN_NAME_P (DECL_NAME (decl1)) - && C_DECL_ISNT_PROTOTYPE (old_decl)) + && old_decl != error_mark_node + && TREE_PUBLIC (decl1) + && !MAIN_NAME_P (DECL_NAME (decl1)) + && C_DECL_ISNT_PROTOTYPE (old_decl)) warning_at (loc, OPT_Wmissing_prototypes, - "no previous prototype for %qD", decl1); + "no previous prototype for %qD", decl1); /* Optionally warn of any def with no previous prototype if the function has already been used. */ else if (warn_missing_prototypes @@ -7720,24 +7829,24 @@ && TREE_USED (old_decl) && !prototype_p (TREE_TYPE (old_decl))) warning_at (loc, OPT_Wmissing_prototypes, - "%qD was used with no prototype before its definition", decl1); + "%qD was used with no prototype before its definition", decl1); /* Optionally warn of any global def with no previous declaration. */ else if (warn_missing_declarations - && TREE_PUBLIC (decl1) - && old_decl == 0 - && !MAIN_NAME_P (DECL_NAME (decl1))) + && TREE_PUBLIC (decl1) + && old_decl == 0 + && !MAIN_NAME_P (DECL_NAME (decl1))) warning_at (loc, OPT_Wmissing_declarations, - "no previous declaration for %qD", - decl1); + "no previous declaration for %qD", + decl1); /* Optionally warn of any def with no previous declaration if the function has already been used. */ else if (warn_missing_declarations - && old_decl != 0 - && old_decl != error_mark_node - && TREE_USED (old_decl) - && C_DECL_IMPLICIT (old_decl)) + && old_decl != 0 + && old_decl != error_mark_node + && TREE_USED (old_decl) + && C_DECL_IMPLICIT (old_decl)) warning_at (loc, OPT_Wmissing_declarations, - "%qD was used with no declaration before its definition", decl1); + "%qD was used with no declaration before its definition", decl1); /* This function exists in static storage. (This does not mean `static' in the C sense!) */ @@ -7755,14 +7864,14 @@ if (warn_main && MAIN_NAME_P (DECL_NAME (decl1))) { if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1))) - != integer_type_node) - pedwarn (loc, OPT_Wmain, "return type of %qD is not %", decl1); + != integer_type_node) + pedwarn (loc, OPT_Wmain, "return type of %qD is not %", decl1); check_main_parameter_types (decl1); if (!TREE_PUBLIC (decl1)) - pedwarn (loc, OPT_Wmain, - "%qD is normally a non-static function", decl1); + pedwarn (loc, OPT_Wmain, + "%qD is normally a non-static function", decl1); } /* Record the decl so that the function name is defined. @@ -7799,8 +7908,8 @@ if (current_scope->bindings) { error_at (DECL_SOURCE_LOCATION (fndecl), - "old-style parameter declarations in prototyped " - "function definition"); + "old-style parameter declarations in prototyped " + "function definition"); /* Get rid of the old-style declarations. */ pop_scope (); @@ -7811,9 +7920,9 @@ (this happens when a function definition has just an ellipsis in its parameter list). */ else if (!in_system_header && !current_function_scope - && arg_info->types != error_mark_node) + && arg_info->types != error_mark_node) warning_at (DECL_SOURCE_LOCATION (fndecl), OPT_Wtraditional, - "traditional C rejects ISO C style function definitions"); + "traditional C rejects ISO C style function definitions"); /* Now make all the parameter declarations visible in the function body. We can bypass most of the grunt work of pushdecl. */ @@ -7821,15 +7930,15 @@ { DECL_CONTEXT (decl) = current_function_decl; if (DECL_NAME (decl)) - { - bind (DECL_NAME (decl), decl, current_scope, - /*invisible=*/false, /*nested=*/false, - UNKNOWN_LOCATION); - if (!TREE_USED (decl)) - warn_if_shadowing (decl); - } + { + bind (DECL_NAME (decl), decl, current_scope, + /*invisible=*/false, /*nested=*/false, + UNKNOWN_LOCATION); + if (!TREE_USED (decl)) + warn_if_shadowing (decl); + } else - error_at (DECL_SOURCE_LOCATION (decl), "parameter name omitted"); + error_at (DECL_SOURCE_LOCATION (decl), "parameter name omitted"); } /* Record the parameter list in the function declaration. */ @@ -7866,19 +7975,19 @@ if (!in_system_header) warning_at (DECL_SOURCE_LOCATION (fndecl), - OPT_Wold_style_definition, "old-style function definition"); + OPT_Wold_style_definition, "old-style function definition"); /* Match each formal parameter name with its declaration. Save each decl in the appropriate TREE_PURPOSE slot of the parmids chain. */ for (parm = parmids; parm; parm = TREE_CHAIN (parm)) { if (TREE_VALUE (parm) == 0) - { - error_at (DECL_SOURCE_LOCATION (fndecl), - "parameter name missing from parameter list"); - TREE_PURPOSE (parm) = 0; - continue; - } + { + error_at (DECL_SOURCE_LOCATION (fndecl), + "parameter name missing from parameter list"); + TREE_PURPOSE (parm) = 0; + continue; + } b = I_SYMBOL_BINDING (TREE_VALUE (parm)); if (b && B_IN_CURRENT_SCOPE (b)) @@ -7914,32 +8023,32 @@ } /* If no declaration found, default to int. */ else - { - /* FIXME diagnostics: This should be the location of the argument, - not the FNDECL. E.g., for an old-style declaration - - int f10(v) { blah; } - - We should use the location of the V, not the F10. - Unfortunately, the V is an IDENTIFIER_NODE which has no - location. In the future we need locations for c_arg_info - entries. - - See gcc.dg/Wshadow-3.c for an example of this problem. */ - decl = build_decl (DECL_SOURCE_LOCATION (fndecl), - PARM_DECL, TREE_VALUE (parm), integer_type_node); - DECL_ARG_TYPE (decl) = TREE_TYPE (decl); - pushdecl (decl); - warn_if_shadowing (decl); - - if (flag_isoc99) - pedwarn (DECL_SOURCE_LOCATION (decl), - 0, "type of %qD defaults to %", decl); - else - warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wmissing_parameter_type, - "type of %qD defaults to %", decl); - } + { + /* FIXME diagnostics: This should be the location of the argument, + not the FNDECL. E.g., for an old-style declaration + + int f10(v) { blah; } + + We should use the location of the V, not the F10. + Unfortunately, the V is an IDENTIFIER_NODE which has no + location. In the future we need locations for c_arg_info + entries. + + See gcc.dg/Wshadow-3.c for an example of this problem. */ + decl = build_decl (DECL_SOURCE_LOCATION (fndecl), + PARM_DECL, TREE_VALUE (parm), integer_type_node); + DECL_ARG_TYPE (decl) = TREE_TYPE (decl); + pushdecl (decl); + warn_if_shadowing (decl); + + if (flag_isoc99) + pedwarn (DECL_SOURCE_LOCATION (decl), + 0, "type of %qD defaults to %", decl); + else + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wmissing_parameter_type, + "type of %qD defaults to %", decl); + } TREE_PURPOSE (parm) = decl; pointer_set_insert (seen_args, decl); @@ -7952,27 +8061,27 @@ { parm = b->decl; if (TREE_CODE (parm) != PARM_DECL) - continue; + continue; if (TREE_TYPE (parm) != error_mark_node - && !COMPLETE_TYPE_P (TREE_TYPE (parm))) - { - error_at (DECL_SOURCE_LOCATION (parm), - "parameter %qD has incomplete type", parm); - TREE_TYPE (parm) = error_mark_node; - } + && !COMPLETE_TYPE_P (TREE_TYPE (parm))) + { + error_at (DECL_SOURCE_LOCATION (parm), + "parameter %qD has incomplete type", parm); + TREE_TYPE (parm) = error_mark_node; + } if (!pointer_set_contains (seen_args, parm)) - { - error_at (DECL_SOURCE_LOCATION (parm), - "declaration for parameter %qD but no such parameter", - parm); - - /* Pretend the parameter was not missing. - This gets us to a standard state and minimizes - further error messages. */ - parmids = chainon (parmids, tree_cons (parm, 0, 0)); - } + { + error_at (DECL_SOURCE_LOCATION (parm), + "declaration for parameter %qD but no such parameter", + parm); + + /* Pretend the parameter was not missing. + This gets us to a standard state and minimizes + further error messages. */ + parmids = chainon (parmids, tree_cons (parm, 0, 0)); + } } /* Chain the declarations together in the order of the list of @@ -8007,8 +8116,8 @@ { tree type; for (parm = DECL_ARGUMENTS (fndecl), - type = current_function_prototype_arg_types; - parm || (type && TREE_VALUE (type) != error_mark_node + type = current_function_prototype_arg_types; + parm || (type && TREE_VALUE (type) != error_mark_node && (TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node)); parm = DECL_CHAIN (parm), type = TREE_CHAIN (type)) { @@ -8112,17 +8221,17 @@ } type = tree_cons (NULL_TREE, void_type_node, NULL_TREE); if (last) - TREE_CHAIN (last) = type; + TREE_CHAIN (last) = type; else - actual = type; + actual = type; /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES - of the type of this function, but we need to avoid having this - affect the types of other similarly-typed functions, so we must - first force the generation of an identical (but separate) type - node for the relevant function type. The new node we create - will be a variant of the main variant of the original function - type. */ + of the type of this function, but we need to avoid having this + affect the types of other similarly-typed functions, so we must + first force the generation of an identical (but separate) type + node for the relevant function type. The new node we create + will be a variant of the main variant of the original function + type. */ TREE_TYPE (fndecl) = build_variant_type_copy (TREE_TYPE (fndecl)); @@ -8186,7 +8295,7 @@ /* ??? Insert the contents of the pending sizes list into the function to be evaluated. The only reason left to have this is - void foo(int n, int array[n++]) + void foo(int n, int array[n++]) because we throw away the array type in favor of a pointer type, and thus won't naturally see the SAVE_EXPR containing the increment. All other pending sizes would be handled by gimplify_parameters. */ @@ -8247,10 +8356,10 @@ == integer_type_node && flag_isoc99) { /* Hack. We don't want the middle-end to warn that this return - is unreachable, so we mark its location as special. Using - UNKNOWN_LOCATION has the problem that it gets clobbered in - annotate_one_with_locus. A cleaner solution might be to - ensure ! should_carry_locus_p (stmt), but that needs a flag. + is unreachable, so we mark its location as special. Using + UNKNOWN_LOCATION has the problem that it gets clobbered in + annotate_one_with_locus. A cleaner solution might be to + ensure ! should_carry_locus_p (stmt), but that needs a flag. */ c_finish_return (BUILTINS_LOCATION, integer_zero_node, NULL_TREE); } @@ -8277,7 +8386,7 @@ && !TREE_PUBLIC (fndecl)) { warning (OPT_Wreturn_type, - "no return statement in function returning non-void"); + "no return statement in function returning non-void"); TREE_NO_WARNING (fndecl) = 1; } @@ -8320,26 +8429,26 @@ && !undef_nested_function) { if (!decl_function_context (fndecl)) - { - invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); - c_genericize (fndecl); - - /* ??? Objc emits functions after finalizing the compilation unit. - This should be cleaned up later and this conditional removed. */ - if (cgraph_global_info_ready) - { - cgraph_add_new_function (fndecl, false); - return; - } - cgraph_finalize_function (fndecl, false); - } + { + invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); + c_genericize (fndecl); + + /* ??? Objc emits functions after finalizing the compilation unit. + This should be cleaned up later and this conditional removed. */ + if (cgraph_global_info_ready) + { + cgraph_add_new_function (fndecl, false); + return; + } + cgraph_finalize_function (fndecl, false); + } else - { - /* Register this function with cgraph just far enough to get it - added to our parent's nested function list. Handy, since the - C front end doesn't have such a list. */ - (void) cgraph_node (fndecl); - } + { + /* Register this function with cgraph just far enough to get it + added to our parent's nested function list. Handy, since the + C front end doesn't have such a list. */ + (void) cgraph_node (fndecl); + } } if (!decl_function_context (fndecl)) @@ -8374,16 +8483,16 @@ { static bool hint = true; /* If we get here, declarations have been used in a for loop without - the C99 for loop scope. This doesn't make much sense, so don't - allow it. */ + the C99 for loop scope. This doesn't make much sense, so don't + allow it. */ error_at (loc, "% loop initial declarations " - "are only allowed in C99 mode"); + "are only allowed in C99 mode"); if (hint) - { - inform (loc, - "use option -std=c99 or -std=gnu99 to compile your code"); - hint = false; - } + { + inform (loc, + "use option -std=c99 or -std=gnu99 to compile your code"); + hint = false; + } return NULL_TREE; } /* C99 subclause 6.8.5 paragraph 3: @@ -8406,42 +8515,42 @@ tree decl = b->decl; if (!id) - continue; + continue; switch (TREE_CODE (decl)) - { - case VAR_DECL: - { - location_t decl_loc = DECL_SOURCE_LOCATION (decl); - if (TREE_STATIC (decl)) - error_at (decl_loc, - "declaration of static variable %qD in % loop " - "initial declaration", decl); - else if (DECL_EXTERNAL (decl)) - error_at (decl_loc, - "declaration of % variable %qD in % loop " - "initial declaration", decl); - } - break; - - case RECORD_TYPE: - error_at (loc, - "% declared in % loop initial " - "declaration", id); - break; - case UNION_TYPE: - error_at (loc, - "% declared in % loop initial declaration", - id); - break; - case ENUMERAL_TYPE: - error_at (loc, "% declared in % loop " - "initial declaration", id); - break; - default: - error_at (loc, "declaration of non-variable " - "%qD in % loop initial declaration", decl); - } + { + case VAR_DECL: + { + location_t decl_loc = DECL_SOURCE_LOCATION (decl); + if (TREE_STATIC (decl)) + error_at (decl_loc, + "declaration of static variable %qD in % loop " + "initial declaration", decl); + else if (DECL_EXTERNAL (decl)) + error_at (decl_loc, + "declaration of % variable %qD in % loop " + "initial declaration", decl); + } + break; + + case RECORD_TYPE: + error_at (loc, + "% declared in % loop initial " + "declaration", id); + break; + case UNION_TYPE: + error_at (loc, + "% declared in % loop initial declaration", + id); + break; + case ENUMERAL_TYPE: + error_at (loc, "% declared in % loop " + "initial declaration", id); + break; + default: + error_at (loc, "declaration of non-variable " + "%qD in % loop initial declaration", decl); + } n_decls++; one_decl = decl; @@ -8489,7 +8598,7 @@ { /* Stop pointing to the local nodes about to be freed. */ /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ + was an actual function definition. */ DECL_INITIAL (current_function_decl) = error_mark_node; DECL_ARGUMENTS (current_function_decl) = 0; } @@ -8523,7 +8632,7 @@ /* Return the global value of T as a symbol. */ tree -identifier_global_value (tree t) +identifier_global_value (tree t) { struct c_binding *b; @@ -8563,7 +8672,7 @@ struct c_parm * build_c_parm (struct c_declspecs *specs, tree attrs, - struct c_declarator *declarator) + struct c_declarator *declarator) { struct c_parm *ret = XOBNEW (&parser_obstack, struct c_parm); ret->specs = specs; @@ -8591,7 +8700,7 @@ struct c_declarator * build_function_declarator (struct c_arg_info *args, - struct c_declarator *target) + struct c_declarator *target) { struct c_declarator *ret = XOBNEW (&parser_obstack, struct c_declarator); ret->kind = cdk_function; @@ -8622,7 +8731,7 @@ struct c_declarator * make_pointer_declarator (struct c_declspecs *type_quals_attrs, - struct c_declarator *target) + struct c_declarator *target) { tree attrs; int quals = 0; @@ -8633,7 +8742,7 @@ attrs = type_quals_attrs->attrs; quals = quals_from_declspecs (type_quals_attrs); if (attrs != NULL_TREE) - itarget = build_attrs_declarator (attrs, target); + itarget = build_attrs_declarator (attrs, target); } ret->kind = cdk_pointer; ret->declarator = itarget; @@ -8690,8 +8799,8 @@ if (!ADDR_SPACE_GENERIC_P (specs->address_space) && specs->address_space != as) error ("incompatible address space qualifiers %qs and %qs", - c_addr_space_name (as), - c_addr_space_name (specs->address_space)); + c_addr_space_name (as), + c_addr_space_name (specs->address_space)); else specs->address_space = as; return specs; @@ -8708,7 +8817,7 @@ specs->non_sc_seen_p = true; specs->declspecs_seen_p = true; gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE - && C_IS_RESERVED_WORD (qual)); + && C_IS_RESERVED_WORD (qual)); i = C_RID_CODE (qual); switch (i) { @@ -8737,7 +8846,7 @@ struct c_declspecs * declspecs_add_type (location_t loc, struct c_declspecs *specs, - struct c_typespec spec) + struct c_typespec spec) { tree type = spec.spec; specs->non_sc_seen_p = true; @@ -8753,10 +8862,10 @@ { enum rid i = C_RID_CODE (type); if (specs->type) - { - error_at (loc, "two or more data types in declaration specifiers"); - return specs; - } + { + error_at (loc, "two or more data types in declaration specifiers"); + return specs; + } if ((int) i <= (int) RID_LAST_MODIFIER) { /* "long", "short", "signed", "unsigned", "_Complex" or "_Sat". */ @@ -8791,6 +8900,12 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif else if (specs->typespec_word == cts_int128) error_at (loc, ("both % and %<__int128%> in " @@ -8832,6 +8947,12 @@ error_at (loc, ("both % and % in " "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif else if (specs->typespec_word == cts_int128) error_at (loc, ("both % and %<__int128%> in " @@ -8853,107 +8974,126 @@ ("both % and % in " "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) +>>>>>>> other error_at (loc, - ("both % and %<_Decimal32%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat64) - error_at (loc, - ("both % and %<_Decimal64%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat128) - error_at (loc, - ("both % and %<_Decimal128%> in " - "declaration specifiers")); - else - specs->short_p = true; - break; - case RID_SIGNED: - dupe = specs->signed_p; - if (specs->unsigned_p) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_void) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_bool) - error_at (loc, - ("both % and %<_Bool%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_float) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_double) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat32) - error_at (loc, - ("both % and %<_Decimal32%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat64) - error_at (loc, - ("both % and %<_Decimal64%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat128) - error_at (loc, - ("both % and %<_Decimal128%> in " - "declaration specifiers")); - else - specs->signed_p = true; - break; - case RID_UNSIGNED: - dupe = specs->unsigned_p; - if (specs->signed_p) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_void) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_bool) - error_at (loc, - ("both % and %<_Bool%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_float) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_double) - error_at (loc, - ("both % and % in " - "declaration specifiers")); + ("both % and %<_Decimal32%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat64) + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat128) + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); + else + specs->short_p = true; + break; + case RID_SIGNED: + dupe = specs->signed_p; + if (specs->unsigned_p) + error_at (loc, + ("both % and % in " + "declaration specifiers")); + else if (specs->typespec_word == cts_void) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif + else if (specs->typespec_word == cts_bool) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_float) + error_at (loc, + ("both % and % in " + "declaration specifiers")); + else if (specs->typespec_word == cts_double) + error_at (loc, + ("both % and % in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat32) + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat64) + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat128) + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); + else + specs->signed_p = true; + break; + case RID_UNSIGNED: + dupe = specs->unsigned_p; + if (specs->signed_p) + error_at (loc, + ("both % and % in " + "declaration specifiers")); + else if (specs->typespec_word == cts_void) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif + else if (specs->typespec_word == cts_bool) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_float) + error_at (loc, + ("both % and % in " + "declaration specifiers")); + else if (specs->typespec_word == cts_double) + error_at (loc, + ("both % and % in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error_at (loc, - ("both % and %<_Decimal32%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat64) - error_at (loc, - ("both % and %<_Decimal64%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat128) - error_at (loc, - ("both % and %<_Decimal128%> in " - "declaration specifiers")); - else - specs->unsigned_p = true; - break; - case RID_COMPLEX: - dupe = specs->complex_p; - if (!flag_isoc99 && !in_system_header) - pedwarn (loc, OPT_pedantic, - "ISO C90 does not support complex types"); - if (specs->typespec_word == cts_void) - error_at (loc, - ("both % and % in " - "declaration specifiers")); - else if (specs->typespec_word == cts_bool) - error_at (loc, - ("both % and %<_Bool%> in " - "declaration specifiers")); + error_at (loc, + ("both % and %<_Decimal32%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat64) + error_at (loc, + ("both % and %<_Decimal64%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat128) + error_at (loc, + ("both % and %<_Decimal128%> in " + "declaration specifiers")); + else + specs->unsigned_p = true; + break; + case RID_COMPLEX: + dupe = specs->complex_p; + if (!flag_isoc99 && !in_system_header) + pedwarn (loc, OPT_pedantic, + "ISO C90 does not support complex types"); + if (specs->typespec_word == cts_void) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#ifndef noCbC + else if (specs->typespec_word == cts_CbC_code) + error_at (loc, + ("both % and % in " + "declaration specifiers")); +#endif + else if (specs->typespec_word == cts_bool) + error_at (loc, + ("both % and %<_Bool%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) error_at (loc, ("both % and %<_Decimal32%> in " @@ -9016,33 +9156,33 @@ ("both %<_Sat%> and % in " "declaration specifiers")); else if (specs->typespec_word == cts_dfloat32) - error_at (loc, - ("both %<_Sat%> and %<_Decimal32%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat64) - error_at (loc, - ("both %<_Sat%> and %<_Decimal64%> in " - "declaration specifiers")); - else if (specs->typespec_word == cts_dfloat128) - error_at (loc, - ("both %<_Sat%> and %<_Decimal128%> in " - "declaration specifiers")); - else if (specs->complex_p) - error_at (loc, - ("both %<_Sat%> and % in " - "declaration specifiers")); - else - specs->saturating_p = true; - break; - default: - gcc_unreachable (); - } - - if (dupe) - error_at (loc, "duplicate %qE", type); - - return specs; - } + error_at (loc, + ("both %<_Sat%> and %<_Decimal32%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat64) + error_at (loc, + ("both %<_Sat%> and %<_Decimal64%> in " + "declaration specifiers")); + else if (specs->typespec_word == cts_dfloat128) + error_at (loc, + ("both %<_Sat%> and %<_Decimal128%> in " + "declaration specifiers")); + else if (specs->complex_p) + error_at (loc, + ("both %<_Sat%> and % in " + "declaration specifiers")); + else + specs->saturating_p = true; + break; + default: + gcc_unreachable (); + } + + if (dupe) + error_at (loc, "duplicate %qE", type); + + return specs; + } else { /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32", @@ -9108,6 +9248,27 @@ else specs->typespec_word = cts_void; return specs; +#ifndef noCbC + case RID_CbC_CODE: + if (specs->long_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->short_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->signed_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->unsigned_p) + error ("both % and % in " + "declaration specifiers"); + else if (specs->complex_p) + error ("both % and % in " + "declaration specifiers"); + else + specs->typespec_word = cts_CbC_code; + return specs; +#endif case RID_BOOL: if (specs->long_p) error_at (loc, @@ -9246,57 +9407,57 @@ str); else if (specs->complex_p) error_at (loc, - ("both % and %<%s%> in " - "declaration specifiers"), - str); + ("both % and %<%s%> in " + "declaration specifiers"), + str); else if (specs->saturating_p) error_at (loc, - ("both %<_Sat%> and %<%s%> in " - "declaration specifiers"), - str); - else if (i == RID_DFLOAT32) - specs->typespec_word = cts_dfloat32; - else if (i == RID_DFLOAT64) - specs->typespec_word = cts_dfloat64; - else - specs->typespec_word = cts_dfloat128; - } - if (!targetm.decimal_float_supported_p ()) - error_at (loc, - ("decimal floating point not supported " - "for this target")); - pedwarn (loc, OPT_pedantic, - "ISO C does not support decimal floating point"); - return specs; - case RID_FRACT: - case RID_ACCUM: - { - const char *str; - if (i == RID_FRACT) - str = "_Fract"; - else - str = "_Accum"; + ("both %<_Sat%> and %<%s%> in " + "declaration specifiers"), + str); + else if (i == RID_DFLOAT32) + specs->typespec_word = cts_dfloat32; + else if (i == RID_DFLOAT64) + specs->typespec_word = cts_dfloat64; + else + specs->typespec_word = cts_dfloat128; + } + if (!targetm.decimal_float_supported_p ()) + error_at (loc, + ("decimal floating point not supported " + "for this target")); + pedwarn (loc, OPT_pedantic, + "ISO C does not support decimal floating point"); + return specs; + case RID_FRACT: + case RID_ACCUM: + { + const char *str; + if (i == RID_FRACT) + str = "_Fract"; + else + str = "_Accum"; if (specs->complex_p) error_at (loc, - ("both % and %<%s%> in " - "declaration specifiers"), - str); - else if (i == RID_FRACT) - specs->typespec_word = cts_fract; - else - specs->typespec_word = cts_accum; - } - if (!targetm.fixed_point_supported_p ()) - error_at (loc, - "fixed-point types not supported for this target"); - pedwarn (loc, OPT_pedantic, - "ISO C does not support fixed-point types"); - return specs; - default: - /* ObjC reserved word "id", handled below. */ - break; - } - } + ("both % and %<%s%> in " + "declaration specifiers"), + str); + else if (i == RID_FRACT) + specs->typespec_word = cts_fract; + else + specs->typespec_word = cts_accum; + } + if (!targetm.fixed_point_supported_p ()) + error_at (loc, + "fixed-point types not supported for this target"); + pedwarn (loc, OPT_pedantic, + "ISO C does not support fixed-point types"); + return specs; + default: + /* ObjC reserved word "id", handled below. */ + break; + } + } } /* Now we have a typedef (a TYPE_DECL node), an identifier (some @@ -9311,37 +9472,37 @@ else if (TREE_CODE (type) == TYPE_DECL) { if (TREE_TYPE (type) == error_mark_node) - ; /* Allow the type to default to int to avoid cascading errors. */ + ; /* Allow the type to default to int to avoid cascading errors. */ else - { - specs->type = TREE_TYPE (type); - specs->decl_attr = DECL_ATTRIBUTES (type); - specs->typedef_p = true; - specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type); - - /* If this typedef name is defined in a struct, then a C++ - lookup would return a different value. */ - if (warn_cxx_compat - && I_SYMBOL_BINDING (DECL_NAME (type))->in_struct) - warning_at (loc, OPT_Wc___compat, - "C++ lookup of %qD would return a field, not a type", - type); - - /* If we are parsing a struct, record that a struct field - used a typedef. */ - if (warn_cxx_compat && struct_parse_info != NULL) - VEC_safe_push (tree, heap, struct_parse_info->typedefs_seen, type); - } + { + specs->type = TREE_TYPE (type); + specs->decl_attr = DECL_ATTRIBUTES (type); + specs->typedef_p = true; + specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type); + + /* If this typedef name is defined in a struct, then a C++ + lookup would return a different value. */ + if (warn_cxx_compat + && I_SYMBOL_BINDING (DECL_NAME (type))->in_struct) + warning_at (loc, OPT_Wc___compat, + "C++ lookup of %qD would return a field, not a type", + type); + + /* If we are parsing a struct, record that a struct field + used a typedef. */ + if (warn_cxx_compat && struct_parse_info != NULL) + VEC_safe_push (tree, heap, struct_parse_info->typedefs_seen, type); + } } else if (TREE_CODE (type) == IDENTIFIER_NODE) { tree t = lookup_name (type); if (!t || TREE_CODE (t) != TYPE_DECL) - error_at (loc, "%qE fails to be a typedef or built in type", type); + error_at (loc, "%qE fails to be a typedef or built in type", type); else if (TREE_TYPE (t) == error_mark_node) - ; + ; else - specs->type = TREE_TYPE (t); + specs->type = TREE_TYPE (t); } else { @@ -9375,7 +9536,7 @@ bool dupe = false; specs->declspecs_seen_p = true; gcc_assert (TREE_CODE (scspec) == IDENTIFIER_NODE - && C_IS_RESERVED_WORD (scspec)); + && C_IS_RESERVED_WORD (scspec)); i = C_RID_CODE (scspec); if (specs->non_sc_seen_p) warning (OPT_Wold_style_declaration, @@ -9384,22 +9545,22 @@ { case RID_INLINE: /* C99 permits duplicate inline. Although of doubtful utility, - it seems simplest to permit it in gnu89 mode as well, as - there is also little utility in maintaining this as a - difference between gnu89 and C99 inline. */ + it seems simplest to permit it in gnu89 mode as well, as + there is also little utility in maintaining this as a + difference between gnu89 and C99 inline. */ dupe = false; specs->inline_p = true; break; case RID_THREAD: dupe = specs->thread_p; if (specs->storage_class == csc_auto) - error ("%<__thread%> used with %"); + error ("%<__thread%> used with %"); else if (specs->storage_class == csc_register) - error ("%<__thread%> used with %"); + error ("%<__thread%> used with %"); else if (specs->storage_class == csc_typedef) - error ("%<__thread%> used with %"); + error ("%<__thread%> used with %"); else - specs->thread_p = true; + specs->thread_p = true; break; case RID_AUTO: n = csc_auto; @@ -9408,7 +9569,7 @@ n = csc_extern; /* Diagnose "__thread extern". */ if (specs->thread_p) - error ("%<__thread%> before %"); + error ("%<__thread%> before %"); break; case RID_REGISTER: n = csc_register; @@ -9417,7 +9578,7 @@ n = csc_static; /* Diagnose "__thread static". */ if (specs->thread_p) - error ("%<__thread%> before %"); + error ("%<__thread%> before %"); break; case RID_TYPEDEF: n = csc_typedef; @@ -9432,18 +9593,18 @@ if (n != csc_none) { if (specs->storage_class != csc_none && n != specs->storage_class) - { - error ("multiple storage classes in declaration specifiers"); - } + { + error ("multiple storage classes in declaration specifiers"); + } else - { - specs->storage_class = n; - if (n != csc_extern && n != csc_static && specs->thread_p) - { - error ("%<__thread%> used with %qE", scspec); - specs->thread_p = false; - } - } + { + specs->storage_class = n; + if (n != csc_extern && n != csc_static && specs->thread_p) + { + error ("%<__thread%> used with %qE", scspec); + specs->thread_p = false; + } + } } return specs; } @@ -9490,32 +9651,32 @@ if (specs->typespec_word == cts_none) { if (specs->saturating_p) - { - error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>"); - if (!targetm.fixed_point_supported_p ()) - error ("fixed-point types not supported for this target"); - specs->typespec_word = cts_fract; - } + { + error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>"); + if (!targetm.fixed_point_supported_p ()) + error ("fixed-point types not supported for this target"); + specs->typespec_word = cts_fract; + } else if (specs->long_p || specs->short_p - || specs->signed_p || specs->unsigned_p) - { - specs->typespec_word = cts_int; - } + || specs->signed_p || specs->unsigned_p) + { + specs->typespec_word = cts_int; + } else if (specs->complex_p) - { - specs->typespec_word = cts_double; - pedwarn (input_location, OPT_pedantic, - "ISO C does not support plain % meaning " - "%"); - } + { + specs->typespec_word = cts_double; + pedwarn (input_location, OPT_pedantic, + "ISO C does not support plain % meaning " + "%"); + } else - { - specs->typespec_word = cts_int; - specs->default_int_p = true; - /* We don't diagnose this here because grokdeclarator will - give more specific diagnostics according to whether it is - a function definition. */ - } + { + specs->typespec_word = cts_int; + specs->default_int_p = true; + /* We don't diagnose this here because grokdeclarator will + give more specific diagnostics according to whether it is + a function definition. */ + } } /* If "signed" was specified, record this to distinguish "int" and @@ -9527,32 +9688,35 @@ switch (specs->typespec_word) { case cts_void: +#ifndef noCbC + case cts_CbC_code: +#endif gcc_assert (!specs->long_p && !specs->short_p - && !specs->signed_p && !specs->unsigned_p - && !specs->complex_p); + && !specs->signed_p && !specs->unsigned_p + && !specs->complex_p); specs->type = void_type_node; break; case cts_bool: gcc_assert (!specs->long_p && !specs->short_p - && !specs->signed_p && !specs->unsigned_p - && !specs->complex_p); + && !specs->signed_p && !specs->unsigned_p + && !specs->complex_p); specs->type = boolean_type_node; break; case cts_char: gcc_assert (!specs->long_p && !specs->short_p); gcc_assert (!(specs->signed_p && specs->unsigned_p)); if (specs->signed_p) - specs->type = signed_char_type_node; + specs->type = signed_char_type_node; else if (specs->unsigned_p) - specs->type = unsigned_char_type_node; + specs->type = unsigned_char_type_node; else - specs->type = char_type_node; + specs->type = char_type_node; if (specs->complex_p) - { - pedwarn (input_location, OPT_pedantic, - "ISO C does not support complex integer types"); - specs->type = build_complex_type (specs->type); - } + { + pedwarn (input_location, OPT_pedantic, + "ISO C does not support complex integer types"); + specs->type = build_complex_type (specs->type); + } break; case cts_int128: gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p); @@ -9571,148 +9735,148 @@ gcc_assert (!(specs->long_p && specs->short_p)); gcc_assert (!(specs->signed_p && specs->unsigned_p)); if (specs->long_long_p) - specs->type = (specs->unsigned_p - ? long_long_unsigned_type_node - : long_long_integer_type_node); + specs->type = (specs->unsigned_p + ? long_long_unsigned_type_node + : long_long_integer_type_node); else if (specs->long_p) - specs->type = (specs->unsigned_p - ? long_unsigned_type_node - : long_integer_type_node); + specs->type = (specs->unsigned_p + ? long_unsigned_type_node + : long_integer_type_node); else if (specs->short_p) - specs->type = (specs->unsigned_p - ? short_unsigned_type_node - : short_integer_type_node); + specs->type = (specs->unsigned_p + ? short_unsigned_type_node + : short_integer_type_node); else - specs->type = (specs->unsigned_p - ? unsigned_type_node - : integer_type_node); + specs->type = (specs->unsigned_p + ? unsigned_type_node + : integer_type_node); if (specs->complex_p) - { - pedwarn (input_location, OPT_pedantic, - "ISO C does not support complex integer types"); - specs->type = build_complex_type (specs->type); - } + { + pedwarn (input_location, OPT_pedantic, + "ISO C does not support complex integer types"); + specs->type = build_complex_type (specs->type); + } break; case cts_float: gcc_assert (!specs->long_p && !specs->short_p - && !specs->signed_p && !specs->unsigned_p); + && !specs->signed_p && !specs->unsigned_p); specs->type = (specs->complex_p - ? complex_float_type_node - : float_type_node); + ? complex_float_type_node + : float_type_node); break; case cts_double: gcc_assert (!specs->long_long_p && !specs->short_p - && !specs->signed_p && !specs->unsigned_p); + && !specs->signed_p && !specs->unsigned_p); if (specs->long_p) - { - specs->type = (specs->complex_p - ? complex_long_double_type_node - : long_double_type_node); - } + { + specs->type = (specs->complex_p + ? complex_long_double_type_node + : long_double_type_node); + } else - { - specs->type = (specs->complex_p - ? complex_double_type_node - : double_type_node); - } + { + specs->type = (specs->complex_p + ? complex_double_type_node + : double_type_node); + } break; case cts_dfloat32: case cts_dfloat64: case cts_dfloat128: gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p - && !specs->signed_p && !specs->unsigned_p && !specs->complex_p); + && !specs->signed_p && !specs->unsigned_p && !specs->complex_p); if (specs->typespec_word == cts_dfloat32) - specs->type = dfloat32_type_node; + specs->type = dfloat32_type_node; else if (specs->typespec_word == cts_dfloat64) - specs->type = dfloat64_type_node; + specs->type = dfloat64_type_node; else - specs->type = dfloat128_type_node; + specs->type = dfloat128_type_node; break; case cts_fract: gcc_assert (!specs->complex_p); if (!targetm.fixed_point_supported_p ()) - specs->type = integer_type_node; + specs->type = integer_type_node; else if (specs->saturating_p) - { - if (specs->long_long_p) - specs->type = specs->unsigned_p - ? sat_unsigned_long_long_fract_type_node - : sat_long_long_fract_type_node; - else if (specs->long_p) - specs->type = specs->unsigned_p - ? sat_unsigned_long_fract_type_node - : sat_long_fract_type_node; - else if (specs->short_p) - specs->type = specs->unsigned_p - ? sat_unsigned_short_fract_type_node - : sat_short_fract_type_node; - else - specs->type = specs->unsigned_p - ? sat_unsigned_fract_type_node - : sat_fract_type_node; - } + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_long_fract_type_node + : sat_long_long_fract_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_fract_type_node + : sat_long_fract_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? sat_unsigned_short_fract_type_node + : sat_short_fract_type_node; + else + specs->type = specs->unsigned_p + ? sat_unsigned_fract_type_node + : sat_fract_type_node; + } else - { - if (specs->long_long_p) - specs->type = specs->unsigned_p - ? unsigned_long_long_fract_type_node - : long_long_fract_type_node; - else if (specs->long_p) - specs->type = specs->unsigned_p - ? unsigned_long_fract_type_node - : long_fract_type_node; - else if (specs->short_p) - specs->type = specs->unsigned_p - ? unsigned_short_fract_type_node - : short_fract_type_node; - else - specs->type = specs->unsigned_p - ? unsigned_fract_type_node - : fract_type_node; - } + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? unsigned_long_long_fract_type_node + : long_long_fract_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? unsigned_long_fract_type_node + : long_fract_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? unsigned_short_fract_type_node + : short_fract_type_node; + else + specs->type = specs->unsigned_p + ? unsigned_fract_type_node + : fract_type_node; + } break; case cts_accum: gcc_assert (!specs->complex_p); if (!targetm.fixed_point_supported_p ()) - specs->type = integer_type_node; + specs->type = integer_type_node; else if (specs->saturating_p) - { - if (specs->long_long_p) - specs->type = specs->unsigned_p - ? sat_unsigned_long_long_accum_type_node - : sat_long_long_accum_type_node; - else if (specs->long_p) - specs->type = specs->unsigned_p - ? sat_unsigned_long_accum_type_node - : sat_long_accum_type_node; - else if (specs->short_p) - specs->type = specs->unsigned_p - ? sat_unsigned_short_accum_type_node - : sat_short_accum_type_node; - else - specs->type = specs->unsigned_p - ? sat_unsigned_accum_type_node - : sat_accum_type_node; - } + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_long_accum_type_node + : sat_long_long_accum_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_accum_type_node + : sat_long_accum_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? sat_unsigned_short_accum_type_node + : sat_short_accum_type_node; + else + specs->type = specs->unsigned_p + ? sat_unsigned_accum_type_node + : sat_accum_type_node; + } else - { - if (specs->long_long_p) - specs->type = specs->unsigned_p - ? unsigned_long_long_accum_type_node - : long_long_accum_type_node; - else if (specs->long_p) - specs->type = specs->unsigned_p - ? unsigned_long_accum_type_node - : long_accum_type_node; - else if (specs->short_p) - specs->type = specs->unsigned_p - ? unsigned_short_accum_type_node - : short_accum_type_node; - else - specs->type = specs->unsigned_p - ? unsigned_accum_type_node - : accum_type_node; - } + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? unsigned_long_long_accum_type_node + : long_long_accum_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? unsigned_long_accum_type_node + : long_accum_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? unsigned_short_accum_type_node + : short_accum_type_node; + else + specs->type = specs->unsigned_p + ? unsigned_accum_type_node + : accum_type_node; + } break; default: gcc_unreachable (); @@ -9735,17 +9899,17 @@ for (decl = globals; decl; decl = DECL_CHAIN (decl)) { /* Check for used but undefined static functions using the C - standard's definition of "used", and set TREE_NO_WARNING so - that check_global_declarations doesn't repeat the check. */ + standard's definition of "used", and set TREE_NO_WARNING so + that check_global_declarations doesn't repeat the check. */ if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_INITIAL (decl) == 0 - && DECL_EXTERNAL (decl) - && !TREE_PUBLIC (decl) - && C_DECL_USED (decl)) - { - pedwarn (input_location, 0, "%q+F used but never defined", decl); - TREE_NO_WARNING (decl) = 1; - } + && DECL_INITIAL (decl) == 0 + && DECL_EXTERNAL (decl) + && !TREE_PUBLIC (decl) + && C_DECL_USED (decl)) + { + pedwarn (input_location, 0, "%q+F used but never defined", decl); + TREE_NO_WARNING (decl) = 1; + } wrapup_global_declaration_1 (decl); } @@ -9855,10 +10019,10 @@ int flags; FILE * stream = dump_begin (TDI_tu, &flags); if (stream && tmp) - { - dump_node (tmp, flags & ~TDF_SLIM, stream); - dump_end (TDI_tu, stream); - } + { + dump_node (tmp, flags & ~TDF_SLIM, stream); + dump_end (TDI_tu, stream); + } } /* Process all file scopes in this compilation, and the external_scope, diff -r 561a7518be6b -r 1b10fe6932e1 gcc/c-parser.c --- a/gcc/c-parser.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/c-parser.c Sun Aug 21 07:53:12 2011 +0900 @@ -56,6 +56,9 @@ #include "vec.h" #include "target.h" #include "cgraph.h" +#ifndef noCbC +#include "cbc-tree.h" +#endif #include "plugin.h" @@ -81,7 +84,7 @@ { mask |= D_ASM | D_EXT; if (!flag_isoc99) - mask |= D_EXT89; + mask |= D_EXT89; } if (!c_dialect_objc ()) mask |= D_OBJC | D_CXX_OBJC; @@ -90,18 +93,18 @@ for (i = 0; i < num_c_common_reswords; i++) { /* If a keyword is disabled, do not enter it into the table - and so create a canonical spelling that isn't a keyword. */ + and so create a canonical spelling that isn't a keyword. */ if (c_common_reswords[i].disable & mask) - { - if (warn_cxx_compat - && (c_common_reswords[i].disable & D_CXXWARN)) - { - id = get_identifier (c_common_reswords[i].word); - C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN); - C_IS_RESERVED_WORD (id) = 1; - } - continue; - } + { + if (warn_cxx_compat + && (c_common_reswords[i].disable & D_CXXWARN)) + { + id = get_identifier (c_common_reswords[i].word); + C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN); + C_IS_RESERVED_WORD (id) = 1; + } + continue; + } id = get_identifier (c_common_reswords[i].word); C_SET_RID_CODE (id, c_common_reswords[i].rid); @@ -214,8 +217,8 @@ timevar_push (TV_LEX); token->type = c_lex_with_flags (&token->value, &token->location, NULL, - (parser->lex_untranslated_string - ? C_LEX_STRING_NO_TRANSLATE : 0)); + (parser->lex_untranslated_string + ? C_LEX_STRING_NO_TRANSLATE : 0)); token->id_kind = C_ID_NONE; token->keyword = RID_MAX; token->pragma_kind = PRAGMA_NONE; @@ -373,9 +376,9 @@ case CPP_CLOSE_PAREN: case CPP_SEMICOLON: /* These tokens may affect the interpretation of any identifiers - following, if doing Objective-C. */ + following, if doing Objective-C. */ if (c_dialect_objc ()) - parser->objc_need_raw_identifier = false; + parser->objc_need_raw_identifier = false; break; case CPP_PRAGMA: /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ @@ -454,19 +457,19 @@ { case CPP_NAME: switch (token->id_kind) - { - case C_ID_ID: - return false; - case C_ID_ADDRSPACE: - return true; - case C_ID_TYPENAME: - return true; - case C_ID_CLASSNAME: - gcc_assert (c_dialect_objc ()); - return true; - default: - gcc_unreachable (); - } + { + case C_ID_ID: + return false; + case C_ID_ADDRSPACE: + return true; + case C_ID_TYPENAME: + return true; + case C_ID_CLASSNAME: + gcc_assert (c_dialect_objc ()); + return true; + default: + gcc_unreachable (); + } case CPP_KEYWORD: switch (token->keyword) { @@ -502,7 +505,7 @@ } case CPP_LESS: if (c_dialect_objc ()) - return true; + return true; return false; default: return false; @@ -601,19 +604,19 @@ { case CPP_NAME: switch (token->id_kind) - { - case C_ID_ID: - return false; - case C_ID_ADDRSPACE: - return true; - case C_ID_TYPENAME: - return true; - case C_ID_CLASSNAME: - gcc_assert (c_dialect_objc ()); - return true; - default: - gcc_unreachable (); - } + { + case C_ID_ID: + return false; + case C_ID_ADDRSPACE: + return true; + case C_ID_TYPENAME: + return true; + case C_ID_CLASSNAME: + gcc_assert (c_dialect_objc ()); + return true; + default: + gcc_unreachable (); + } case CPP_KEYWORD: switch (token->keyword) { @@ -650,13 +653,16 @@ case RID_FRACT: case RID_ACCUM: case RID_SAT: - return true; +#ifndef noCbC + case RID_CbC_CODE: +#endif + return true; default: return false; } case CPP_LESS: if (c_dialect_objc ()) - return true; + return true; return false; default: return false; @@ -791,15 +797,15 @@ the token we just peeked at. */ c_parser_set_source_position_from_token (token); c_parse_error (gmsgid, - /* Because c_parse_error does not understand - CPP_KEYWORD, keywords are treated like - identifiers. */ - (token->type == CPP_KEYWORD ? CPP_NAME : token->type), - /* ??? The C parser does not save the cpp flags of a - token, we need to pass 0 here and we will not get - the source spelling of some tokens but rather the - canonical spelling. */ - token->value, /*flags=*/0); + /* Because c_parse_error does not understand + CPP_KEYWORD, keywords are treated like + identifiers. */ + (token->type == CPP_KEYWORD ? CPP_NAME : token->type), + /* ??? The C parser does not save the cpp flags of a + token, we need to pass 0 here and we will not get + the source spelling of some tokens but rather the + canonical spelling. */ + token->value, /*flags=*/0); } /* If the next token is of the indicated TYPE, consume it. Otherwise, @@ -809,8 +815,8 @@ static bool c_parser_require (c_parser *parser, - enum cpp_ttype type, - const char *msgid) + enum cpp_ttype type, + const char *msgid) { if (c_parser_next_token_is (parser, type)) { @@ -829,8 +835,8 @@ static bool c_parser_require_keyword (c_parser *parser, - enum rid keyword, - const char *msgid) + enum rid keyword, + const char *msgid) { if (c_parser_next_token_is_keyword (parser, keyword)) { @@ -852,8 +858,8 @@ static void c_parser_skip_until_found (c_parser *parser, - enum cpp_ttype type, - const char *msgid) + enum cpp_ttype type, + const char *msgid) { unsigned nesting_depth = 0; @@ -867,27 +873,27 @@ c_token *token = c_parser_peek_token (parser); /* If we've reached the token we want, consume it and stop. */ if (token->type == type && !nesting_depth) - { - c_parser_consume_token (parser); - break; - } + { + c_parser_consume_token (parser); + break; + } /* If we've run out of tokens, stop. */ if (token->type == CPP_EOF) - return; + return; if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) - return; + return; if (token->type == CPP_OPEN_BRACE - || token->type == CPP_OPEN_PAREN - || token->type == CPP_OPEN_SQUARE) - ++nesting_depth; + || token->type == CPP_OPEN_PAREN + || token->type == CPP_OPEN_SQUARE) + ++nesting_depth; else if (token->type == CPP_CLOSE_BRACE - || token->type == CPP_CLOSE_PAREN - || token->type == CPP_CLOSE_SQUARE) - { - if (nesting_depth-- == 0) - break; - } + || token->type == CPP_CLOSE_PAREN + || token->type == CPP_CLOSE_SQUARE) + { + if (nesting_depth-- == 0) + break; + } /* Consume this token. */ c_parser_consume_token (parser); } @@ -906,24 +912,24 @@ { c_token *token = c_parser_peek_token (parser); if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON) - && !nesting_depth) - break; + && !nesting_depth) + break; /* If we've run out of tokens, stop. */ if (token->type == CPP_EOF) - return; + return; if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) - return; + return; if (token->type == CPP_OPEN_BRACE - || token->type == CPP_OPEN_PAREN - || token->type == CPP_OPEN_SQUARE) - ++nesting_depth; + || token->type == CPP_OPEN_PAREN + || token->type == CPP_OPEN_SQUARE) + ++nesting_depth; else if (token->type == CPP_CLOSE_BRACE - || token->type == CPP_CLOSE_PAREN - || token->type == CPP_CLOSE_SQUARE) - { - if (nesting_depth-- == 0) - break; - } + || token->type == CPP_CLOSE_PAREN + || token->type == CPP_CLOSE_SQUARE) + { + if (nesting_depth-- == 0) + break; + } /* Consume this token. */ c_parser_consume_token (parser); } @@ -942,15 +948,15 @@ if (!c_parser_require (parser, CPP_PRAGMA_EOL, "expected end of line")) while (true) { - c_token *token = c_parser_peek_token (parser); - if (token->type == CPP_EOF) - break; - if (token->type == CPP_PRAGMA_EOL) - { - c_parser_consume_token (parser); - break; - } - c_parser_consume_token (parser); + c_token *token = c_parser_peek_token (parser); + if (token->type == CPP_EOF) + break; + if (token->type == CPP_PRAGMA_EOL) + { + c_parser_consume_token (parser); + break; + } + c_parser_consume_token (parser); } parser->error = false; @@ -973,57 +979,57 @@ token = c_parser_peek_token (parser); switch (token->type) - { - case CPP_EOF: - return; - - case CPP_PRAGMA_EOL: - if (parser->in_pragma) - return; - break; - - case CPP_SEMICOLON: - /* If the next token is a ';', we have reached the - end of the statement. */ - if (!nesting_depth) - { - /* Consume the ';'. */ - c_parser_consume_token (parser); - goto finished; - } - break; - - case CPP_CLOSE_BRACE: - /* If the next token is a non-nested '}', then we have - reached the end of the current block. */ - if (nesting_depth == 0 || --nesting_depth == 0) - { - c_parser_consume_token (parser); - goto finished; - } - break; - - case CPP_OPEN_BRACE: - /* If it the next token is a '{', then we are entering a new - block. Consume the entire block. */ - ++nesting_depth; - break; - - case CPP_PRAGMA: - /* If we see a pragma, consume the whole thing at once. We - have some safeguards against consuming pragmas willy-nilly. - Normally, we'd expect to be here with parser->error set, - which disables these safeguards. But it's possible to get - here for secondary error recovery, after parser->error has - been cleared. */ - c_parser_consume_pragma (parser); - c_parser_skip_to_pragma_eol (parser); - parser->error = save_error; - continue; - - default: - break; - } + { + case CPP_EOF: + return; + + case CPP_PRAGMA_EOL: + if (parser->in_pragma) + return; + break; + + case CPP_SEMICOLON: + /* If the next token is a ';', we have reached the + end of the statement. */ + if (!nesting_depth) + { + /* Consume the ';'. */ + c_parser_consume_token (parser); + goto finished; + } + break; + + case CPP_CLOSE_BRACE: + /* If the next token is a non-nested '}', then we have + reached the end of the current block. */ + if (nesting_depth == 0 || --nesting_depth == 0) + { + c_parser_consume_token (parser); + goto finished; + } + break; + + case CPP_OPEN_BRACE: + /* If it the next token is a '{', then we are entering a new + block. Consume the entire block. */ + ++nesting_depth; + break; + + case CPP_PRAGMA: + /* If we see a pragma, consume the whole thing at once. We + have some safeguards against consuming pragmas willy-nilly. + Normally, we'd expect to be here with parser->error set, + which disables these safeguards. But it's possible to get + here for secondary error recovery, after parser->error has + been cleared. */ + c_parser_consume_pragma (parser); + c_parser_skip_to_pragma_eol (parser); + parser->error = save_error; + continue; + + default: + break; + } c_parser_consume_token (parser); } @@ -1101,12 +1107,12 @@ static tree c_parser_struct_declaration (c_parser *); static struct c_typespec c_parser_typeof_specifier (c_parser *); static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn, - bool *); + bool *); static struct c_declarator *c_parser_direct_declarator (c_parser *, bool, - c_dtr_syn, bool *); + c_dtr_syn, bool *); static struct c_declarator *c_parser_direct_declarator_inner (c_parser *, - bool, - struct c_declarator *); + bool, + struct c_declarator *); static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree); static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree); static struct c_parm *c_parser_parameter_declaration (c_parser *, tree); @@ -1134,7 +1140,7 @@ static tree c_parser_asm_clobbers (c_parser *); static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *); static struct c_expr c_parser_conditional_expression (c_parser *, - struct c_expr *); + struct c_expr *); static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *); static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *); static struct c_expr c_parser_unary_expression (c_parser *); @@ -1142,15 +1148,15 @@ static struct c_expr c_parser_alignof_expression (c_parser *); static struct c_expr c_parser_postfix_expression (c_parser *); static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, - struct c_type_name *, - location_t); + struct c_type_name *, + location_t); static struct c_expr c_parser_postfix_expression_after_primary (c_parser *, - location_t loc, - struct c_expr); + location_t loc, + struct c_expr); static struct c_expr c_parser_expression (c_parser *); static struct c_expr c_parser_expression_conv (c_parser *); static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool, - VEC(tree,gc) **); + VEC(tree,gc) **); static void c_parser_omp_construct (c_parser *); static void c_parser_omp_threadprivate (c_parser *); static void c_parser_omp_barrier (c_parser *); @@ -1208,18 +1214,18 @@ if (c_parser_next_token_is (parser, CPP_EOF)) { pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, - "ISO C forbids an empty translation unit"); + "ISO C forbids an empty translation unit"); } else { void *obstack_position = obstack_alloc (&parser_obstack, 0); mark_valid_location_for_stdc_pragma (false); do - { - ggc_collect (); - c_parser_external_declaration (parser); - obstack_free (&parser_obstack, obstack_position); - } + { + ggc_collect (); + c_parser_external_declaration (parser); + obstack_free (&parser_obstack, obstack_position); + } while (c_parser_next_token_is_not (parser, CPP_EOF)); } } @@ -1306,7 +1312,7 @@ break; case CPP_SEMICOLON: pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, - "ISO C does not allow extra %<;%> outside of a function"); + "ISO C does not allow extra %<;%> outside of a function"); c_parser_consume_token (parser); break; case CPP_PRAGMA: @@ -1317,12 +1323,12 @@ case CPP_PLUS: case CPP_MINUS: if (c_dialect_objc ()) - { - c_parser_objc_method_definition (parser); - break; - } + { + c_parser_objc_method_definition (parser); + break; + } /* Else fall through, and yield a syntax error trying to parse - as a declaration or function definition. */ + as a declaration or function definition. */ default: decl_or_fndef: /* A declaration or a function definition (or, in Objective-C, @@ -1460,12 +1466,12 @@ if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { if (empty_ok) - shadow_tag (specs); + shadow_tag (specs); else - { - shadow_tag_warned (specs, 1); - pedwarn (here, 0, "empty declaration"); - } + { + shadow_tag_warned (specs, 1); + pedwarn (here, 0, "empty declaration"); + } c_parser_consume_token (parser); return; } @@ -1577,10 +1583,10 @@ specs->typespec_kind != ctsk_none, C_DTR_NORMAL, &dummy); if (declarator == NULL) - { - c_parser_skip_to_end_of_block_or_statement (parser); - return; - } + { + c_parser_skip_to_end_of_block_or_statement (parser); + return; + } if (c_parser_next_token_is (parser, CPP_EQ) || c_parser_next_token_is (parser, CPP_COMMA) || c_parser_next_token_is (parser, CPP_SEMICOLON) @@ -1674,67 +1680,67 @@ } } else if (!fndef_ok) - { - c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, " - "% or %<__attribute__%>"); - c_parser_skip_to_end_of_block_or_statement (parser); - return; - } + { + c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, " + "% or %<__attribute__%>"); + c_parser_skip_to_end_of_block_or_statement (parser); + return; + } /* Function definition (nested or otherwise). */ if (nested) - { - pedwarn (here, OPT_pedantic, "ISO C forbids nested functions"); - c_push_function_context (); - } + { + pedwarn (here, OPT_pedantic, "ISO C forbids nested functions"); + c_push_function_context (); + } if (!start_function (specs, declarator, all_prefix_attrs)) - { - /* This can appear in many cases looking nothing like a - function definition, so we don't give a more specific - error suggesting there was one. */ - c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, % " - "or %<__attribute__%>"); - if (nested) - c_pop_function_context (); - break; - } + { + /* This can appear in many cases looking nothing like a + function definition, so we don't give a more specific + error suggesting there was one. */ + c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, % " + "or %<__attribute__%>"); + if (nested) + c_pop_function_context (); + break; + } /* Parse old-style parameter declarations. ??? Attributes are - not allowed to start declaration specifiers here because of a - syntax conflict between a function declaration with attribute - suffix and a function definition with an attribute prefix on - first old-style parameter declaration. Following the old - parser, they are not accepted on subsequent old-style - parameter declarations either. However, there is no - ambiguity after the first declaration, nor indeed on the - first as long as we don't allow postfix attributes after a - declarator with a nonempty identifier list in a definition; - and postfix attributes have never been accepted here in - function definitions either. */ + not allowed to start declaration specifiers here because of a + syntax conflict between a function declaration with attribute + suffix and a function definition with an attribute prefix on + first old-style parameter declaration. Following the old + parser, they are not accepted on subsequent old-style + parameter declarations either. However, there is no + ambiguity after the first declaration, nor indeed on the + first as long as we don't allow postfix attributes after a + declarator with a nonempty identifier list in a definition; + and postfix attributes have never been accepted here in + function definitions either. */ while (c_parser_next_token_is_not (parser, CPP_EOF) && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) c_parser_declaration_or_fndef (parser, false, false, false, true, false, NULL); store_parm_decls (); DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus - = c_parser_peek_token (parser)->location; + = c_parser_peek_token (parser)->location; fnbody = c_parser_compound_statement (parser); if (nested) - { - tree decl = current_function_decl; - /* Mark nested functions as needing static-chain initially. - lower_nested_functions will recompute it but the - DECL_STATIC_CHAIN flag is also used before that happens, - by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ - DECL_STATIC_CHAIN (decl) = 1; - add_stmt (fnbody); - finish_function (); - c_pop_function_context (); - add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); - } + { + tree decl = current_function_decl; + /* Mark nested functions as needing static-chain initially. + lower_nested_functions will recompute it but the + DECL_STATIC_CHAIN flag is also used before that happens, + by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ + DECL_STATIC_CHAIN (decl) = 1; + add_stmt (fnbody); + finish_function (); + c_pop_function_context (); + add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); + } else - { - add_stmt (fnbody); - finish_function (); - } + { + add_stmt (fnbody); + finish_function (); + } break; } } @@ -1950,8 +1956,8 @@ gcc_assert (la == cla_prefer_id); while (c_parser_next_token_is (parser, CPP_NAME) - || c_parser_next_token_is (parser, CPP_KEYWORD) - || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS))) + || c_parser_next_token_is (parser, CPP_KEYWORD) + || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS))) { struct c_typespec t; tree attrs; @@ -2025,21 +2031,21 @@ continue; } if (c_parser_next_token_is (parser, CPP_LESS)) - { - /* Make "" equivalent to "id " - - nisse@lysator.liu.se. */ - tree proto; - gcc_assert (c_dialect_objc ()); - if (!typespec_ok || seen_type) - break; - proto = c_parser_objc_protocol_refs (parser); - t.kind = ctsk_objc; - t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); - t.expr = NULL_TREE; - t.expr_const_operands = true; - declspecs_add_type (loc, specs, t); - continue; - } + { + /* Make "" equivalent to "id " - + nisse@lysator.liu.se. */ + tree proto; + gcc_assert (c_dialect_objc ()); + if (!typespec_ok || seen_type) + break; + proto = c_parser_objc_protocol_refs (parser); + t.kind = ctsk_objc; + t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); + t.expr = NULL_TREE; + t.expr_const_operands = true; + declspecs_add_type (loc, specs, t); + continue; + } gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD)); switch (c_parser_peek_token (parser)->keyword) { @@ -2090,6 +2096,30 @@ declspecs_add_type (loc, specs, t); c_parser_consume_token (parser); break; +#ifndef noCbC + case RID_CbC_CODE: + if (!typespec_ok) + goto out; + attrs_ok = true; + seen_type = true; + if (c_dialect_objc ()) + parser->objc_need_raw_identifier = true; + t.kind = ctsk_resword; + t.spec = c_parser_peek_token (parser)->value; + declspecs_add_type (loc, specs, t); + + /* + attrs = get_identifier("fastcall"); + attrs = build_tree_list(attrs, NULL_TREE); + declspecs_add_attrs(specs, attrs); + */ + attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE); + /*attrs = build_tree_list (get_identifier("noreturn"), attrs);*/ + declspecs_add_attrs(specs, attrs); + + c_parser_consume_token (parser); + break; +#endif case RID_ENUM: if (!typespec_ok) goto out; @@ -2106,35 +2136,35 @@ seen_type = true; t = c_parser_struct_or_union_specifier (parser); invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); - declspecs_add_type (loc, specs, t); - break; - case RID_TYPEOF: - /* ??? The old parser rejected typeof after other type - specifiers, but is a syntax error the best way of - handling this? */ - if (!typespec_ok || seen_type) - goto out; - attrs_ok = true; - seen_type = true; - t = c_parser_typeof_specifier (parser); - declspecs_add_type (loc, specs, t); - break; - case RID_CONST: - case RID_VOLATILE: - case RID_RESTRICT: - attrs_ok = true; - declspecs_add_qual (specs, c_parser_peek_token (parser)->value); - c_parser_consume_token (parser); - break; - case RID_ATTRIBUTE: - if (!attrs_ok) - goto out; - attrs = c_parser_attributes (parser); - declspecs_add_attrs (specs, attrs); - break; - default: - goto out; - } + declspecs_add_type (loc, specs, t); + break; + case RID_TYPEOF: + /* ??? The old parser rejected typeof after other type + specifiers, but is a syntax error the best way of + handling this? */ + if (!typespec_ok || seen_type) + goto out; + attrs_ok = true; + seen_type = true; + t = c_parser_typeof_specifier (parser); + declspecs_add_type (loc, specs, t); + break; + case RID_CONST: + case RID_VOLATILE: + case RID_RESTRICT: + attrs_ok = true; + declspecs_add_qual (specs, c_parser_peek_token (parser)->value); + c_parser_consume_token (parser); + break; + case RID_ATTRIBUTE: + if (!attrs_ok) + goto out; + attrs = c_parser_attributes (parser); + declspecs_add_attrs (specs, attrs); + break; + default: + goto out; + } } out: ; } @@ -2190,7 +2220,7 @@ tree type = start_enum (enum_loc, &the_enum, ident); tree postfix_attrs; /* We chain the enumerators in reverse order, then put them in - forward order at the end. */ + forward order at the end. */ tree values = NULL_TREE; c_parser_consume_token (parser); while (true) @@ -2251,7 +2281,7 @@ } postfix_attrs = c_parser_attributes (parser); ret.spec = finish_enum (type, nreverse (values), - chainon (attrs, postfix_attrs)); + chainon (attrs, postfix_attrs)); ret.kind = ctsk_tagdef; ret.expr = NULL_TREE; ret.expr_const_operands = true; @@ -2273,7 +2303,7 @@ { gcc_assert (ident); pedwarn (enum_loc, OPT_pedantic, - "ISO C forbids forward references to % types"); + "ISO C forbids forward references to % types"); } return ret; } @@ -2354,51 +2384,51 @@ if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { /* Parse a struct or union definition. Start the scope of the - tag before parsing components. */ + tag before parsing components. */ struct c_struct_parse_info *struct_info; tree type = start_struct (struct_loc, code, ident, &struct_info); tree postfix_attrs; /* We chain the components in reverse order, then put them in - forward order at the end. Each struct-declaration may - declare multiple components (comma-separated), so we must use - chainon to join them, although when parsing each - struct-declaration we can use TREE_CHAIN directly. - - The theory behind all this is that there will be more - semicolon separated fields than comma separated fields, and - so we'll be minimizing the number of node traversals required - by chainon. */ + forward order at the end. Each struct-declaration may + declare multiple components (comma-separated), so we must use + chainon to join them, although when parsing each + struct-declaration we can use TREE_CHAIN directly. + + The theory behind all this is that there will be more + semicolon separated fields than comma separated fields, and + so we'll be minimizing the number of node traversals required + by chainon. */ tree contents = NULL_TREE; c_parser_consume_token (parser); /* Handle the Objective-C @defs construct, - e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ + e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS)) - { - tree name; - gcc_assert (c_dialect_objc ()); - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - goto end_at_defs; - if (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) - { - name = c_parser_peek_token (parser)->value; - c_parser_consume_token (parser); - } - else - { - c_parser_error (parser, "expected class name"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - goto end_at_defs; - } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - contents = nreverse (objc_get_class_ivars (name)); - } + { + tree name; + gcc_assert (c_dialect_objc ()); + c_parser_consume_token (parser); + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + goto end_at_defs; + if (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) + { + name = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + } + else + { + c_parser_error (parser, "expected class name"); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + goto end_at_defs; + } + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + contents = nreverse (objc_get_class_ivars (name)); + } end_at_defs: /* Parse the struct-declarations and semicolons. Problems with - semicolons are diagnosed here; empty structures are diagnosed - elsewhere. */ + semicolons are diagnosed here; empty structures are diagnosed + elsewhere. */ while (true) { tree decls; @@ -2451,7 +2481,7 @@ } postfix_attrs = c_parser_attributes (parser); ret.spec = finish_struct (struct_loc, type, nreverse (contents), - chainon (attrs, postfix_attrs), struct_info); + chainon (attrs, postfix_attrs), struct_info); ret.kind = ctsk_tagdef; ret.expr = NULL_TREE; ret.expr_const_operands = true; @@ -2548,18 +2578,18 @@ ret = NULL_TREE; } else - { - /* Support for unnamed structs or unions as members of - structs or unions (which is [a] useful and [b] supports - MS P-SDK). */ - tree attrs = NULL; - - ret = grokfield (c_parser_peek_token (parser)->location, - build_id_declarator (NULL_TREE), specs, - NULL_TREE, &attrs); - if (ret) - decl_attributes (&ret, attrs, 0); - } + { + /* Support for unnamed structs or unions as members of + structs or unions (which is [a] useful and [b] supports + MS P-SDK). */ + tree attrs = NULL; + + ret = grokfield (c_parser_peek_token (parser)->location, + build_id_declarator (NULL_TREE), specs, + NULL_TREE, &attrs); + if (ret) + decl_attributes (&ret, attrs, 0); + } return ret; } @@ -2586,16 +2616,16 @@ struct c_declarator *declarator; bool dummy = false; if (c_parser_next_token_is (parser, CPP_COLON)) - declarator = build_id_declarator (NULL_TREE); + declarator = build_id_declarator (NULL_TREE); else declarator = c_parser_declarator (parser, specs->typespec_kind != ctsk_none, C_DTR_NORMAL, &dummy); if (declarator == NULL) - { - c_parser_skip_to_end_of_block_or_statement (parser); - break; - } + { + c_parser_skip_to_end_of_block_or_statement (parser); + break; + } if (c_parser_next_token_is (parser, CPP_COLON) || c_parser_next_token_is (parser, CPP_COMMA) || c_parser_next_token_is (parser, CPP_SEMICOLON) @@ -2638,12 +2668,28 @@ } } else - { - c_parser_error (parser, - "expected %<:%>, %<,%>, %<;%>, %<}%> or " - "%<__attribute__%>"); - break; - } + all_prefix_attrs = prefix_attrs; + if (c_parser_next_token_is (parser, CPP_COMMA)) + c_parser_consume_token (parser); + else if (c_parser_next_token_is (parser, CPP_SEMICOLON) + || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) + { + /* Semicolon consumed in caller. */ + break; + } + else + { + c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>"); + break; + } + } + else + { + c_parser_error (parser, + "expected %<:%>, %<,%>, %<;%>, %<}%> or " + "%<__attribute__%>"); + break; + } } return decls; } @@ -2679,10 +2725,10 @@ c_inhibit_evaluation_warnings--; in_typeof--; if (type != NULL) - { - ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands); - pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE)); - } + { + ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands); + pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE)); + } } else { @@ -2698,9 +2744,9 @@ ret.spec = TREE_TYPE (expr.value); was_vm = variably_modified_type_p (ret.spec, NULL_TREE); /* This is returned with the type so that when the type is - evaluated, this can be evaluated. */ + evaluated, this can be evaluated. */ if (was_vm) - ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands); + ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands); pop_maybe_used (was_vm); } c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -2765,11 +2811,11 @@ direct-declarator: direct-declarator ( parameter-forward-declarations - parameter-type-list[opt] ) + parameter-type-list[opt] ) direct-abstract-declarator: direct-abstract-declarator[opt] ( parameter-forward-declarations - parameter-type-list[opt] ) + parameter-type-list[opt] ) parameter-forward-declarations: parameter-list ; @@ -2786,7 +2832,7 @@ static struct c_declarator * c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, - bool *seen_id) + bool *seen_id) { /* Parse any initial pointer part. */ if (c_parser_next_token_is (parser, CPP_MULT)) @@ -2797,9 +2843,9 @@ c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id); inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); if (inner == NULL) - return NULL; + return NULL; else - return make_pointer_declarator (quals_attrs, inner); + return make_pointer_declarator (quals_attrs, inner); } /* Now we have a direct declarator, direct abstract declarator or nothing (which counts as a direct abstract declarator here). */ @@ -2811,7 +2857,7 @@ static struct c_declarator * c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, - bool *seen_id) + bool *seen_id) { /* The direct declarator must start with an identifier (possibly omitted) or a parenthesized declarator (possibly abstract). In @@ -2855,7 +2901,7 @@ || c_parser_peek_token (parser)->id_kind == C_ID_ID)) { struct c_declarator *inner - = build_id_declarator (c_parser_peek_token (parser)->value); + = build_id_declarator (c_parser_peek_token (parser)->value); *seen_id = true; inner->id_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); @@ -2879,51 +2925,51 @@ c_parser_consume_token (parser); attrs = c_parser_attributes (parser); if (kind != C_DTR_NORMAL - && (c_parser_next_token_starts_declspecs (parser) - || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) - { - struct c_arg_info *args - = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL, - attrs); - if (args == NULL) - return NULL; - else - { - inner - = build_function_declarator (args, - build_id_declarator (NULL_TREE)); - return c_parser_direct_declarator_inner (parser, *seen_id, - inner); - } - } + && (c_parser_next_token_starts_declspecs (parser) + || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) + { + struct c_arg_info *args + = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL, + attrs); + if (args == NULL) + return NULL; + else + { + inner + = build_function_declarator (args, + build_id_declarator (NULL_TREE)); + return c_parser_direct_declarator_inner (parser, *seen_id, + inner); + } + } /* A parenthesized declarator. */ inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); if (inner != NULL && attrs != NULL) - inner = build_attrs_declarator (attrs, inner); + inner = build_attrs_declarator (attrs, inner); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - { - c_parser_consume_token (parser); - if (inner == NULL) - return NULL; - else - return c_parser_direct_declarator_inner (parser, *seen_id, inner); - } + { + c_parser_consume_token (parser); + if (inner == NULL) + return NULL; else - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - return NULL; - } + return c_parser_direct_declarator_inner (parser, *seen_id, inner); + } + else + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + return NULL; + } } else { if (kind == C_DTR_NORMAL) - { - c_parser_error (parser, "expected identifier or %<(%>"); - return NULL; - } + { + c_parser_error (parser, "expected identifier or %<(%>"); + return NULL; + } else - return build_id_declarator (NULL_TREE); + return build_id_declarator (NULL_TREE); } } @@ -2934,7 +2980,7 @@ static struct c_declarator * c_parser_direct_declarator_inner (c_parser *parser, bool id_present, - struct c_declarator *inner) + struct c_declarator *inner) { /* Parse a sequence of array declarators and parameter lists. */ if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) @@ -2949,48 +2995,40 @@ c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id); static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC); if (static_seen) - c_parser_consume_token (parser); + c_parser_consume_token (parser); if (static_seen && !quals_attrs->declspecs_seen_p) c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id); if (!quals_attrs->declspecs_seen_p) - quals_attrs = NULL; + quals_attrs = NULL; /* If "static" is present, there must be an array dimension. - Otherwise, there may be a dimension, "*", or no - dimension. */ + Otherwise, there may be a dimension, "*", or no + dimension. */ if (static_seen) - { - star_seen = false; - dimen = c_parser_expr_no_commas (parser, NULL).value; - } + { + star_seen = false; + dimen = c_parser_expr_no_commas (parser, NULL).value; + } else - { - if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) - { - dimen = NULL_TREE; - star_seen = false; - } - else if (c_parser_next_token_is (parser, CPP_MULT)) - { - if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE) - { - dimen = NULL_TREE; - star_seen = true; - c_parser_consume_token (parser); - } - else - { - star_seen = false; - dimen = c_parser_expr_no_commas (parser, NULL).value; - } - } - else - { - star_seen = false; - dimen = c_parser_expr_no_commas (parser, NULL).value; - } - } + { if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) - c_parser_consume_token (parser); + { + dimen = NULL_TREE; + star_seen = false; + } + else if (c_parser_next_token_is (parser, CPP_MULT)) + { + if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE) + { + dimen = NULL_TREE; + star_seen = true; + c_parser_consume_token (parser); + } + else + { + star_seen = false; + dimen = c_parser_expr_no_commas (parser, NULL).value; + } + } else { c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, @@ -3000,9 +3038,9 @@ if (dimen) mark_exp_read (dimen); declarator = build_array_declarator (brace_loc, dimen, quals_attrs, - static_seen, star_seen); + static_seen, star_seen); if (declarator == NULL) - return NULL; + return NULL; inner = set_array_declarator_inner (declarator, inner); return c_parser_direct_declarator_inner (parser, id_present, inner); } @@ -3014,12 +3052,12 @@ attrs = c_parser_attributes (parser); args = c_parser_parms_declarator (parser, id_present, attrs); if (args == NULL) - return NULL; + return NULL; else - { - inner = build_function_declarator (args, inner); - return c_parser_direct_declarator_inner (parser, id_present, inner); - } + { + inner = build_function_declarator (args, inner); + return c_parser_direct_declarator_inner (parser, id_present, inner); + } } return inner; } @@ -3049,21 +3087,15 @@ { tree list = NULL_TREE, *nextp = &list; while (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_token (parser)->id_kind == C_ID_ID) - { - *nextp = build_tree_list (NULL_TREE, - c_parser_peek_token (parser)->value); - nextp = & TREE_CHAIN (*nextp); - c_parser_consume_token (parser); - if (c_parser_next_token_is_not (parser, CPP_COMMA)) - break; - c_parser_consume_token (parser); - if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - { - c_parser_error (parser, "expected identifier"); - break; - } - } + && c_parser_peek_token (parser)->id_kind == C_ID_ID) + { + *nextp = build_tree_list (NULL_TREE, + c_parser_peek_token (parser)->value); + nextp = & TREE_CHAIN (*nextp); + c_parser_consume_token (parser); + if (c_parser_next_token_is_not (parser, CPP_COMMA)) + break; + c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { struct c_arg_info *ret = build_arg_info (); @@ -3073,12 +3105,12 @@ return ret; } else - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - pop_scope (); - return NULL; - } + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + pop_scope (); + return NULL; + } } else { @@ -3114,19 +3146,19 @@ /* Suppress -Wold-style-definition for this case. */ ret->types = error_mark_node; error_at (c_parser_peek_token (parser)->location, - "ISO C requires a named argument before %<...%>"); + "ISO C requires a named argument before %<...%>"); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - { - c_parser_consume_token (parser); - return ret; - } + { + c_parser_consume_token (parser); + return ret; + } else - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - return NULL; - } + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + return NULL; + } } /* Nonempty list of parameters, either terminated with semicolon (forward declarations; recurse) or with close parenthesis (normal @@ -3141,13 +3173,13 @@ else push_parm_decl (parm); if (c_parser_next_token_is (parser, CPP_SEMICOLON)) - { - tree new_attrs; - c_parser_consume_token (parser); - mark_forward_parm_decls (); - new_attrs = c_parser_attributes (parser); - return c_parser_parms_list_declarator (parser, new_attrs); - } + { + tree new_attrs; + c_parser_consume_token (parser); + mark_forward_parm_decls (); + new_attrs = c_parser_attributes (parser); + return c_parser_parms_list_declarator (parser, new_attrs); + } if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { c_parser_consume_token (parser); @@ -3160,12 +3192,12 @@ return get_parm_info (false); } if (!c_parser_require (parser, CPP_COMMA, - "expected %<;%>, %<,%> or %<)%>")) - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - get_pending_sizes (); - return NULL; - } + "expected %<;%>, %<,%> or %<)%>")) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + get_pending_sizes (); + return NULL; + } if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) { c_parser_consume_token (parser); @@ -3243,7 +3275,7 @@ if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) postfix_attrs = c_parser_attributes (parser); return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs), - declarator); + declarator); } /* Parse a string literal in an asm expression. It should not be @@ -3269,7 +3301,7 @@ else if (c_parser_next_token_is (parser, CPP_WSTRING)) { error_at (c_parser_peek_token (parser)->location, - "wide string literal in %"); + "wide string literal in %"); str = build_string (1, ""); c_parser_consume_token (parser); } @@ -3347,20 +3379,20 @@ while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) { /* ??? Follow the C++ parser rather than using the - lex_untranslated_string kludge. */ + lex_untranslated_string kludge. */ parser->lex_untranslated_string = true; c_parser_consume_token (parser); if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - parser->lex_untranslated_string = false; - return attrs; - } + { + parser->lex_untranslated_string = false; + return attrs; + } if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - parser->lex_untranslated_string = false; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - return attrs; - } + { + parser->lex_untranslated_string = false; + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + return attrs; + } /* Parse the attribute list. */ while (c_parser_next_token_is (parser, CPP_COMMA) || c_parser_next_token_is (parser, CPP_NAME) @@ -3482,23 +3514,34 @@ attrs = chainon (attrs, attr); } if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - { - parser->lex_untranslated_string = false; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - return attrs; - } + { + parser->lex_untranslated_string = false; + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + return attrs; + } + attrs = chainon (attrs, attr); + } if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - { - parser->lex_untranslated_string = false; - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - return attrs; - } + { + parser->lex_untranslated_string = false; + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + return attrs; + } + if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) + c_parser_consume_token (parser); + else + { + parser->lex_untranslated_string = false; + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + return attrs; + } parser->lex_untranslated_string = false; } return attrs; @@ -3625,7 +3668,7 @@ else { /* Parse a non-empty initializer list, possibly with a trailing - comma. */ + comma. */ while (true) { c_parser_initelt (parser, &braced_init_obstack); @@ -3671,14 +3714,14 @@ braced_init_obstack); /* Use the colon as the error location. */ pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic, - "obsolete use of designated initializer with %<:%>"); + "obsolete use of designated initializer with %<:%>"); c_parser_consume_token (parser); c_parser_consume_token (parser); } else { /* des_seen is 0 if there have been no designators, 1 if there - has been a single array designator and 2 otherwise. */ + has been a single array designator and 2 otherwise. */ int des_seen = 0; /* Location of a designator. */ location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */ @@ -3937,7 +3980,7 @@ if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) { /* Ensure a scope is entered and left anyway to avoid confusion - if we have just prepared to enter a function body. */ + if we have just prepared to enter a function body. */ stmt = c_begin_compound_stmt (true); c_end_compound_stmt (brace_loc, stmt, true); return error_mark_node; @@ -3967,34 +4010,34 @@ if (c_parser_next_token_is_keyword (parser, RID_LABEL)) { /* Read zero or more forward-declarations for labels that nested - functions can jump to. */ + functions can jump to. */ mark_valid_location_for_stdc_pragma (false); while (c_parser_next_token_is_keyword (parser, RID_LABEL)) - { - label_loc = c_parser_peek_token (parser)->location; - c_parser_consume_token (parser); - /* Any identifiers, including those declared as type names, - are OK here. */ - while (true) - { - tree label; - if (c_parser_next_token_is_not (parser, CPP_NAME)) - { - c_parser_error (parser, "expected identifier"); - break; - } - label - = declare_label (c_parser_peek_token (parser)->value); - C_DECLARED_LABEL_FLAG (label) = 1; - add_stmt (build_stmt (label_loc, DECL_EXPR, label)); - c_parser_consume_token (parser); - if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); - else - break; - } - c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); - } + { + label_loc = c_parser_peek_token (parser)->location; + c_parser_consume_token (parser); + /* Any identifiers, including those declared as type names, + are OK here. */ + while (true) + { + tree label; + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + c_parser_error (parser, "expected identifier"); + break; + } + label + = declare_label (c_parser_peek_token (parser)->value); + C_DECLARED_LABEL_FLAG (label) = 1; + add_stmt (build_stmt (label_loc, DECL_EXPR, label)); + c_parser_consume_token (parser); + if (c_parser_next_token_is (parser, CPP_COMMA)) + c_parser_consume_token (parser); + else + break; + } + c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); + } pedwarn (label_loc, OPT_pedantic, "ISO C forbids label declarations"); } /* We must now have at least one statement, label or declaration. */ @@ -4009,19 +4052,19 @@ { location_t loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is_keyword (parser, RID_CASE) - || c_parser_next_token_is_keyword (parser, RID_DEFAULT) - || (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) - { - if (c_parser_next_token_is_keyword (parser, RID_CASE)) - label_loc = c_parser_peek_2nd_token (parser)->location; - else - label_loc = c_parser_peek_token (parser)->location; - last_label = true; - last_stmt = false; - mark_valid_location_for_stdc_pragma (false); - c_parser_label (parser); - } + || c_parser_next_token_is_keyword (parser, RID_DEFAULT) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + { + if (c_parser_next_token_is_keyword (parser, RID_CASE)) + label_loc = c_parser_peek_2nd_token (parser)->location; + else + label_loc = c_parser_peek_token (parser)->location; + last_label = true; + last_stmt = false; + mark_valid_location_for_stdc_pragma (false); + c_parser_label (parser); + } else if (!last_label && c_parser_next_tokens_start_declaration (parser)) { @@ -4070,26 +4113,26 @@ goto statement; } else if (c_parser_next_token_is (parser, CPP_PRAGMA)) - { - /* External pragmas, and some omp pragmas, are not associated - with regular c code, and so are not to be considered statements - syntactically. This ensures that the user doesn't put them - places that would turn into syntax errors if the directive - were ignored. */ - if (c_parser_pragma (parser, pragma_compound)) - last_label = false, last_stmt = true; - } + { + /* External pragmas, and some omp pragmas, are not associated + with regular c code, and so are not to be considered statements + syntactically. This ensures that the user doesn't put them + places that would turn into syntax errors if the directive + were ignored. */ + if (c_parser_pragma (parser, pragma_compound)) + last_label = false, last_stmt = true; + } else if (c_parser_next_token_is (parser, CPP_EOF)) - { - mark_valid_location_for_stdc_pragma (save_valid_for_pragma); - c_parser_error (parser, "expected declaration or statement"); - return; - } + { + mark_valid_location_for_stdc_pragma (save_valid_for_pragma); + c_parser_error (parser, "expected declaration or statement"); + return; + } else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) { if (parser->in_if_block) { - mark_valid_location_for_stdc_pragma (save_valid_for_pragma); + mark_valid_location_for_stdc_pragma (save_valid_for_pragma); error_at (loc, """expected %<}%> before %"); return; } @@ -4101,13 +4144,13 @@ } } else - { - statement: - last_label = false; - last_stmt = true; - mark_valid_location_for_stdc_pragma (false); - c_parser_statement_after_labels (parser); - } + { + statement: + last_label = false; + last_stmt = true; + mark_valid_location_for_stdc_pragma (false); + c_parser_statement_after_labels (parser); + } parser->error = false; } @@ -4145,25 +4188,25 @@ c_parser_consume_token (parser); exp1 = c_parser_expr_no_commas (parser, NULL).value; if (c_parser_next_token_is (parser, CPP_COLON)) - { - c_parser_consume_token (parser); - label = do_case (loc1, exp1, NULL_TREE); - } + { + c_parser_consume_token (parser); + label = do_case (loc1, exp1, NULL_TREE); + } else if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) - { - c_parser_consume_token (parser); - exp2 = c_parser_expr_no_commas (parser, NULL).value; - if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) - label = do_case (loc1, exp1, exp2); - } + { + c_parser_consume_token (parser); + exp2 = c_parser_expr_no_commas (parser, NULL).value; + if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) + label = do_case (loc1, exp1, exp2); + } else - c_parser_error (parser, "expected %<:%> or %<...%>"); + c_parser_error (parser, "expected %<:%> or %<...%>"); } else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) { c_parser_consume_token (parser); if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) - label = do_case (loc1, NULL_TREE, NULL_TREE); + label = do_case (loc1, NULL_TREE, NULL_TREE); } else { @@ -4178,10 +4221,10 @@ attrs = c_parser_attributes (parser); tlab = define_label (loc2, name); if (tlab) - { - decl_attributes (&tlab, attrs, 0); - label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab)); - } + { + decl_attributes (&tlab, attrs, 0); + label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab)); + } } if (label) { @@ -4299,18 +4342,92 @@ c_parser_statement (c_parser *parser) { while (c_parser_next_token_is_keyword (parser, RID_CASE) - || c_parser_next_token_is_keyword (parser, RID_DEFAULT) - || (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + || c_parser_next_token_is_keyword (parser, RID_DEFAULT) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) c_parser_label (parser); c_parser_statement_after_labels (parser); } +#if 0 +static tree +c_parser_cbc_make_env(c_parser *parser) +{ + struct c_expr env; + tree field, fields=NULL_TREE; + tree env_struct, env_struct_type; + tree ebp, argsp; + tree tmp; + + c_parser_consume_token (parser); + env = c_parser_expr_no_commas (parser, NULL); + env = default_function_array_conversion (env); + + /* build type_node of environment structure */ + env_struct_type = start_struct (RECORD_TYPE, NULL_TREE); + field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node); + fields = chainon (field, fields); + field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node); + fields = chainon (field, fields); + //field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node); + //fields = chainon (field, fields); + fields = nreverse(fields); + finish_struct (env_struct_type, fields, NULL_TREE); + + env_struct = build_c_cast (build_pointer_type(env_struct_type), env.value); + //build_component_ref (cbc_env, get_identifier("argsp")); + ebp = build_component_ref (build_indirect_ref (loc,env_struct, "CbCenv->sp"), get_identifier("sp")); + argsp = build_component_ref (build_indirect_ref (loc, env_struct, "CbCenv->sp"), get_identifier("argsp")); + //ebp = chainon (ebp, argsp); + tmp = build_tree_list (ebp, argsp); + + return tmp; +} +#endif + +static tree +cbc_replace_arguments (location_t loc, tree call) +{ + tree args; + tree fn; + tree tmp_decl; + int i=0; + + fn = CALL_EXPR_FN (call); + if ( TREE_CODE (fn)==PARM_DECL || !TREE_CONSTANT (fn) ) + { + tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(fn)); + pushdecl (tmp_decl); + + add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, fn, NULL_TREE)); + CALL_EXPR_FN (call) = tmp_decl; + } + + args = CALL_EXPR_ARGS (call); + for ( ;args; args = TREE_CHAIN (args), i++) + { + tree arg = TREE_VALUE (args); + + //if ( !CONSTANT_CLASS_P (arg) && !VAR_OR_FUNCTION_DECL_P (arg) ) + if ( TREE_CODE (arg)==PARM_DECL || !TREE_CONSTANT (arg) ) + { + tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(arg)); + pushdecl (tmp_decl); + + add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, arg, NULL_TREE)); + CALL_EXPR_ARG (call, i) = tmp_decl; + } + } + + return call; +} + /* Parse a statement, other than a labeled statement. */ static void c_parser_statement_after_labels (c_parser *parser) { + struct c_expr expr; location_t loc = c_parser_peek_token (parser)->location; tree stmt = NULL_TREE; bool in_if_block = parser->in_if_block; @@ -4340,8 +4457,14 @@ break; case RID_GOTO: c_parser_consume_token (parser); +#ifndef noCbC + if ( c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON ) + { +#else if (c_parser_next_token_is (parser, CPP_NAME)) - { + { +#endif stmt = c_finish_goto_label (loc, c_parser_peek_token (parser)->value); c_parser_consume_token (parser); @@ -4349,15 +4472,40 @@ else if (c_parser_next_token_is (parser, CPP_MULT)) { tree val; - c_parser_consume_token (parser); val = c_parser_expression (parser).value; mark_exp_read (val); stmt = c_finish_goto_ptr (loc, val); } else +#ifndef noCbC + { + if (c_parser_next_token_is (parser, CPP_NAME)) + { + tree id = c_parser_peek_token (parser)->value; + location_t loc = c_parser_peek_token (parser)->location; + /** build_external_ref (id,RID_CbC_CODE , loc); **/ + build_external_ref (loc, id, RID_CbC_CODE, &expr.original_type); + } + expr = c_parser_expr_no_commas (parser, NULL); + if (TREE_CODE(expr.value) == CALL_EXPR ) + { + location_t loc = c_parser_peek_token (parser)->location; + cbc_replace_arguments (loc, expr.value); + TREE_TYPE(expr.value) = void_type_node; + /*tree env = NULL_TREE;**/ + CbC_IS_CbC_GOTO (expr.value) = 1; + CALL_EXPR_TAILCALL (expr.value) = 1; + add_stmt(expr.value); + stmt = c_finish_return(loc, NULL_TREE, NULL_TREE); /* stmt = c_finish_return (0); */ + } + else + c_parser_error (parser, "expected code segment jump or %<*%>"); + } +#else c_parser_error (parser, "expected identifier or %<*%>"); - goto expect_semicolon; +#endif + goto expect_semicolon; case RID_CONTINUE: c_parser_consume_token (parser); stmt = c_finish_bc_stmt (loc, &c_cont_label, false); @@ -4418,9 +4566,9 @@ case CPP_CLOSE_PAREN: case CPP_CLOSE_SQUARE: /* Avoid infinite loop in error recovery: - c_parser_skip_until_found stops at a closing nesting - delimiter without consuming it, but here we need to consume - it to proceed further. */ + c_parser_skip_until_found stops at a closing nesting + delimiter without consuming it, but here we need to consume + it to proceed further. */ c_parser_error (parser, "expected statement"); c_parser_consume_token (parser); break; @@ -4507,9 +4655,9 @@ tree block = c_begin_compound_stmt (flag_isoc99); location_t body_loc = c_parser_peek_token (parser)->location; while (c_parser_next_token_is_keyword (parser, RID_CASE) - || c_parser_next_token_is_keyword (parser, RID_DEFAULT) - || (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + || c_parser_next_token_is_keyword (parser, RID_DEFAULT) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) c_parser_label (parser); *if_p = c_parser_next_token_is_keyword (parser, RID_IF); if (c_parser_next_token_is (parser, CPP_SEMICOLON)) @@ -4518,8 +4666,8 @@ add_stmt (build_empty_stmt (loc)); c_parser_consume_token (parser); if (!c_parser_next_token_is_keyword (parser, RID_ELSE)) - warning_at (loc, OPT_Wempty_body, - "suggest braces around empty body in an % statement"); + warning_at (loc, OPT_Wempty_body, + "suggest braces around empty body in an % statement"); } else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) add_stmt (c_parser_compound_statement (parser)); @@ -4538,16 +4686,16 @@ location_t else_loc = c_parser_peek_token (parser)->location; tree block = c_begin_compound_stmt (flag_isoc99); while (c_parser_next_token_is_keyword (parser, RID_CASE) - || c_parser_next_token_is_keyword (parser, RID_DEFAULT) - || (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + || c_parser_next_token_is_keyword (parser, RID_DEFAULT) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) c_parser_label (parser); if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { location_t loc = c_parser_peek_token (parser)->location; warning_at (loc, - OPT_Wempty_body, - "suggest braces around empty body in an % statement"); + OPT_Wempty_body, + "suggest braces around empty body in an % statement"); add_stmt (build_empty_stmt (loc)); c_parser_consume_token (parser); } @@ -4677,8 +4825,8 @@ c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_SEMICOLON)) warning_at (c_parser_peek_token (parser)->location, - OPT_Wempty_body, - "suggest braces around empty body in % statement"); + OPT_Wempty_body, + "suggest braces around empty body in % statement"); block = c_begin_compound_stmt (flag_isoc99); loc = c_parser_peek_token (parser)->location; save_break = c_break_label; @@ -4944,12 +5092,12 @@ c_parser_consume_token (parser); } else if (c_parser_next_token_is_keyword (parser, RID_CONST) - || c_parser_next_token_is_keyword (parser, RID_RESTRICT)) + || c_parser_next_token_is_keyword (parser, RID_RESTRICT)) { warning_at (c_parser_peek_token (parser)->location, - 0, - "%E qualifier ignored on asm", - c_parser_peek_token (parser)->value); + 0, + "%E qualifier ignored on asm", + c_parser_peek_token (parser)->value); quals = NULL_TREE; c_parser_consume_token (parser); } @@ -4989,40 +5137,40 @@ for (section = 0; section < nsections; ++section) { if (!c_parser_require (parser, CPP_COLON, - is_goto - ? "expected %<:%>" - : "expected %<:%> or %<)%>")) - goto error_close_paren; + is_goto + ? "expected %<:%>" + : "expected %<:%> or %<)%>")) + goto error_close_paren; /* Once past any colon, we're no longer a simple asm. */ simple = false; if ((!c_parser_next_token_is (parser, CPP_COLON) - && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - || section == 3) - switch (section) - { - case 0: - /* For asm goto, we don't allow output operands, but reserve - the slot for a future extension that does allow them. */ - if (!is_goto) - outputs = c_parser_asm_operands (parser, false); - break; - case 1: - inputs = c_parser_asm_operands (parser, true); - break; - case 2: - clobbers = c_parser_asm_clobbers (parser); - break; - case 3: - labels = c_parser_asm_goto_operands (parser); - break; - default: - gcc_unreachable (); - } + && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) + || section == 3) + switch (section) + { + case 0: + /* For asm goto, we don't allow output operands, but reserve + the slot for a future extension that does allow them. */ + if (!is_goto) + outputs = c_parser_asm_operands (parser, false); + break; + case 1: + inputs = c_parser_asm_operands (parser, true); + break; + case 2: + clobbers = c_parser_asm_clobbers (parser); + break; + case 3: + labels = c_parser_asm_goto_operands (parser); + break; + default: + gcc_unreachable (); + } if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto) - goto done_asm; + goto done_asm; } done_asm: @@ -5036,7 +5184,7 @@ c_parser_skip_to_end_of_block_or_statement (parser); ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs, - clobbers, labels, simple)); + clobbers, labels, simple)); error: parser->lex_untranslated_string = false; @@ -5070,53 +5218,53 @@ tree name, str; struct c_expr expr; if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) - { - c_parser_consume_token (parser); - if (c_parser_next_token_is (parser, CPP_NAME)) - { - tree id = c_parser_peek_token (parser)->value; - c_parser_consume_token (parser); - name = build_string (IDENTIFIER_LENGTH (id), - IDENTIFIER_POINTER (id)); - } - else - { - c_parser_error (parser, "expected identifier"); - c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); - return NULL_TREE; - } - c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, - "expected %<]%>"); - } + { + c_parser_consume_token (parser); + if (c_parser_next_token_is (parser, CPP_NAME)) + { + tree id = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + name = build_string (IDENTIFIER_LENGTH (id), + IDENTIFIER_POINTER (id)); + } else - name = NULL_TREE; + { + c_parser_error (parser, "expected identifier"); + c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); + return NULL_TREE; + } + c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, + "expected %<]%>"); + } + else + name = NULL_TREE; str = c_parser_asm_string_literal (parser); if (str == NULL_TREE) - return NULL_TREE; + return NULL_TREE; parser->lex_untranslated_string = false; if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - parser->lex_untranslated_string = true; - return NULL_TREE; - } + { + parser->lex_untranslated_string = true; + return NULL_TREE; + } loc = c_parser_peek_token (parser)->location; expr = c_parser_expression (parser); mark_exp_read (expr.value); if (convert_p) - expr = default_function_array_conversion (loc, expr); + expr = default_function_array_conversion (loc, expr); expr.value = c_fully_fold (expr.value, false, NULL); parser->lex_untranslated_string = true; if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - return NULL_TREE; - } + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + return NULL_TREE; + } list = chainon (list, build_tree_list (build_tree_list (name, str), - expr.value)); + expr.value)); if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - break; + break; } return list; } @@ -5136,13 +5284,13 @@ { tree str = c_parser_asm_string_literal (parser); if (str) - list = tree_cons (NULL_TREE, str, list); + list = tree_cons (NULL_TREE, str, list); else - return NULL_TREE; + return NULL_TREE; if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - break; + break; } return list; } @@ -5163,26 +5311,26 @@ tree name, label; if (c_parser_next_token_is (parser, CPP_NAME)) - { - c_token *tok = c_parser_peek_token (parser); - name = tok->value; - label = lookup_label_for_goto (tok->location, name); - c_parser_consume_token (parser); - TREE_USED (label) = 1; - } + { + c_token *tok = c_parser_peek_token (parser); + name = tok->value; + label = lookup_label_for_goto (tok->location, name); + c_parser_consume_token (parser); + TREE_USED (label) = 1; + } else - { - c_parser_error (parser, "expected identifier"); - return NULL_TREE; - } + { + c_parser_error (parser, "expected identifier"); + return NULL_TREE; + } name = build_string (IDENTIFIER_LENGTH (name), - IDENTIFIER_POINTER (name)); + IDENTIFIER_POINTER (name)); list = tree_cons (name, label, list); if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - return nreverse (list); + return nreverse (list); } } @@ -5254,8 +5402,8 @@ rhs = c_parser_expr_no_commas (parser, NULL); rhs = default_function_array_read_conversion (exp_location, rhs); ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type, - code, exp_location, rhs.value, - rhs.original_type); + code, exp_location, rhs.value, + rhs.original_type); if (code == NOP_EXPR) ret.original_code = MODIFY_EXPR; else @@ -5299,20 +5447,19 @@ if (c_parser_next_token_is (parser, CPP_COLON)) { tree eptype = NULL_TREE; - middle_loc = c_parser_peek_token (parser)->location; pedwarn (middle_loc, OPT_pedantic, "ISO C forbids omitting the middle term of a ?: expression"); warn_for_omitted_condop (middle_loc, cond.value); if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR) - { - eptype = TREE_TYPE (cond.value); - cond.value = TREE_OPERAND (cond.value, 0); - } + { + eptype = TREE_TYPE (cond.value); + cond.value = TREE_OPERAND (cond.value, 0); + } /* Make sure first operand is calculated only once. */ exp1.value = c_save_expr (default_conversion (cond.value)); if (eptype) - exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value); + exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value); exp1.original_type = NULL; cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value); c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node; @@ -5320,14 +5467,14 @@ else { cond.value - = c_objc_common_truthvalue_conversion - (cond_loc, default_conversion (cond.value)); + = c_objc_common_truthvalue_conversion + (cond_loc, default_conversion (cond.value)); c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node; exp1 = c_parser_expression_conv (parser); mark_exp_read (exp1.value); c_inhibit_evaluation_warnings += - ((cond.value == truthvalue_true_node) - - (cond.value == truthvalue_false_node)); + ((cond.value == truthvalue_true_node) + - (cond.value == truthvalue_false_node)); } colon_loc = c_parser_peek_token (parser)->location; @@ -5346,9 +5493,9 @@ } c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; ret.value = build_conditional_expr (colon_loc, cond.value, - cond.original_code == C_MAYBE_CONST_EXPR, - exp1.value, exp1.original_type, - exp2.value, exp2.original_type); + cond.original_code == C_MAYBE_CONST_EXPR, + exp1.value, exp1.original_type, + exp2.value, exp2.original_type); ret.original_code = ERROR_MARK; if (exp1.value == error_mark_node || exp2.value == error_mark_node) ret.original_type = NULL; @@ -5357,16 +5504,16 @@ tree t1, t2; /* If both sides are enum type, the default conversion will have - made the type of the result be an integer type. We want to - remember the enum types we started with. */ + made the type of the result be an integer type. We want to + remember the enum types we started with. */ t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value); t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value); ret.original_type = ((t1 != error_mark_node - && t2 != error_mark_node - && (TYPE_MAIN_VARIANT (t1) - == TYPE_MAIN_VARIANT (t2))) - ? t1 - : NULL); + && t2 != error_mark_node + && (TYPE_MAIN_VARIANT (t1) + == TYPE_MAIN_VARIANT (t2))) + ? t1 + : NULL); } return ret; } @@ -5516,90 +5663,90 @@ enum prec oprec; enum tree_code ocode; if (parser->error) - goto out; + goto out; switch (c_parser_peek_token (parser)->type) - { - case CPP_MULT: - oprec = PREC_MULT; - ocode = MULT_EXPR; - break; - case CPP_DIV: - oprec = PREC_MULT; - ocode = TRUNC_DIV_EXPR; - break; - case CPP_MOD: - oprec = PREC_MULT; - ocode = TRUNC_MOD_EXPR; - break; - case CPP_PLUS: - oprec = PREC_ADD; - ocode = PLUS_EXPR; - break; - case CPP_MINUS: - oprec = PREC_ADD; - ocode = MINUS_EXPR; - break; - case CPP_LSHIFT: - oprec = PREC_SHIFT; - ocode = LSHIFT_EXPR; - break; - case CPP_RSHIFT: - oprec = PREC_SHIFT; - ocode = RSHIFT_EXPR; - break; - case CPP_LESS: - oprec = PREC_REL; - ocode = LT_EXPR; - break; - case CPP_GREATER: - oprec = PREC_REL; - ocode = GT_EXPR; - break; - case CPP_LESS_EQ: - oprec = PREC_REL; - ocode = LE_EXPR; - break; - case CPP_GREATER_EQ: - oprec = PREC_REL; - ocode = GE_EXPR; - break; - case CPP_EQ_EQ: - oprec = PREC_EQ; - ocode = EQ_EXPR; - break; - case CPP_NOT_EQ: - oprec = PREC_EQ; - ocode = NE_EXPR; - break; - case CPP_AND: - oprec = PREC_BITAND; - ocode = BIT_AND_EXPR; - break; - case CPP_XOR: - oprec = PREC_BITXOR; - ocode = BIT_XOR_EXPR; - break; - case CPP_OR: - oprec = PREC_BITOR; - ocode = BIT_IOR_EXPR; - break; - case CPP_AND_AND: - oprec = PREC_LOGAND; - ocode = TRUTH_ANDIF_EXPR; - break; - case CPP_OR_OR: - oprec = PREC_LOGOR; - ocode = TRUTH_ORIF_EXPR; - break; - default: - /* Not a binary operator, so end of the binary - expression. */ - goto out; - } + { + case CPP_MULT: + oprec = PREC_MULT; + ocode = MULT_EXPR; + break; + case CPP_DIV: + oprec = PREC_MULT; + ocode = TRUNC_DIV_EXPR; + break; + case CPP_MOD: + oprec = PREC_MULT; + ocode = TRUNC_MOD_EXPR; + break; + case CPP_PLUS: + oprec = PREC_ADD; + ocode = PLUS_EXPR; + break; + case CPP_MINUS: + oprec = PREC_ADD; + ocode = MINUS_EXPR; + break; + case CPP_LSHIFT: + oprec = PREC_SHIFT; + ocode = LSHIFT_EXPR; + break; + case CPP_RSHIFT: + oprec = PREC_SHIFT; + ocode = RSHIFT_EXPR; + break; + case CPP_LESS: + oprec = PREC_REL; + ocode = LT_EXPR; + break; + case CPP_GREATER: + oprec = PREC_REL; + ocode = GT_EXPR; + break; + case CPP_LESS_EQ: + oprec = PREC_REL; + ocode = LE_EXPR; + break; + case CPP_GREATER_EQ: + oprec = PREC_REL; + ocode = GE_EXPR; + break; + case CPP_EQ_EQ: + oprec = PREC_EQ; + ocode = EQ_EXPR; + break; + case CPP_NOT_EQ: + oprec = PREC_EQ; + ocode = NE_EXPR; + break; + case CPP_AND: + oprec = PREC_BITAND; + ocode = BIT_AND_EXPR; + break; + case CPP_XOR: + oprec = PREC_BITXOR; + ocode = BIT_XOR_EXPR; + break; + case CPP_OR: + oprec = PREC_BITOR; + ocode = BIT_IOR_EXPR; + break; + case CPP_AND_AND: + oprec = PREC_LOGAND; + ocode = TRUTH_ANDIF_EXPR; + break; + case CPP_OR_OR: + oprec = PREC_LOGOR; + ocode = TRUTH_ORIF_EXPR; + break; + default: + /* Not a binary operator, so end of the binary + expression. */ + goto out; + } binary_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); while (oprec <= stack[sp].prec) - POP; + POP; switch (ocode) { case TRUTH_ANDIF_EXPR: @@ -5653,7 +5800,7 @@ gcc_assert (!after || c_dialect_objc ()); if (after) return c_parser_postfix_expression_after_primary (parser, - cast_loc, *after); + cast_loc, *after); /* If the expression begins with a parenthesized type name, it may be either a cast or a compound literal; we need to see whether the next character is '{' to tell the difference. If not, it is @@ -5669,19 +5816,19 @@ type_name = c_parser_type_name (parser); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (type_name == NULL) - { - ret.value = error_mark_node; - ret.original_code = ERROR_MARK; - ret.original_type = NULL; - return ret; - } + { + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + ret.original_type = NULL; + return ret; + } /* Save casted types in the function's used types hash table. */ used_types_insert (type_name->specs->type); if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) - return c_parser_postfix_expression_after_paren_type (parser, type_name, - cast_loc); + return c_parser_postfix_expression_after_paren_type (parser, type_name, + cast_loc); { location_t expr_loc = c_parser_peek_token (parser)->location; expr = c_parser_cast_expression (parser, NULL); @@ -5760,9 +5907,9 @@ return ret; case CPP_PLUS: if (!c_dialect_objc () && !in_system_header) - warning_at (op_loc, - OPT_Wtraditional, - "traditional C rejects the unary plus operator"); + warning_at (op_loc, + OPT_Wtraditional, + "traditional C rejects the unary plus operator"); c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); @@ -5790,45 +5937,45 @@ /* Refer to the address of a label as a pointer. */ c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_NAME)) - { - ret.value = finish_label_address_expr - (c_parser_peek_token (parser)->value, op_loc); - c_parser_consume_token (parser); - } + { + ret.value = finish_label_address_expr + (c_parser_peek_token (parser)->value, op_loc); + c_parser_consume_token (parser); + } else - { - c_parser_error (parser, "expected identifier"); - ret.value = error_mark_node; - } - return ret; + { + c_parser_error (parser, "expected identifier"); + ret.value = error_mark_node; + } + return ret; case CPP_KEYWORD: switch (c_parser_peek_token (parser)->keyword) - { - case RID_SIZEOF: - return c_parser_sizeof_expression (parser); - case RID_ALIGNOF: - return c_parser_alignof_expression (parser); - case RID_EXTENSION: - c_parser_consume_token (parser); - ext = disable_extension_diagnostics (); - ret = c_parser_cast_expression (parser, NULL); - restore_extension_diagnostics (ext); - return ret; - case RID_REALPART: - c_parser_consume_token (parser); - exp_loc = c_parser_peek_token (parser)->location; - op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, REALPART_EXPR, op); - case RID_IMAGPART: - c_parser_consume_token (parser); - exp_loc = c_parser_peek_token (parser)->location; - op = c_parser_cast_expression (parser, NULL); - op = default_function_array_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, IMAGPART_EXPR, op); - default: - return c_parser_postfix_expression (parser); - } + { + case RID_SIZEOF: + return c_parser_sizeof_expression (parser); + case RID_ALIGNOF: + return c_parser_alignof_expression (parser); + case RID_EXTENSION: + c_parser_consume_token (parser); + ext = disable_extension_diagnostics (); + ret = c_parser_cast_expression (parser, NULL); + restore_extension_diagnostics (ext); + return ret; + case RID_REALPART: + c_parser_consume_token (parser); + exp_loc = c_parser_peek_token (parser)->location; + op = c_parser_cast_expression (parser, NULL); + op = default_function_array_conversion (exp_loc, op); + return parser_build_unary_op (op_loc, REALPART_EXPR, op); + case RID_IMAGPART: + c_parser_consume_token (parser); + exp_loc = c_parser_peek_token (parser)->location; + op = c_parser_cast_expression (parser, NULL); + op = default_function_array_conversion (exp_loc, op); + return parser_build_unary_op (op_loc, IMAGPART_EXPR, op); + default: + return c_parser_postfix_expression (parser); + } default: return c_parser_postfix_expression (parser); } @@ -5849,29 +5996,29 @@ && c_token_starts_typename (c_parser_peek_2nd_token (parser))) { /* Either sizeof ( type-name ) or sizeof unary-expression - starting with a compound literal. */ + starting with a compound literal. */ struct c_type_name *type_name; c_parser_consume_token (parser); expr_loc = c_parser_peek_token (parser)->location; type_name = c_parser_type_name (parser); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (type_name == NULL) - { - struct c_expr ret; - c_inhibit_evaluation_warnings--; - in_sizeof--; - ret.value = error_mark_node; - ret.original_code = ERROR_MARK; - ret.original_type = NULL; - return ret; - } + { + struct c_expr ret; + c_inhibit_evaluation_warnings--; + in_sizeof--; + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + ret.original_type = NULL; + return ret; + } if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) - { - expr = c_parser_postfix_expression_after_paren_type (parser, - type_name, - expr_loc); - goto sizeof_expr; - } + { + expr = c_parser_postfix_expression_after_paren_type (parser, + type_name, + expr_loc); + goto sizeof_expr; + } /* sizeof ( type-name ). */ c_inhibit_evaluation_warnings--; in_sizeof--; @@ -5886,8 +6033,8 @@ in_sizeof--; mark_exp_read (expr.value); if (TREE_CODE (expr.value) == COMPONENT_REF - && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) - error_at (expr_loc, "% applied to a bit-field"); + && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) + error_at (expr_loc, "% applied to a bit-field"); return c_expr_sizeof_expr (expr_loc, expr); } } @@ -5907,7 +6054,7 @@ && c_token_starts_typename (c_parser_peek_2nd_token (parser))) { /* Either __alignof__ ( type-name ) or __alignof__ - unary-expression starting with a compound literal. */ + unary-expression starting with a compound literal. */ location_t loc; struct c_type_name *type_name; struct c_expr ret; @@ -5916,22 +6063,22 @@ type_name = c_parser_type_name (parser); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (type_name == NULL) - { - struct c_expr ret; - c_inhibit_evaluation_warnings--; - in_alignof--; - ret.value = error_mark_node; - ret.original_code = ERROR_MARK; - ret.original_type = NULL; - return ret; - } + { + struct c_expr ret; + c_inhibit_evaluation_warnings--; + in_alignof--; + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + ret.original_type = NULL; + return ret; + } if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) - { - expr = c_parser_postfix_expression_after_paren_type (parser, - type_name, - loc); - goto alignof_expr; - } + { + expr = c_parser_postfix_expression_after_paren_type (parser, + type_name, + loc); + goto alignof_expr; + } /* alignof ( type-name ). */ c_inhibit_evaluation_warnings--; in_alignof--; @@ -5989,8 +6136,8 @@ __builtin_va_arg ( assignment-expression , type-name ) __builtin_offsetof ( type-name , offsetof-member-designator ) __builtin_choose_expr ( assignment-expression , - assignment-expression , - assignment-expression ) + assignment-expression , + assignment-expression ) __builtin_types_compatible_p ( type-name , type-name ) offsetof-member-designator: @@ -6009,11 +6156,127 @@ Classname . identifier */ +static void +cbc_finish_labeled_goto (location_t loc, tree label, tree retval) +{ + /* add statement below. + * + * if (0) { + * _cbc_exit0: + * return retval; + * } + */ + tree tlab; + tree cond; + + tree cstmt = c_begin_compound_stmt (true); + + tlab = define_label (loc, label); + gcc_assert (tlab); + decl_attributes (&tlab, NULL_TREE, 0); + add_stmt (build_stmt (loc, LABEL_EXPR, tlab)); + + tree ret = c_finish_return (loc, retval, retval); /*tree ret = c_finish_return (retval);*/ + TREE_USED(ret) = 1; + + cond = integer_zero_node; + tree if_body = c_end_compound_stmt (loc, cstmt, true); + TREE_SIDE_EFFECTS (cstmt) = 1; + c_finish_if_stmt (loc, cond, if_body, NULL_TREE, false); +} + +static tree +cbc_finish_nested_function (location_t loc, tree label, tree retval_decl) +{ + + /* add statement below. + * void __return_func(int _retval, void *_envp){ + * retval = _retval; + * goto exit0; + * } + */ + /* TODO: + * retval(lhs)のTREE_DECLを引数から取得するように + * int _retvalパラメータのタイプはretvalに合わせる + */ + + tree fnbody; + tree _retval_decl, _envp_decl; + struct c_declarator *declarator; + //tree ident; + struct c_arg_info *args; + struct c_declspecs *specs; + struct c_typespec t; + { + push_scope (); + declare_parm_level (); + /*tree retval_type = TREE_TYPE(retval_decl);*/ + + _retval_decl = build_decl (loc, PARM_DECL, get_identifier ("_retval"), TREE_TYPE(retval_decl)); + DECL_SOURCE_LOCATION (_retval_decl) = loc; + DECL_ARTIFICIAL (_retval_decl) = 1; + DECL_ARG_TYPE (_retval_decl) = TREE_TYPE(retval_decl); + pushdecl (_retval_decl); + finish_decl (_retval_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); + + _envp_decl = build_decl (loc, PARM_DECL, get_identifier ("_envp"), ptr_type_node); + DECL_SOURCE_LOCATION (_envp_decl) = loc; + DECL_ARTIFICIAL (_envp_decl) = 1; + DECL_ARG_TYPE (_envp_decl) = ptr_type_node; + pushdecl (_envp_decl); + finish_decl (_envp_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); + + args = get_parm_info(false); + pop_scope(); + } + + t.kind = ctsk_resword; + t.spec = get_identifier("void"); + specs = build_null_declspecs(); + declspecs_add_type (loc, specs, t); + finish_declspecs (specs); + + /* make nested function. */ + declarator = build_id_declarator (get_identifier ("_cbc_internal_return")); + declarator = build_function_declarator (args, declarator); + + c_push_function_context (); + + if (!start_function (specs, declarator, NULL_TREE)) + { + c_pop_function_context(); + gcc_assert (0); + } + store_parm_decls (); + + + /* start compound statement. */ + tree cstmt = c_begin_compound_stmt (true); + + add_stmt (build_modify_expr (loc, retval_decl, NULL_TREE, NOP_EXPR, loc, _retval_decl, NULL_TREE)); + //tree stmt = c_finish_goto_label (loc, label); + + /* end compound statement. */ + fnbody = c_end_compound_stmt (loc, cstmt, true); + TREE_SIDE_EFFECTS (cstmt) = 1; + + /* finish declaration of nested function. */ + tree decl = current_function_decl; + add_stmt (fnbody); + finish_function (); + c_pop_function_context (); + + add_stmt (build_stmt (loc, DECL_EXPR, decl)); + return decl; + +} + static struct c_expr c_parser_postfix_expression (c_parser *parser) { struct c_expr expr, e1, e2, e3; struct c_type_name *t1, *t2; + //cbc? static tree return_label1; location_t loc = c_parser_peek_token (parser)->location;; expr.original_code = ERROR_MARK; expr.original_type = NULL; @@ -6024,11 +6287,11 @@ loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); if (TREE_CODE (expr.value) == FIXED_CST - && !targetm.fixed_point_supported_p ()) - { - error_at (loc, "fixed-point types not supported for this target"); - expr.value = error_mark_node; - } + && !targetm.fixed_point_supported_p ()) + { + error_at (loc, "fixed-point types not supported for this target"); + expr.value = error_mark_node; + } break; case CPP_CHAR: case CPP_CHAR16: @@ -6049,7 +6312,7 @@ case CPP_OBJC_STRING: gcc_assert (c_dialect_objc ()); expr.value - = objc_build_string_object (c_parser_peek_token (parser)->value); + = objc_build_string_object (c_parser_peek_token (parser)->value); c_parser_consume_token (parser); break; case CPP_NAME: @@ -6098,7 +6361,7 @@ break; case CPP_OPEN_PAREN: /* A parenthesized expression, statement expression or compound - literal. */ + literal. */ if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE) { /* A statement expression. */ @@ -6127,40 +6390,40 @@ mark_exp_read (expr.value); } else if (c_token_starts_typename (c_parser_peek_2nd_token (parser))) - { - /* A compound literal. ??? Can we actually get here rather - than going directly to - c_parser_postfix_expression_after_paren_type from - elsewhere? */ - location_t loc; - struct c_type_name *type_name; - c_parser_consume_token (parser); - loc = c_parser_peek_token (parser)->location; - type_name = c_parser_type_name (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - if (type_name == NULL) - { - expr.value = error_mark_node; - } - else - expr = c_parser_postfix_expression_after_paren_type (parser, - type_name, - loc); - } + { + /* A compound literal. ??? Can we actually get here rather + than going directly to + c_parser_postfix_expression_after_paren_type from + elsewhere? */ + location_t loc; + struct c_type_name *type_name; + c_parser_consume_token (parser); + loc = c_parser_peek_token (parser)->location; + type_name = c_parser_type_name (parser); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + if (type_name == NULL) + { + expr.value = error_mark_node; + } else - { - /* A parenthesized expression. */ - c_parser_consume_token (parser); - expr = c_parser_expression (parser); - if (TREE_CODE (expr.value) == MODIFY_EXPR) - TREE_NO_WARNING (expr.value) = 1; - if (expr.original_code != C_MAYBE_CONST_EXPR) - expr.original_code = ERROR_MARK; - /* Don't change EXPR.ORIGINAL_TYPE. */ - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - } + expr = c_parser_postfix_expression_after_paren_type (parser, + type_name, + loc); + } + else + { + /* A parenthesized expression. */ + c_parser_consume_token (parser); + expr = c_parser_expression (parser); + if (TREE_CODE (expr.value) == MODIFY_EXPR) + TREE_NO_WARNING (expr.value) = 1; + if (expr.original_code != C_MAYBE_CONST_EXPR) + expr.original_code = ERROR_MARK; + /* Don't change EXPR.ORIGINAL_TYPE. */ + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + } break; case CPP_KEYWORD: switch (c_parser_peek_token (parser)->keyword) @@ -6324,7 +6587,6 @@ "expected %<)%>"); { tree c; - c = e1.value; mark_exp_read (e2.value); mark_exp_read (e3.value); @@ -6366,10 +6628,8 @@ "expected %<)%>"); { tree e1, e2; - e1 = TYPE_MAIN_VARIANT (groktypename (t1, NULL, NULL)); e2 = TYPE_MAIN_VARIANT (groktypename (t2, NULL, NULL)); - expr.value = comptypes (e1, e2) ? integer_one_node : integer_zero_node; } @@ -6435,6 +6695,190 @@ expr.value = objc_build_encode_expr (type); } break; + +#ifndef noCbC + case RID_CbC_ENV: + { + c_parser_consume_token (parser); + /* get value of %ebp. */ + /*tree env_tree = build_external_ref ( + get_identifier ("__builtin_frame_address"), 0, + c_parser_peek_token (parser)->location);*/ + loc = c_parser_peek_token (parser)->location; + tree env_tree = build_external_ref (loc, + get_identifier ("__builtin_frame_address"), 0, &expr.original_type); + expr.value = build_function_call(loc, env_tree, + build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,0))); + expr.original_code = ERROR_MARK; + } + break; + case RID_CbC_RET: + case RID_RETURN: + +#if 0 + if (cbc_return_f==0) + { tree retval; + + /* + Generates something like... + + int retval = 1; + void (*ret)(int retval_,void *fp) ; + + ret = ({ + __label__ exit0; + volatile static flag = 0; + void __return_func(int retval_,void *fp) { + retval = retval_; + goto exit0; + } + if (flag) { + exit0: + printf("f1: fp = 0x%x\n",__builtin_frame_address(0)); + return retval; + } + __return_func; + }); + + */ + + tree stmt = c_begin_stmt_expr (); + cbc_return_f = c_parser_peek_token (parser)->value; + cbc_return = c_parser_peek_token (parser)->location; + c_parser_consume_token (parser); + location_t next = c_parser_peek_token (parser)->location; + + // dummy variable for hidden condition + struct c_expr cexpr; + tree cond; + location_t loc; + loc = next; + tree decl_cond = + build_decl (VAR_DECL, get_identifier ("__return"), + intHI_type_node); + TREE_STATIC (decl_cond) = 1; + cexpr.value = lang_hooks.decls.pushdecl(decl_cond); + + cexpr.original_code = ERROR_MARK; + cond = c_objc_common_truthvalue_conversion(loc, cexpr.value); + if (EXPR_P (cond)) + SET_EXPR_LOCATION (cond, loc); + + + + + tree fwlabel = create_artificial_label (); + //TREE_USED(fwlabel) = 1; + + //add_stmt (build1 (GOTO_EXPR, void_type_node, fwlabel)); + tree block = c_begin_compound_stmt (flag_isoc99); + + tree tlab = lookup_label(cbc_return_f); + + tree decl= build_stmt (LABEL_EXPR, tlab); + //TREE_USED(decl) = 1; + add_stmt(decl); + + //tree hoge = build_int_cst(NULL_TREE,55); + retval = build_component_ref (cbc_env, get_identifier("retval")); + tree ret = c_finish_return (retval); + TREE_USED(ret) = 1; + tree first_body = c_end_compound_stmt (block, flag_isoc99); + + c_finish_if_stmt (loc, cond, first_body, NULL_TREE, false); + + // define_label(EXPR_LOCATION(decl) ,cbc_return_f); + return_label1 = + define_label(cbc_return ,cbc_return_f); + tree fwdef= build_stmt (LABEL_EXPR, fwlabel); + + //TREE_USED(fwdef) = 1; + add_stmt(fwdef); + TREE_SIDE_EFFECTS (block) = 1; + + // tree label = lookup_label(c_parser_peek_token (parser)->value); + //TREE_USED(label) = 1; + + tree value = build1(ADDR_EXPR, ptr_type_node, return_label1); + SET_EXPR_LOCATION (value, next); + TREE_SIDE_EFFECTS (value) = 1; + add_stmt(value); + + TREE_SIDE_EFFECTS (stmt) = 1; + expr.value = c_finish_stmt_expr (stmt); + expr.original_code = ERROR_MARK; + + + } + else + { + //tree label = lookup_label(c_parser_peek_token (parser)->value); + //TREE_USED(label) = 1; + //expr.value = build1(ADDR_EXPR, ptr_type_node, label); + expr.value = build1(ADDR_EXPR, ptr_type_node, return_label1); + c_parser_consume_token (parser); + } +#else //by KENT. + { + /* + ({ + __label__ _cbc_exit0; + void __return_func(int retval_, void *_envp){ + retval = retval_; + goto exit0; + } + if (0) { + _cbc_exit0: + return retval; + } + __return_func; + }); + */ + tree value, stmt, label, tlab, decl; + c_parser_consume_token (parser); + + stmt = c_begin_stmt_expr (); + cbc_return_f = c_parser_peek_token (parser)->value; + location_t location = c_parser_peek_token (parser)->location; + + /* create label. (__label__ _cbc_exit0;) */ + label = get_identifier ("_cbc_exit0"); + tlab = declare_label (label); + C_DECLARED_LABEL_FLAG (tlab) = 1; + add_stmt (build_stmt (location, DECL_EXPR, tlab)); + + /* declare retval. (int retval;) */ + tree decl_cond = + build_decl (location, VAR_DECL, get_identifier ("retval"), + TREE_TYPE (TREE_TYPE (current_function_decl))); + TREE_STATIC (decl_cond) = 1; + DECL_ARTIFICIAL (decl_cond) = 1; + pushdecl (decl_cond); + + /* define nested function. */ + decl = + cbc_finish_nested_function (location, label, decl_cond); + + /* define if-ed goto label and return statement. */ + cbc_finish_labeled_goto (location, label, decl_cond); + + /* get pointer to nested function. */ + value = build_addr (decl , current_function_decl); + SET_EXPR_LOCATION (value, location); + add_stmt (value); + /*value = build_external_ref (get_identifier("_cbc_internal_return"), false, location);*/ + /*value = build_unary_op (location, ADDR_EXPR, value, 0);*/ + /*add_stmt (value);*/ + + TREE_SIDE_EFFECTS (stmt) = 1; + expr.value = c_finish_stmt_expr (location, stmt); + expr.original_code = ERROR_MARK; + } + +#endif //0 + break; +#endif //noCbC + default: c_parser_error (parser, "expected expression"); expr.value = error_mark_node; @@ -6443,17 +6887,17 @@ break; case CPP_OPEN_SQUARE: if (c_dialect_objc ()) - { - tree receiver, args; - c_parser_consume_token (parser); - receiver = c_parser_objc_receiver (parser); - args = c_parser_objc_message_args (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, - "expected %<]%>"); - expr.value = objc_build_message_expr (build_tree_list (receiver, - args)); - break; - } + { + tree receiver, args; + c_parser_consume_token (parser); + receiver = c_parser_objc_receiver (parser); + args = c_parser_objc_message_args (parser); + c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, + "expected %<]%>"); + expr.value = objc_build_message_expr (build_tree_list (receiver, + args)); + break; + } /* Else fall through to report error. */ default: c_parser_error (parser, "expected expression"); @@ -6475,8 +6919,8 @@ static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *parser, - struct c_type_name *type_name, - location_t type_loc) + struct c_type_name *type_name, + location_t type_loc) { tree type; struct c_expr init; @@ -6509,8 +6953,8 @@ if (!flag_isoc99) pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals"); non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR) - ? CONSTRUCTOR_NON_CONST (init.value) - : init.original_code == C_MAYBE_CONST_EXPR); + ? CONSTRUCTOR_NON_CONST (init.value) + : init.original_code == C_MAYBE_CONST_EXPR); non_const |= !type_expr_const; expr.value = build_compound_literal (start_loc, type, init.value, non_const); expr.original_code = ERROR_MARK; @@ -6518,16 +6962,16 @@ if (type_expr) { if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR) - { - gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE); - C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr; - } + { + gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE); + C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr; + } else - { - gcc_assert (!non_const); - expr.value = build2 (C_MAYBE_CONST_EXPR, type, - type_expr, expr.value); - } + { + gcc_assert (!non_const); + expr.value = build2 (C_MAYBE_CONST_EXPR, type, + type_expr, expr.value); + } } return c_parser_postfix_expression_after_primary (parser, start_loc, expr); } @@ -6539,8 +6983,8 @@ static struct c_expr c_parser_postfix_expression_after_primary (c_parser *parser, - location_t expr_loc, - struct c_expr expr) + location_t expr_loc, + struct c_expr expr) { struct c_expr orig_expr; tree ident, idx; @@ -6732,7 +7176,7 @@ static VEC(tree,gc) * c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, - VEC(tree,gc) **p_orig_types) + VEC(tree,gc) **p_orig_types) { VEC(tree,gc) *ret; VEC(tree,gc) *orig_types; @@ -6761,10 +7205,10 @@ if (convert_p) expr = default_function_array_read_conversion (loc, expr); if (fold_p) - expr.value = c_fully_fold (expr.value, false, NULL); + expr.value = c_fully_fold (expr.value, false, NULL); VEC_safe_push (tree, gc, ret, expr.value); if (orig_types != NULL) - VEC_safe_push (tree, gc, orig_types, expr.original_type); + VEC_safe_push (tree, gc, orig_types, expr.original_type); } if (orig_types != NULL) *p_orig_types = orig_types; @@ -6843,10 +7287,10 @@ } c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (!iface_p) - { - objc_start_category_implementation (id1, id2); - return; - } + { + objc_start_category_implementation (id1, id2); + return; + } if (c_parser_next_token_is (parser, CPP_LESS)) proto = c_parser_objc_protocol_refs (parser); objc_start_category_interface (id1, id2, proto, attributes); @@ -6859,10 +7303,10 @@ { c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_NAME)) - { - c_parser_error (parser, "expected identifier"); - return; - } + { + c_parser_error (parser, "expected identifier"); + return; + } superclass = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); } @@ -6925,18 +7369,18 @@ tree decls; /* Parse any stray semicolon. */ if (c_parser_next_token_is (parser, CPP_SEMICOLON)) - { - pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, - "extra semicolon in struct or union specified"); - c_parser_consume_token (parser); - continue; - } + { + pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, + "extra semicolon in struct or union specified"); + c_parser_consume_token (parser); + continue; + } /* Stop if at the end of the instance variables. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) - { - c_parser_consume_token (parser); - break; - } + { + c_parser_consume_token (parser); + break; + } /* Parse any objc-visibility-spec. */ if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE)) { @@ -6963,11 +7407,10 @@ continue; } else if (c_parser_next_token_is (parser, CPP_PRAGMA)) - { - c_parser_pragma (parser, pragma_external); - continue; - } - + { + c_parser_pragma (parser, pragma_external); + continue; + } /* Parse some comma-separated declarations. */ decls = c_parser_struct_declaration (parser); { @@ -7009,9 +7452,9 @@ list = chainon (list, build_tree_list (NULL_TREE, id)); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - break; + break; } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); objc_declare_class (list); @@ -7076,23 +7519,23 @@ { tree list = NULL_TREE; /* Any identifiers, including those declared as type names, are - OK here. */ + OK here. */ while (true) - { - tree id; - if (c_parser_next_token_is_not (parser, CPP_NAME)) - { - c_parser_error (parser, "expected identifier"); - break; - } - id = c_parser_peek_token (parser)->value; - list = chainon (list, build_tree_list (NULL_TREE, id)); - c_parser_consume_token (parser); - if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); - else - break; - } + { + tree id; + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + c_parser_error (parser, "expected identifier"); + break; + } + id = c_parser_peek_token (parser)->value; + list = chainon (list, build_tree_list (NULL_TREE, id)); + c_parser_consume_token (parser); + if (c_parser_next_token_is (parser, CPP_COMMA)) + c_parser_consume_token (parser); + else + break; + } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); objc_declare_protocols (list, attributes); } @@ -7102,7 +7545,7 @@ tree proto = NULL_TREE; c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_LESS)) - proto = c_parser_objc_protocol_refs (parser); + proto = c_parser_objc_protocol_refs (parser); parser->objc_pq_context = true; objc_start_protocol (id, proto, attributes); c_parser_objc_methodprotolist (parser); @@ -7157,7 +7600,7 @@ { c_parser_consume_token (parser); pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic, - "extra semicolon in method definition specified"); + "extra semicolon in method definition specified"); } if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) @@ -7400,8 +7843,8 @@ attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ; /* Parse the optional parameter list. Optional Objective-C - method parameters follow the C syntax, and may include '...' - to denote a variable number of arguments. */ + method parameters follow the C syntax, and may include '...' + to denote a variable number of arguments. */ parms = make_node (TREE_LIST); while (c_parser_next_token_is (parser, CPP_COMMA)) { @@ -7473,7 +7916,7 @@ c_parser_consume_token (parser); } else - break; + break; } if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) type_name = c_parser_type_name (parser); @@ -7508,17 +7951,17 @@ { tree id; if (c_parser_next_token_is_not (parser, CPP_NAME)) - { - c_parser_error (parser, "expected identifier"); - break; - } + { + c_parser_error (parser, "expected identifier"); + break; + } id = c_parser_peek_token (parser)->value; list = chainon (list, build_tree_list (NULL_TREE, id)); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - break; + break; } c_parser_require (parser, CPP_GREATER, "expected %<>%>"); return list; @@ -7607,7 +8050,7 @@ } objc_begin_catch_clause (parameter_declaration); if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) - c_parser_compound_statement_nostart (parser); + c_parser_compound_statement_nostart (parser); objc_finish_catch_clause (); } if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY)) @@ -7747,11 +8190,11 @@ while (true) { if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) - return list; + return list; list = chainon (list, build_tree_list (sel, NULL_TREE)); sel = c_parser_objc_selector (parser); if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) - break; + break; } return list; } @@ -7769,7 +8212,7 @@ { if (c_parser_peek_token (parser)->type == CPP_NAME && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME - || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) + || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) { tree id = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); @@ -7804,12 +8247,12 @@ { tree keywordexpr; if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) - return error_mark_node; + return error_mark_node; keywordexpr = c_parser_objc_keywordexpr (parser); list = chainon (list, build_tree_list (sel, keywordexpr)); sel = c_parser_objc_selector (parser); if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) - break; + break; } return list; } @@ -7828,7 +8271,7 @@ if (VEC_length (tree, expr_list) == 1) { /* Just return the expression, remove a level of - indirection. */ + indirection. */ ret = VEC_index (tree, expr_list, 0); } else @@ -8174,34 +8617,34 @@ { case PRAGMA_OMP_BARRIER: if (context != pragma_compound) - { - if (context == pragma_stmt) - c_parser_error (parser, "%<#pragma omp barrier%> may only be " - "used in compound statements"); - goto bad_stmt; - } + { + if (context == pragma_stmt) + c_parser_error (parser, "%<#pragma omp barrier%> may only be " + "used in compound statements"); + goto bad_stmt; + } c_parser_omp_barrier (parser); return false; case PRAGMA_OMP_FLUSH: if (context != pragma_compound) - { - if (context == pragma_stmt) - c_parser_error (parser, "%<#pragma omp flush%> may only be " - "used in compound statements"); - goto bad_stmt; - } + { + if (context == pragma_stmt) + c_parser_error (parser, "%<#pragma omp flush%> may only be " + "used in compound statements"); + goto bad_stmt; + } c_parser_omp_flush (parser); return false; case PRAGMA_OMP_TASKWAIT: if (context != pragma_compound) - { - if (context == pragma_stmt) - c_parser_error (parser, "%<#pragma omp taskwait%> may only be " - "used in compound statements"); - goto bad_stmt; - } + { + if (context == pragma_stmt) + c_parser_error (parser, "%<#pragma omp taskwait%> may only be " + "used in compound statements"); + goto bad_stmt; + } c_parser_omp_taskwait (parser); return false; @@ -8211,8 +8654,8 @@ case PRAGMA_OMP_SECTION: error_at (c_parser_peek_token (parser)->location, - "%<#pragma omp section%> may only be used in " - "%<#pragma omp sections%> construct"); + "%<#pragma omp section%> may only be used in " + "%<#pragma omp sections%> construct"); c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); return false; @@ -8223,17 +8666,17 @@ default: if (id < PRAGMA_FIRST_EXTERNAL) - { - if (context == pragma_external) - { - bad_stmt: - c_parser_error (parser, "expected declaration specifiers"); - c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); - return false; - } - c_parser_omp_construct (parser); - return true; - } + { + if (context == pragma_external) + { + bad_stmt: + c_parser_error (parser, "expected declaration specifiers"); + c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); + return false; + } + c_parser_omp_construct (parser); + return true; + } break; } @@ -8263,7 +8706,7 @@ else { if (ret == CPP_KEYWORD) - ret = CPP_NAME; + ret = CPP_NAME; c_parser_consume_token (the_parser); } @@ -8310,52 +8753,52 @@ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); switch (p[0]) - { - case 'c': - if (!strcmp ("collapse", p)) - result = PRAGMA_OMP_CLAUSE_COLLAPSE; - else if (!strcmp ("copyin", p)) - result = PRAGMA_OMP_CLAUSE_COPYIN; + { + case 'c': + if (!strcmp ("collapse", p)) + result = PRAGMA_OMP_CLAUSE_COLLAPSE; + else if (!strcmp ("copyin", p)) + result = PRAGMA_OMP_CLAUSE_COPYIN; else if (!strcmp ("copyprivate", p)) - result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; - break; - case 'f': - if (!strcmp ("firstprivate", p)) - result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; - break; - case 'l': - if (!strcmp ("lastprivate", p)) - result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; - break; - case 'n': - if (!strcmp ("nowait", p)) - result = PRAGMA_OMP_CLAUSE_NOWAIT; - else if (!strcmp ("num_threads", p)) - result = PRAGMA_OMP_CLAUSE_NUM_THREADS; - break; - case 'o': - if (!strcmp ("ordered", p)) - result = PRAGMA_OMP_CLAUSE_ORDERED; - break; - case 'p': - if (!strcmp ("private", p)) - result = PRAGMA_OMP_CLAUSE_PRIVATE; - break; - case 'r': - if (!strcmp ("reduction", p)) - result = PRAGMA_OMP_CLAUSE_REDUCTION; - break; - case 's': - if (!strcmp ("schedule", p)) - result = PRAGMA_OMP_CLAUSE_SCHEDULE; - else if (!strcmp ("shared", p)) - result = PRAGMA_OMP_CLAUSE_SHARED; - break; - case 'u': - if (!strcmp ("untied", p)) - result = PRAGMA_OMP_CLAUSE_UNTIED; - break; - } + result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; + break; + case 'f': + if (!strcmp ("firstprivate", p)) + result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; + break; + case 'l': + if (!strcmp ("lastprivate", p)) + result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; + break; + case 'n': + if (!strcmp ("nowait", p)) + result = PRAGMA_OMP_CLAUSE_NOWAIT; + else if (!strcmp ("num_threads", p)) + result = PRAGMA_OMP_CLAUSE_NUM_THREADS; + break; + case 'o': + if (!strcmp ("ordered", p)) + result = PRAGMA_OMP_CLAUSE_ORDERED; + break; + case 'p': + if (!strcmp ("private", p)) + result = PRAGMA_OMP_CLAUSE_PRIVATE; + break; + case 'r': + if (!strcmp ("reduction", p)) + result = PRAGMA_OMP_CLAUSE_REDUCTION; + break; + case 's': + if (!strcmp ("schedule", p)) + result = PRAGMA_OMP_CLAUSE_SCHEDULE; + else if (!strcmp ("shared", p)) + result = PRAGMA_OMP_CLAUSE_SHARED; + break; + case 'u': + if (!strcmp ("untied", p)) + result = PRAGMA_OMP_CLAUSE_UNTIED; + break; + } } if (result != PRAGMA_OMP_CLAUSE_NONE) @@ -8368,16 +8811,16 @@ static void check_no_duplicate_clause (tree clauses, enum omp_clause_code code, - const char *name) + const char *name) { tree c; for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == code) { - location_t loc = OMP_CLAUSE_LOCATION (c); - error_at (loc, "too many %qs clauses", name); - break; + location_t loc = OMP_CLAUSE_LOCATION (c); + error_at (loc, "too many %qs clauses", name); + break; } } @@ -8395,8 +8838,8 @@ static tree c_parser_omp_variable_list (c_parser *parser, - location_t clause_loc, - enum omp_clause_code kind, + location_t clause_loc, + enum omp_clause_code kind, tree list) { if (c_parser_next_token_is_not (parser, CPP_NAME) @@ -8404,29 +8847,29 @@ c_parser_error (parser, "expected identifier"); while (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_token (parser)->id_kind == C_ID_ID) + && c_parser_peek_token (parser)->id_kind == C_ID_ID) { tree t = lookup_name (c_parser_peek_token (parser)->value); if (t == NULL_TREE) - undeclared_variable (c_parser_peek_token (parser)->location, - c_parser_peek_token (parser)->value); + undeclared_variable (c_parser_peek_token (parser)->location, + c_parser_peek_token (parser)->value); else if (t == error_mark_node) - ; + ; else if (kind != 0) - { - tree u = build_omp_clause (clause_loc, kind); - OMP_CLAUSE_DECL (u) = t; - OMP_CLAUSE_CHAIN (u) = list; - list = u; - } + { + tree u = build_omp_clause (clause_loc, kind); + OMP_CLAUSE_DECL (u) = t; + OMP_CLAUSE_CHAIN (u) = list; + list = u; + } else - list = tree_cons (t, NULL_TREE, list); + list = tree_cons (t, NULL_TREE, list); c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_COMMA)) - break; + break; c_parser_consume_token (parser); } @@ -8439,7 +8882,7 @@ static tree c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, - tree list) + tree list) { /* The clauses location. */ location_t loc = c_parser_peek_token (parser)->location; @@ -8478,7 +8921,7 @@ || (int) n != n) { error_at (loc, - "collapse argument needs positive constant integer expression"); + "collapse argument needs positive constant integer expression"); return list; } c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE); @@ -8522,22 +8965,22 @@ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); switch (p[0]) - { - case 'n': - if (strcmp ("none", p) != 0) - goto invalid_kind; - kind = OMP_CLAUSE_DEFAULT_NONE; - break; - - case 's': - if (strcmp ("shared", p) != 0) - goto invalid_kind; - kind = OMP_CLAUSE_DEFAULT_SHARED; - break; - - default: - goto invalid_kind; - } + { + case 'n': + if (strcmp ("none", p) != 0) + goto invalid_kind; + kind = OMP_CLAUSE_DEFAULT_NONE; + break; + + case 's': + if (strcmp ("shared", p) != 0) + goto invalid_kind; + kind = OMP_CLAUSE_DEFAULT_SHARED; + break; + + default: + goto invalid_kind; + } c_parser_consume_token (parser); } @@ -8634,22 +9077,22 @@ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - c_parser_error (parser, "expected integer expression"); - return list; - } + { + c_parser_error (parser, "expected integer expression"); + return list; + } /* Attempt to statically determine when the number isn't positive. */ c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, - build_int_cst (TREE_TYPE (t), 0)); + build_int_cst (TREE_TYPE (t), 0)); if (CAN_HAVE_LOCATION_P (c)) - SET_EXPR_LOCATION (c, expr_loc); + SET_EXPR_LOCATION (c, expr_loc); if (c == boolean_true_node) - { - warning_at (expr_loc, 0, - "% value must be positive"); - t = integer_one_node; - } + { + warning_at (expr_loc, 0, + "% value must be positive"); + t = integer_one_node; + } check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads"); @@ -8673,7 +9116,7 @@ check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered"); c = build_omp_clause (c_parser_peek_token (parser)->location, - OMP_CLAUSE_ORDERED); + OMP_CLAUSE_ORDERED); OMP_CLAUSE_CHAIN (c) = list; return c; @@ -8703,50 +9146,50 @@ enum tree_code code; switch (c_parser_peek_token (parser)->type) - { - case CPP_PLUS: - code = PLUS_EXPR; - break; - case CPP_MULT: - code = MULT_EXPR; - break; - case CPP_MINUS: - code = MINUS_EXPR; - break; - case CPP_AND: - code = BIT_AND_EXPR; - break; - case CPP_XOR: - code = BIT_XOR_EXPR; - break; - case CPP_OR: - code = BIT_IOR_EXPR; - break; - case CPP_AND_AND: - code = TRUTH_ANDIF_EXPR; - break; - case CPP_OR_OR: - code = TRUTH_ORIF_EXPR; - break; - default: - c_parser_error (parser, - "expected %<+%>, %<*%>, %<-%>, %<&%>, " - "%<^%>, %<|%>, %<&&%>, or %<||%>"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); - return list; - } + { + case CPP_PLUS: + code = PLUS_EXPR; + break; + case CPP_MULT: + code = MULT_EXPR; + break; + case CPP_MINUS: + code = MINUS_EXPR; + break; + case CPP_AND: + code = BIT_AND_EXPR; + break; + case CPP_XOR: + code = BIT_XOR_EXPR; + break; + case CPP_OR: + code = BIT_IOR_EXPR; + break; + case CPP_AND_AND: + code = TRUTH_ANDIF_EXPR; + break; + case CPP_OR_OR: + code = TRUTH_ORIF_EXPR; + break; + default: + c_parser_error (parser, + "expected %<+%>, %<*%>, %<-%>, %<&%>, " + "%<^%>, %<|%>, %<&&%>, or %<||%>"); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); + return list; + } c_parser_consume_token (parser); if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) - { - tree nl, c; - - nl = c_parser_omp_variable_list (parser, clause_loc, - OMP_CLAUSE_REDUCTION, list); - for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) - OMP_CLAUSE_REDUCTION_CODE (c) = code; - - list = nl; - } + { + tree nl, c; + + nl = c_parser_omp_variable_list (parser, clause_loc, + OMP_CLAUSE_REDUCTION, list); + for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_REDUCTION_CODE (c) = code; + + list = nl; + } c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } return list; @@ -8777,28 +9220,28 @@ const char *p = IDENTIFIER_POINTER (kind); switch (p[0]) - { - case 'd': - if (strcmp ("dynamic", p) != 0) - goto invalid_kind; - OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC; - break; + { + case 'd': + if (strcmp ("dynamic", p) != 0) + goto invalid_kind; + OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC; + break; case 'g': - if (strcmp ("guided", p) != 0) - goto invalid_kind; - OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED; - break; - - case 'r': - if (strcmp ("runtime", p) != 0) - goto invalid_kind; - OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME; - break; - - default: - goto invalid_kind; - } + if (strcmp ("guided", p) != 0) + goto invalid_kind; + OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED; + break; + + case 'r': + if (strcmp ("runtime", p) != 0) + goto invalid_kind; + OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME; + break; + + default: + goto invalid_kind; + } } else if (c_parser_next_token_is_keyword (parser, RID_STATIC)) OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC; @@ -8818,22 +9261,22 @@ t = c_fully_fold (t, false, NULL); if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) - error_at (here, "schedule % does not take " - "a % parameter"); + error_at (here, "schedule % does not take " + "a % parameter"); else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO) - error_at (here, - "schedule % does not take " - "a % parameter"); + error_at (here, + "schedule % does not take " + "a % parameter"); else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE) - OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; + OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; else - c_parser_error (parser, "expected integer expression"); + c_parser_error (parser, "expected integer expression"); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } else c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<,%> or %<)%>"); + "expected %<,%> or %<)%>"); check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule"); OMP_CLAUSE_CHAIN (c) = list; @@ -8866,7 +9309,7 @@ check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied"); c = build_omp_clause (c_parser_peek_token (parser)->location, - OMP_CLAUSE_UNTIED); + OMP_CLAUSE_UNTIED); OMP_CLAUSE_CHAIN (c) = list; return c; @@ -8878,7 +9321,7 @@ static tree c_parser_omp_all_clauses (c_parser *parser, unsigned int mask, - const char *where) + const char *where) { tree clauses = NULL; bool first = true; @@ -8891,86 +9334,86 @@ tree prev = clauses; if (!first && c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); first = false; here = c_parser_peek_token (parser)->location; c_kind = c_parser_omp_clause_name (parser); switch (c_kind) - { - case PRAGMA_OMP_CLAUSE_COLLAPSE: - clauses = c_parser_omp_clause_collapse (parser, clauses); - c_name = "collapse"; - break; - case PRAGMA_OMP_CLAUSE_COPYIN: - clauses = c_parser_omp_clause_copyin (parser, clauses); - c_name = "copyin"; - break; - case PRAGMA_OMP_CLAUSE_COPYPRIVATE: - clauses = c_parser_omp_clause_copyprivate (parser, clauses); - c_name = "copyprivate"; - break; - case PRAGMA_OMP_CLAUSE_DEFAULT: - clauses = c_parser_omp_clause_default (parser, clauses); - c_name = "default"; - break; - case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: - clauses = c_parser_omp_clause_firstprivate (parser, clauses); - c_name = "firstprivate"; - break; - case PRAGMA_OMP_CLAUSE_IF: - clauses = c_parser_omp_clause_if (parser, clauses); - c_name = "if"; - break; - case PRAGMA_OMP_CLAUSE_LASTPRIVATE: - clauses = c_parser_omp_clause_lastprivate (parser, clauses); - c_name = "lastprivate"; - break; - case PRAGMA_OMP_CLAUSE_NOWAIT: - clauses = c_parser_omp_clause_nowait (parser, clauses); - c_name = "nowait"; - break; - case PRAGMA_OMP_CLAUSE_NUM_THREADS: - clauses = c_parser_omp_clause_num_threads (parser, clauses); - c_name = "num_threads"; - break; - case PRAGMA_OMP_CLAUSE_ORDERED: - clauses = c_parser_omp_clause_ordered (parser, clauses); - c_name = "ordered"; - break; - case PRAGMA_OMP_CLAUSE_PRIVATE: - clauses = c_parser_omp_clause_private (parser, clauses); - c_name = "private"; - break; - case PRAGMA_OMP_CLAUSE_REDUCTION: - clauses = c_parser_omp_clause_reduction (parser, clauses); - c_name = "reduction"; - break; - case PRAGMA_OMP_CLAUSE_SCHEDULE: - clauses = c_parser_omp_clause_schedule (parser, clauses); - c_name = "schedule"; - break; - case PRAGMA_OMP_CLAUSE_SHARED: - clauses = c_parser_omp_clause_shared (parser, clauses); - c_name = "shared"; - break; - case PRAGMA_OMP_CLAUSE_UNTIED: - clauses = c_parser_omp_clause_untied (parser, clauses); - c_name = "untied"; - break; - default: - c_parser_error (parser, "expected %<#pragma omp%> clause"); - goto saw_error; - } + { + case PRAGMA_OMP_CLAUSE_COLLAPSE: + clauses = c_parser_omp_clause_collapse (parser, clauses); + c_name = "collapse"; + break; + case PRAGMA_OMP_CLAUSE_COPYIN: + clauses = c_parser_omp_clause_copyin (parser, clauses); + c_name = "copyin"; + break; + case PRAGMA_OMP_CLAUSE_COPYPRIVATE: + clauses = c_parser_omp_clause_copyprivate (parser, clauses); + c_name = "copyprivate"; + break; + case PRAGMA_OMP_CLAUSE_DEFAULT: + clauses = c_parser_omp_clause_default (parser, clauses); + c_name = "default"; + break; + case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: + clauses = c_parser_omp_clause_firstprivate (parser, clauses); + c_name = "firstprivate"; + break; + case PRAGMA_OMP_CLAUSE_IF: + clauses = c_parser_omp_clause_if (parser, clauses); + c_name = "if"; + break; + case PRAGMA_OMP_CLAUSE_LASTPRIVATE: + clauses = c_parser_omp_clause_lastprivate (parser, clauses); + c_name = "lastprivate"; + break; + case PRAGMA_OMP_CLAUSE_NOWAIT: + clauses = c_parser_omp_clause_nowait (parser, clauses); + c_name = "nowait"; + break; + case PRAGMA_OMP_CLAUSE_NUM_THREADS: + clauses = c_parser_omp_clause_num_threads (parser, clauses); + c_name = "num_threads"; + break; + case PRAGMA_OMP_CLAUSE_ORDERED: + clauses = c_parser_omp_clause_ordered (parser, clauses); + c_name = "ordered"; + break; + case PRAGMA_OMP_CLAUSE_PRIVATE: + clauses = c_parser_omp_clause_private (parser, clauses); + c_name = "private"; + break; + case PRAGMA_OMP_CLAUSE_REDUCTION: + clauses = c_parser_omp_clause_reduction (parser, clauses); + c_name = "reduction"; + break; + case PRAGMA_OMP_CLAUSE_SCHEDULE: + clauses = c_parser_omp_clause_schedule (parser, clauses); + c_name = "schedule"; + break; + case PRAGMA_OMP_CLAUSE_SHARED: + clauses = c_parser_omp_clause_shared (parser, clauses); + c_name = "shared"; + break; + case PRAGMA_OMP_CLAUSE_UNTIED: + clauses = c_parser_omp_clause_untied (parser, clauses); + c_name = "untied"; + break; + default: + c_parser_error (parser, "expected %<#pragma omp%> clause"); + goto saw_error; + } if (((mask >> c_kind) & 1) == 0 && !parser->error) - { - /* Remove the invalid clause(s) from the list to avoid - confusing the rest of the compiler. */ - clauses = prev; - error_at (here, "%qs is not valid for %qs", c_name, where); - } + { + /* Remove the invalid clause(s) from the list to avoid + confusing the rest of the compiler. */ + clauses = prev; + error_at (here, "%qs is not valid for %qs", c_name, where); + } } saw_error: @@ -9079,39 +9522,39 @@ /* FALLTHRU */ default: switch (c_parser_peek_token (parser)->type) - { - case CPP_MULT_EQ: - code = MULT_EXPR; - break; - case CPP_DIV_EQ: - code = TRUNC_DIV_EXPR; - break; - case CPP_PLUS_EQ: - code = PLUS_EXPR; - break; - case CPP_MINUS_EQ: - code = MINUS_EXPR; - break; - case CPP_LSHIFT_EQ: - code = LSHIFT_EXPR; - break; - case CPP_RSHIFT_EQ: - code = RSHIFT_EXPR; - break; - case CPP_AND_EQ: - code = BIT_AND_EXPR; - break; - case CPP_OR_EQ: - code = BIT_IOR_EXPR; - break; - case CPP_XOR_EQ: - code = BIT_XOR_EXPR; - break; - default: - c_parser_error (parser, - "invalid operator for %<#pragma omp atomic%>"); - goto saw_error; - } + { + case CPP_MULT_EQ: + code = MULT_EXPR; + break; + case CPP_DIV_EQ: + code = TRUNC_DIV_EXPR; + break; + case CPP_PLUS_EQ: + code = PLUS_EXPR; + break; + case CPP_MINUS_EQ: + code = MINUS_EXPR; + break; + case CPP_LSHIFT_EQ: + code = LSHIFT_EXPR; + break; + case CPP_RSHIFT_EQ: + code = RSHIFT_EXPR; + break; + case CPP_AND_EQ: + code = BIT_AND_EXPR; + break; + case CPP_OR_EQ: + code = BIT_IOR_EXPR; + break; + case CPP_XOR_EQ: + code = BIT_XOR_EXPR; + break; + default: + c_parser_error (parser, + "invalid operator for %<#pragma omp atomic%>"); + goto saw_error; + } /* Arrange to pass the location of the assignment operator to c_finish_omp_atomic. */ @@ -9162,13 +9605,13 @@ { c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_NAME)) - { - name = c_parser_peek_token (parser)->value; - c_parser_consume_token (parser); - c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); - } + { + name = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + } else - c_parser_error (parser, "expected identifier"); + c_parser_error (parser, "expected identifier"); } else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) c_parser_error (parser, "expected %<(%> or end of line"); @@ -9205,7 +9648,7 @@ static tree c_parser_omp_for_loop (location_t loc, - c_parser *parser, tree clauses, tree *par_clauses) + c_parser *parser, tree clauses, tree *par_clauses) { tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl; tree declv, condv, incrv, initv, ret = NULL; @@ -9238,7 +9681,7 @@ int bracecount = 0; if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - goto pop_scopes; + goto pop_scopes; /* Parse the initialization declaration or expression. */ if (c_parser_next_tokens_start_declaration (parser)) @@ -9277,100 +9720,100 @@ c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } else - { - error_init: - c_parser_error (parser, - "expected iteration declaration or initialization"); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - fail = true; - goto parse_next; - } + { + error_init: + c_parser_error (parser, + "expected iteration declaration or initialization"); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + fail = true; + goto parse_next; + } /* Parse the loop condition. */ cond = NULL_TREE; if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) - { - location_t cond_loc = c_parser_peek_token (parser)->location; - struct c_expr cond_expr = c_parser_binary_expression (parser, NULL); - - cond = cond_expr.value; - cond = c_objc_common_truthvalue_conversion (cond_loc, cond); - cond = c_fully_fold (cond, false, NULL); - switch (cond_expr.original_code) - { - case GT_EXPR: - case GE_EXPR: - case LT_EXPR: - case LE_EXPR: - break; - default: - /* Can't be cond = error_mark_node, because we want to preserve - the location until c_finish_omp_for. */ - cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node); - break; - } - protected_set_expr_location (cond, cond_loc); - } + { + location_t cond_loc = c_parser_peek_token (parser)->location; + struct c_expr cond_expr = c_parser_binary_expression (parser, NULL); + + cond = cond_expr.value; + cond = c_objc_common_truthvalue_conversion (cond_loc, cond); + cond = c_fully_fold (cond, false, NULL); + switch (cond_expr.original_code) + { + case GT_EXPR: + case GE_EXPR: + case LT_EXPR: + case LE_EXPR: + break; + default: + /* Can't be cond = error_mark_node, because we want to preserve + the location until c_finish_omp_for. */ + cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node); + break; + } + protected_set_expr_location (cond, cond_loc); + } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); /* Parse the increment expression. */ incr = NULL_TREE; if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) - { - location_t incr_loc = c_parser_peek_token (parser)->location; - - incr = c_process_expr_stmt (incr_loc, - c_parser_expression (parser).value); - } + { + location_t incr_loc = c_parser_peek_token (parser)->location; + + incr = c_process_expr_stmt (incr_loc, + c_parser_expression (parser).value); + } c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (decl == NULL || decl == error_mark_node || init == error_mark_node) - fail = true; + fail = true; else - { - TREE_VEC_ELT (declv, i) = decl; - TREE_VEC_ELT (initv, i) = init; - TREE_VEC_ELT (condv, i) = cond; - TREE_VEC_ELT (incrv, i) = incr; - } + { + TREE_VEC_ELT (declv, i) = decl; + TREE_VEC_ELT (initv, i) = init; + TREE_VEC_ELT (condv, i) = cond; + TREE_VEC_ELT (incrv, i) = incr; + } parse_next: if (i == collapse - 1) - break; + break; /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed - in between the collapsed for loops to be still considered perfectly - nested. Hopefully the final version clarifies this. - For now handle (multiple) {'s and empty statements. */ + in between the collapsed for loops to be still considered perfectly + nested. Hopefully the final version clarifies this. + For now handle (multiple) {'s and empty statements. */ do - { - if (c_parser_next_token_is_keyword (parser, RID_FOR)) - { - c_parser_consume_token (parser); - break; - } - else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) - { - c_parser_consume_token (parser); - bracecount++; - } - else if (bracecount - && c_parser_next_token_is (parser, CPP_SEMICOLON)) - c_parser_consume_token (parser); - else - { - c_parser_error (parser, "not enough perfectly nested loops"); - if (bracecount) - { - open_brace_parsed = true; - bracecount--; - } - fail = true; - collapse = 0; - break; - } - } + { + if (c_parser_next_token_is_keyword (parser, RID_FOR)) + { + c_parser_consume_token (parser); + break; + } + else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) + { + c_parser_consume_token (parser); + bracecount++; + } + else if (bracecount + && c_parser_next_token_is (parser, CPP_SEMICOLON)) + c_parser_consume_token (parser); + else + { + c_parser_error (parser, "not enough perfectly nested loops"); + if (bracecount) + { + open_brace_parsed = true; + bracecount--; + } + fail = true; + collapse = 0; + break; + } + } while (1); nbraces += bracecount; @@ -9405,26 +9848,26 @@ while (nbraces) { if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) - { - c_parser_consume_token (parser); - nbraces--; - } + { + c_parser_consume_token (parser); + nbraces--; + } else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) - c_parser_consume_token (parser); + c_parser_consume_token (parser); else - { - c_parser_error (parser, "collapsed loops not perfectly nested"); - while (nbraces) - { - location_t here = c_parser_peek_token (parser)->location; - stmt = c_begin_compound_stmt (true); - add_stmt (body); - c_parser_compound_statement_nostart (parser); - body = c_end_compound_stmt (here, stmt, true); - nbraces--; - } - goto pop_scopes; - } + { + c_parser_error (parser, "collapsed loops not perfectly nested"); + while (nbraces) + { + location_t here = c_parser_peek_token (parser)->location; + stmt = c_begin_compound_stmt (true); + add_stmt (body); + c_parser_compound_statement_nostart (parser); + body = c_end_compound_stmt (here, stmt, true); + nbraces--; + } + goto pop_scopes; + } } /* Only bother calling c_finish_omp_for if we haven't already generated @@ -9433,44 +9876,44 @@ { stmt = c_finish_omp_for (loc, declv, initv, condv, incrv, body, NULL); if (stmt) - { - if (par_clauses != NULL) - { - tree *c; - for (c = par_clauses; *c ; ) - if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE - && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE) - c = &OMP_CLAUSE_CHAIN (*c); - else - { - for (i = 0; i < collapse; i++) - if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c)) - break; - if (i == collapse) - c = &OMP_CLAUSE_CHAIN (*c); - else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE) - { - error_at (loc, - "iteration variable %qD should not be firstprivate", - OMP_CLAUSE_DECL (*c)); - *c = OMP_CLAUSE_CHAIN (*c); - } - else - { - /* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES, - change it to shared (decl) in - OMP_PARALLEL_CLAUSES. */ - tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c), - OMP_CLAUSE_LASTPRIVATE); - OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c); - OMP_CLAUSE_CHAIN (l) = clauses; - clauses = l; - OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED); - } - } - } - OMP_FOR_CLAUSES (stmt) = clauses; - } + { + if (par_clauses != NULL) + { + tree *c; + for (c = par_clauses; *c ; ) + if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE + && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE) + c = &OMP_CLAUSE_CHAIN (*c); + else + { + for (i = 0; i < collapse; i++) + if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c)) + break; + if (i == collapse) + c = &OMP_CLAUSE_CHAIN (*c); + else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE) + { + error_at (loc, + "iteration variable %qD should not be firstprivate", + OMP_CLAUSE_DECL (*c)); + *c = OMP_CLAUSE_CHAIN (*c); + } + else + { + /* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES, + change it to shared (decl) in + OMP_PARALLEL_CLAUSES. */ + tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c), + OMP_CLAUSE_LASTPRIVATE); + OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c); + OMP_CLAUSE_CHAIN (l) = clauses; + clauses = l; + OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED); + } + } + } + OMP_FOR_CLAUSES (stmt) = clauses; + } ret = stmt; } pop_scopes: @@ -9493,15 +9936,15 @@ LOC is the location of the #pragma token. */ -#define OMP_FOR_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_ORDERED) \ - | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE) \ - | (1u << PRAGMA_OMP_CLAUSE_COLLAPSE) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_FOR_CLAUSE_MASK \ + ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (1u << PRAGMA_OMP_CLAUSE_ORDERED) \ + | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE) \ + | (1u << PRAGMA_OMP_CLAUSE_COLLAPSE) \ + | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree c_parser_omp_for (location_t loc, c_parser *parser) @@ -9509,7 +9952,7 @@ tree block, clauses, ret; clauses = c_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK, - "#pragma omp for"); + "#pragma omp for"); block = c_begin_compound_stmt (true); ret = c_parser_omp_for_loop (loc, parser, clauses, NULL); @@ -9580,16 +10023,16 @@ substmt = push_stmt_list (); while (1) - { + { c_parser_statement (parser); - if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) - break; - if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) - break; - if (c_parser_next_token_is (parser, CPP_EOF)) - break; - } + if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) + break; + if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) + break; + if (c_parser_next_token_is (parser, CPP_EOF)) + break; + } substmt = pop_stmt_list (substmt); substmt = build1 (OMP_SECTION, void_type_node, substmt); @@ -9600,22 +10043,22 @@ while (1) { if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) - break; + break; if (c_parser_next_token_is (parser, CPP_EOF)) - break; + break; loc = c_parser_peek_token (parser)->location; if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) - { - c_parser_consume_pragma (parser); - c_parser_skip_to_pragma_eol (parser); - error_suppress = false; - } + { + c_parser_consume_pragma (parser); + c_parser_skip_to_pragma_eol (parser); + error_suppress = false; + } else if (!error_suppress) - { - error_at (loc, "expected %<#pragma omp section%> or %<}%>"); - error_suppress = true; - } + { + error_at (loc, "expected %<#pragma omp section%> or %<}%>"); + error_suppress = true; + } substmt = c_parser_omp_structured_block (parser); substmt = build1 (OMP_SECTION, void_type_node, substmt); @@ -9623,7 +10066,7 @@ add_stmt (substmt); } c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, - "expected %<#pragma omp section%> or %<}%>"); + "expected %<#pragma omp section%> or %<}%>"); substmt = pop_stmt_list (stmt); @@ -9642,12 +10085,12 @@ LOC is the location of the #pragma token. */ -#define OMP_SECTIONS_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_SECTIONS_CLAUSE_MASK \ + ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree c_parser_omp_sections (location_t loc, c_parser *parser) @@ -9655,7 +10098,7 @@ tree block, clauses, ret; clauses = c_parser_omp_all_clauses (parser, OMP_SECTIONS_CLAUSE_MASK, - "#pragma omp sections"); + "#pragma omp sections"); block = c_begin_compound_stmt (true); ret = c_parser_omp_sections_scope (loc, parser); @@ -9675,15 +10118,15 @@ LOC is the location of the #pragma token. */ -#define OMP_PARALLEL_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_IF) \ - | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ - | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ - | (1u << PRAGMA_OMP_CLAUSE_COPYIN) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS)) +#define OMP_PARALLEL_CLAUSE_MASK \ + ( (1u << PRAGMA_OMP_CLAUSE_IF) \ + | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ + | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ + | (1u << PRAGMA_OMP_CLAUSE_COPYIN) \ + | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS)) static tree c_parser_omp_parallel (location_t loc, c_parser *parser) @@ -9705,13 +10148,13 @@ { const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); if (strcmp (p, "sections") == 0) - { - c_parser_consume_token (parser); - p_kind = PRAGMA_OMP_PARALLEL_SECTIONS; - p_name = "#pragma omp parallel sections"; - mask |= OMP_SECTIONS_CLAUSE_MASK; - mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); - } + { + c_parser_consume_token (parser); + p_kind = PRAGMA_OMP_PARALLEL_SECTIONS; + p_name = "#pragma omp parallel sections"; + mask |= OMP_SECTIONS_CLAUSE_MASK; + mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); + } } clauses = c_parser_omp_all_clauses (parser, mask, p_name); @@ -9737,7 +10180,7 @@ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause); stmt = c_parser_omp_sections_scope (loc, parser); if (stmt) - OMP_SECTIONS_CLAUSES (stmt) = ws_clause; + OMP_SECTIONS_CLAUSES (stmt) = ws_clause; stmt = c_finish_omp_parallel (loc, par_clause, block); OMP_PARALLEL_COMBINED (stmt) = 1; break; @@ -9756,11 +10199,11 @@ LOC is the location of the #pragma. */ -#define OMP_SINGLE_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_SINGLE_CLAUSE_MASK \ + ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree c_parser_omp_single (location_t loc, c_parser *parser) @@ -9771,7 +10214,7 @@ OMP_SINGLE_CLAUSES (stmt) = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK, - "#pragma omp single"); + "#pragma omp single"); OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser); return add_stmt (stmt); @@ -9783,13 +10226,13 @@ LOC is the location of the #pragma. */ -#define OMP_TASK_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_IF) \ - | (1u << PRAGMA_OMP_CLAUSE_UNTIED) \ - | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ - | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_SHARED)) +#define OMP_TASK_CLAUSE_MASK \ + ( (1u << PRAGMA_OMP_CLAUSE_IF) \ + | (1u << PRAGMA_OMP_CLAUSE_UNTIED) \ + | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ + | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (1u << PRAGMA_OMP_CLAUSE_SHARED)) static tree c_parser_omp_task (location_t loc, c_parser *parser) @@ -9797,7 +10240,7 @@ tree clauses, block; clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK, - "#pragma omp task"); + "#pragma omp task"); block = c_begin_omp_task (); c_parser_statement (parser); @@ -9888,36 +10331,36 @@ tree v = TREE_PURPOSE (t); /* FIXME diagnostics: Ideally we should keep individual - locations for all the variables in the var list to make the - following errors more precise. Perhaps - c_parser_omp_var_list_parens() should construct a list of - locations to go along with the var list. */ + locations for all the variables in the var list to make the + following errors more precise. Perhaps + c_parser_omp_var_list_parens() should construct a list of + locations to go along with the var list. */ /* If V had already been marked threadprivate, it doesn't matter - whether it had been used prior to this point. */ + whether it had been used prior to this point. */ if (TREE_CODE (v) != VAR_DECL) - error_at (loc, "%qD is not a variable", v); + error_at (loc, "%qD is not a variable", v); else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v)) - error_at (loc, "%qE declared % after first use", v); + error_at (loc, "%qE declared % after first use", v); else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v)) - error_at (loc, "automatic variable %qE cannot be %", v); + error_at (loc, "automatic variable %qE cannot be %", v); else if (TREE_TYPE (v) == error_mark_node) - ; + ; else if (! COMPLETE_TYPE_P (TREE_TYPE (v))) - error_at (loc, "% %qE has incomplete type", v); + error_at (loc, "% %qE has incomplete type", v); else - { - if (! DECL_THREAD_LOCAL_P (v)) - { - DECL_TLS_MODEL (v) = decl_default_tls_model (v); - /* If rtl has been already set for this var, call - make_decl_rtl once again, so that encode_section_info - has a chance to look at the new decl flags. */ - if (DECL_RTL_SET_P (v)) - make_decl_rtl (v); - } - C_DECL_THREADPRIVATE_P (v) = 1; - } + { + if (! DECL_THREAD_LOCAL_P (v)) + { + DECL_TLS_MODEL (v) = decl_default_tls_model (v); + /* If rtl has been already set for this var, call + make_decl_rtl once again, so that encode_section_info + has a chance to look at the new decl flags. */ + if (DECL_RTL_SET_P (v)) + make_decl_rtl (v); + } + C_DECL_THREADPRIVATE_P (v) = 1; + } } c_parser_skip_to_pragma_eol (parser); diff -r 561a7518be6b -r 1b10fe6932e1 gcc/c-tree.h --- a/gcc/c-tree.h Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/c-tree.h Sun Aug 21 07:53:12 2011 +0900 @@ -70,12 +70,12 @@ /* For FUNCTION_DECLs, evaluates true if the decl is built-in but has been declared. */ -#define C_DECL_DECLARED_BUILTIN(EXP) \ +#define C_DECL_DECLARED_BUILTIN(EXP) \ DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (EXP)) /* For FUNCTION_DECLs, evaluates true if the decl is built-in, has a built-in prototype and does not have a non-built-in prototype. */ -#define C_DECL_BUILTIN_PROTOTYPE(EXP) \ +#define C_DECL_BUILTIN_PROTOTYPE(EXP) \ DECL_LANG_FLAG_6 (FUNCTION_DECL_CHECK (EXP)) /* Record whether a decl was declared register. This is strictly a @@ -199,6 +199,9 @@ cts_float, cts_int128, cts_double, +#ifndef noCbC + cts_CbC_code, +#endif cts_dfloat32, cts_dfloat64, cts_dfloat128, @@ -419,7 +422,7 @@ extern void c_bindings_end_stmt_expr (struct c_spot_bindings *); extern void record_inline_static (location_t, tree, tree, - enum c_inline_static_type); + enum c_inline_static_type); extern void c_init_decl_processing (void); extern void c_print_identifier (FILE *, tree, int); extern int quals_from_declspecs (const struct c_declspecs *); @@ -438,7 +441,7 @@ extern struct c_spot_bindings *c_get_switch_bindings (void); extern void c_release_switch_bindings (struct c_spot_bindings *); extern bool c_check_switch_jump_warnings (struct c_spot_bindings *, - location_t, location_t); + location_t, location_t); extern void finish_decl (tree, location_t, tree, tree, tree); extern tree finish_enum (tree, tree, tree); extern void finish_function (void); @@ -447,17 +450,23 @@ extern struct c_arg_info *build_arg_info (void); extern struct c_arg_info *get_parm_info (bool); extern tree grokfield (location_t, struct c_declarator *, - struct c_declspecs *, tree, tree *); + struct c_declspecs *, tree, tree *); extern tree groktypename (struct c_type_name *, tree *, bool *); extern tree grokparm (const struct c_parm *); + +#ifndef noCbC +extern tree implicitly_declare (location_t, tree, int); +#else extern tree implicitly_declare (location_t, tree); +#endif + extern void keep_next_level (void); extern void pending_xref_error (void); extern void c_push_function_context (void); extern void c_pop_function_context (void); extern void push_parm_decl (const struct c_parm *); extern struct c_declarator *set_array_declarator_inner (struct c_declarator *, - struct c_declarator *); + struct c_declarator *); extern tree c_builtin_function (tree); extern tree c_builtin_function_ext_scope (tree); extern void shadow_tag (const struct c_declspecs *); @@ -465,32 +474,32 @@ extern tree start_enum (location_t, struct c_enum_contents *, tree); extern int start_function (struct c_declspecs *, struct c_declarator *, tree); extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool, - tree); + tree); extern tree start_struct (location_t, enum tree_code, tree, - struct c_struct_parse_info **); + struct c_struct_parse_info **); extern void store_parm_decls (void); extern void store_parm_decls_from (struct c_arg_info *); extern tree xref_tag (enum tree_code, tree); extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree); extern int c_expand_decl (tree); extern struct c_parm *build_c_parm (struct c_declspecs *, tree, - struct c_declarator *); + struct c_declarator *); extern struct c_declarator *build_attrs_declarator (tree, - struct c_declarator *); + struct c_declarator *); extern struct c_declarator *build_function_declarator (struct c_arg_info *, - struct c_declarator *); + struct c_declarator *); extern struct c_declarator *build_id_declarator (tree); extern struct c_declarator *make_pointer_declarator (struct c_declspecs *, - struct c_declarator *); + struct c_declarator *); extern struct c_declspecs *build_null_declspecs (void); extern struct c_declspecs *declspecs_add_qual (struct c_declspecs *, tree); extern struct c_declspecs *declspecs_add_type (location_t, - struct c_declspecs *, - struct c_typespec); + struct c_declspecs *, + struct c_typespec); extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree); extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree); extern struct c_declspecs *declspecs_add_addrspace (struct c_declspecs *, - addr_space_t); + addr_space_t); extern struct c_declspecs *finish_declspecs (struct c_declspecs *); /* in c-objc-common.c */ @@ -529,12 +538,12 @@ extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr); extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *); extern struct c_expr parser_build_unary_op (location_t, enum tree_code, - struct c_expr); + struct c_expr); extern struct c_expr parser_build_binary_op (location_t, - enum tree_code, struct c_expr, - struct c_expr); + enum tree_code, struct c_expr, + struct c_expr); extern tree build_conditional_expr (location_t, tree, bool, tree, tree, - tree, tree); + tree, tree); extern tree build_compound_expr (location_t, tree, tree); extern tree c_cast_expr (location_t, struct c_type_name *, tree); extern tree build_c_cast (location_t, tree, tree); diff -r 561a7518be6b -r 1b10fe6932e1 gcc/c-typeck.c --- a/gcc/c-typeck.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/c-typeck.c Sun Aug 21 07:53:12 2011 +0900 @@ -40,6 +40,10 @@ #include "tree-iterator.h" #include "bitmap.h" #include "gimple.h" +#include "tree-flow.h" +#ifndef noCbC + #include "cbc-tree.h" +#endif #include "c-family/c-objc.h" /* Possible cases of implicit bad conversions. Used to select @@ -77,10 +81,10 @@ static int type_lists_compatible_p (const_tree, const_tree, bool *, bool *); static tree lookup_field (tree, tree); static int convert_arguments (tree, VEC(tree,gc) *, VEC(tree,gc) *, tree, - tree); + tree); static tree pointer_diff (location_t, tree, tree); static tree convert_for_assignment (location_t, tree, tree, tree, - enum impl_conv, bool, tree, tree, int); + enum impl_conv, bool, tree, tree, int); static tree valid_compound_expr_initializer (tree, tree); static void push_string (const char *); static void push_member_name (tree); @@ -111,12 +115,12 @@ yet available everywhere required. */ tree type = TREE_TYPE (expr); return (TREE_CODE (expr) == INTEGER_CST - && !TREE_OVERFLOW (expr) - && integer_zerop (expr) - && (INTEGRAL_TYPE_P (type) - || (TREE_CODE (type) == POINTER_TYPE - && VOID_TYPE_P (TREE_TYPE (type)) - && TYPE_QUALS (TREE_TYPE (type)) == TYPE_UNQUALIFIED))); + && !TREE_OVERFLOW (expr) + && integer_zerop (expr) + && (INTEGRAL_TYPE_P (type) + || (TREE_CODE (type) == POINTER_TYPE + && VOID_TYPE_P (TREE_TYPE (type)) + && TYPE_QUALS (TREE_TYPE (type)) == TYPE_UNQUALIFIED))); } /* EXPR may appear in an unevaluated part of an integer constant @@ -202,7 +206,7 @@ return; if (value != 0 && (TREE_CODE (value) == VAR_DECL - || TREE_CODE (value) == PARM_DECL)) + || TREE_CODE (value) == PARM_DECL)) error ("%qD has an incomplete type", value); else { @@ -210,47 +214,47 @@ /* We must print an error message. Be clever about what it says. */ switch (TREE_CODE (type)) - { - case RECORD_TYPE: - type_code_string = "struct"; - break; - - case UNION_TYPE: - type_code_string = "union"; - break; - - case ENUMERAL_TYPE: - type_code_string = "enum"; - break; - - case VOID_TYPE: - error ("invalid use of void expression"); - return; - - case ARRAY_TYPE: - if (TYPE_DOMAIN (type)) - { - if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL) - { - error ("invalid use of flexible array member"); - return; - } - type = TREE_TYPE (type); - goto retry; - } - error ("invalid use of array with unspecified bounds"); - return; - - default: - gcc_unreachable (); - } + { + case RECORD_TYPE: + type_code_string = "struct"; + break; + + case UNION_TYPE: + type_code_string = "union"; + break; + + case ENUMERAL_TYPE: + type_code_string = "enum"; + break; + + case VOID_TYPE: + error ("invalid use of void expression"); + return; + + case ARRAY_TYPE: + if (TYPE_DOMAIN (type)) + { + if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL) + { + error ("invalid use of flexible array member"); + return; + } + type = TREE_TYPE (type); + goto retry; + } + error ("invalid use of array with unspecified bounds"); + return; + + default: + gcc_unreachable (); + } if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error ("invalid use of undefined type %<%s %E%>", - type_code_string, TYPE_NAME (type)); + error ("invalid use of undefined type %<%s %E%>", + type_code_string, TYPE_NAME (type)); else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error ("invalid use of incomplete typedef %qD", TYPE_NAME (type)); + /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ + error ("invalid use of incomplete typedef %qD", TYPE_NAME (type)); } } @@ -267,8 +271,8 @@ { /* Preserve unsignedness if not really getting any wider. */ if (TYPE_UNSIGNED (type) - && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) - return unsigned_type_node; + && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) + return unsigned_type_node; return integer_type_node; } @@ -317,13 +321,13 @@ { as_common = as_type; error ("%qT and %qT are in disjoint named address spaces", - type, like); + type, like); } return c_build_qualified_type (type, - TYPE_QUALS_NO_ADDR_SPACE (type) - | TYPE_QUALS_NO_ADDR_SPACE (like) - | ENCODE_QUAL_ADDR_SPACE (as_common)); + TYPE_QUALS_NO_ADDR_SPACE (type) + | TYPE_QUALS_NO_ADDR_SPACE (like) + | ENCODE_QUAL_ADDR_SPACE (as_common)); } /* Return true iff the given tree T is a variable length array. */ @@ -383,101 +387,104 @@ case POINTER_TYPE: /* For two pointers, do this recursively on the target type. */ { - tree pointed_to_1 = TREE_TYPE (t1); - tree pointed_to_2 = TREE_TYPE (t2); - tree target = composite_type (pointed_to_1, pointed_to_2); - t1 = build_pointer_type (target); - t1 = build_type_attribute_variant (t1, attributes); - return qualify_type (t1, t2); + tree pointed_to_1 = TREE_TYPE (t1); + tree pointed_to_2 = TREE_TYPE (t2); + tree target = composite_type (pointed_to_1, pointed_to_2); + t1 = build_pointer_type (target); + t1 = build_type_attribute_variant (t1, attributes); + return qualify_type (t1, t2); } case ARRAY_TYPE: { - tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2)); - int quals; - tree unqual_elt; - tree d1 = TYPE_DOMAIN (t1); - tree d2 = TYPE_DOMAIN (t2); - bool d1_variable, d2_variable; - bool d1_zero, d2_zero; - bool t1_complete, t2_complete; - - /* We should not have any type quals on arrays at all. */ - gcc_assert (!TYPE_QUALS_NO_ADDR_SPACE (t1) - && !TYPE_QUALS_NO_ADDR_SPACE (t2)); - - t1_complete = COMPLETE_TYPE_P (t1); - t2_complete = COMPLETE_TYPE_P (t2); - - d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1); - d2_zero = d2 == 0 || !TYPE_MAX_VALUE (d2); - - d1_variable = (!d1_zero - && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST)); - d2_variable = (!d2_zero - && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)); - d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1)); - d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2)); - - /* Save space: see if the result is identical to one of the args. */ - if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1) - && (d2_variable || d2_zero || !d1_variable)) - return build_type_attribute_variant (t1, attributes); - if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2) - && (d1_variable || d1_zero || !d2_variable)) - return build_type_attribute_variant (t2, attributes); - - if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) - return build_type_attribute_variant (t1, attributes); - if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) - return build_type_attribute_variant (t2, attributes); - - /* Merge the element types, and have a size if either arg has - one. We may have qualifiers on the element types. To set - up TYPE_MAIN_VARIANT correctly, we need to form the - composite of the unqualified types and add the qualifiers - back at the end. */ - quals = TYPE_QUALS (strip_array_types (elt)); - unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED); - t1 = build_array_type (unqual_elt, - TYPE_DOMAIN ((TYPE_DOMAIN (t1) - && (d2_variable - || d2_zero - || !d1_variable)) - ? t1 - : t2)); - /* Ensure a composite type involving a zero-length array type - is a zero-length type not an incomplete type. */ - if (d1_zero && d2_zero - && (t1_complete || t2_complete) - && !COMPLETE_TYPE_P (t1)) - { - TYPE_SIZE (t1) = bitsize_zero_node; - TYPE_SIZE_UNIT (t1) = size_zero_node; - } - t1 = c_build_qualified_type (t1, quals); - return build_type_attribute_variant (t1, attributes); + tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2)); + int quals; + tree unqual_elt; + tree d1 = TYPE_DOMAIN (t1); + tree d2 = TYPE_DOMAIN (t2); + bool d1_variable, d2_variable; + bool d1_zero, d2_zero; + bool t1_complete, t2_complete; + + /* We should not have any type quals on arrays at all. */ + gcc_assert (!TYPE_QUALS_NO_ADDR_SPACE (t1) + && !TYPE_QUALS_NO_ADDR_SPACE (t2)); + + t1_complete = COMPLETE_TYPE_P (t1); + t2_complete = COMPLETE_TYPE_P (t2); + + d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1); + d2_zero = d2 == 0 || !TYPE_MAX_VALUE (d2); + + d1_variable = (!d1_zero + && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST + || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST)); + d2_variable = (!d2_zero + && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST + || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)); + d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1)); + d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2)); + + /* Save space: see if the result is identical to one of the args. */ + if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1) + && (d2_variable || d2_zero || !d1_variable)) + return build_type_attribute_variant (t1, attributes); + if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2) + && (d1_variable || d1_zero || !d2_variable)) + return build_type_attribute_variant (t2, attributes); + + if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) + return build_type_attribute_variant (t1, attributes); + if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) + return build_type_attribute_variant (t2, attributes); + + /* Merge the element types, and have a size if either arg has + one. We may have qualifiers on the element types. To set + up TYPE_MAIN_VARIANT correctly, we need to form the + composite of the unqualified types and add the qualifiers + back at the end. */ + quals = TYPE_QUALS (strip_array_types (elt)); + unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED); + t1 = build_array_type (unqual_elt, + TYPE_DOMAIN ((TYPE_DOMAIN (t1) + && (d2_variable + || d2_zero + || !d1_variable)) + ? t1 + : t2)); + /* Ensure a composite type involving a zero-length array type + is a zero-length type not an incomplete type. */ + if (d1_zero && d2_zero + && (t1_complete || t2_complete) + && !COMPLETE_TYPE_P (t1)) + { + TYPE_SIZE (t1) = bitsize_zero_node; + TYPE_SIZE_UNIT (t1) = size_zero_node; + } + t1 = c_build_qualified_type (t1, quals); + return build_type_attribute_variant (t1, attributes); } case ENUMERAL_TYPE: case RECORD_TYPE: case UNION_TYPE: if (attributes != NULL) - { - /* Try harder not to create a new aggregate type. */ - if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes)) - return t1; - if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes)) - return t2; - } + { + /* Try harder not to create a new aggregate type. */ + if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes)) + return t1; + if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes)) + return t2; + } return build_type_attribute_variant (t1, attributes); case FUNCTION_TYPE: /* Function types: prefer the one that specified arg types. - If both do, merge the arg types. Also merge the return types. */ + If both do, merge the arg types. Also merge the return types. */ { +#ifndef noCbC + int is_code_segment = CbC_IS_CODE_SEGMENT(t1); +#endif tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2)); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); @@ -494,12 +501,20 @@ /* Simple way if one arg fails to specify argument types. */ if (TYPE_ARG_TYPES (t1) == 0) { +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, TYPE_ARG_TYPES (t2)); + else +#endif t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); t1 = build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); } if (TYPE_ARG_TYPES (t2) == 0) { +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, TYPE_ARG_TYPES (t1)); + else +#endif t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); t1 = build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); @@ -593,11 +608,15 @@ } c_override_global_bindings_to_false = false; + +#ifndef noCbC + if (is_code_segment) t1 = build_code_segment_type (valtype, newargs); + else +#endif t1 = build_function_type (valtype, newargs); t1 = qualify_type (t1, t2); /* ... falls through ... */ } - default: return build_type_attribute_variant (t1, attributes); } @@ -632,7 +651,7 @@ return t1; gcc_assert (TREE_CODE (t1) == POINTER_TYPE - && TREE_CODE (t2) == POINTER_TYPE); + && TREE_CODE (t2) == POINTER_TYPE); /* Merge the attributes. */ attributes = targetm.merge_type_attributes (t1, t2); @@ -713,11 +732,11 @@ code2 = TREE_CODE (t2); gcc_assert (code1 == VECTOR_TYPE || code1 == COMPLEX_TYPE - || code1 == FIXED_POINT_TYPE || code1 == REAL_TYPE - || code1 == INTEGER_TYPE); + || code1 == FIXED_POINT_TYPE || code1 == REAL_TYPE + || code1 == INTEGER_TYPE); gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE - || code2 == FIXED_POINT_TYPE || code2 == REAL_TYPE - || code2 == INTEGER_TYPE); + || code2 == FIXED_POINT_TYPE || code2 == REAL_TYPE + || code2 == INTEGER_TYPE); /* When one operand is a decimal float type, the other operand cannot be a generic float type or a complex type. We also disallow vector types @@ -726,20 +745,20 @@ && !(DECIMAL_FLOAT_TYPE_P (t1) && DECIMAL_FLOAT_TYPE_P (t2))) { if (code1 == VECTOR_TYPE || code2 == VECTOR_TYPE) - { - error ("can%'t mix operands of decimal float and vector types"); - return error_mark_node; - } + { + error ("can%'t mix operands of decimal float and vector types"); + return error_mark_node; + } if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) - { - error ("can%'t mix operands of decimal float and complex types"); - return error_mark_node; - } + { + error ("can%'t mix operands of decimal float and complex types"); + return error_mark_node; + } if (code1 == REAL_TYPE && code2 == REAL_TYPE) - { - error ("can%'t mix operands of decimal float and other float types"); - return error_mark_node; - } + { + error ("can%'t mix operands of decimal float and other float types"); + return error_mark_node; + } } /* If one type is a vector type, return that type. (How the usual @@ -761,11 +780,11 @@ tree subtype = c_common_type (subtype1, subtype2); if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) - return t1; + return t1; else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) - return t2; + return t2; else - return build_complex_type (subtype); + return build_complex_type (subtype); } /* If only one is real, use it as the result. */ @@ -782,14 +801,14 @@ if (code1 == REAL_TYPE && code2 == REAL_TYPE) { if (TYPE_MAIN_VARIANT (t1) == dfloat128_type_node - || TYPE_MAIN_VARIANT (t2) == dfloat128_type_node) - return dfloat128_type_node; + || TYPE_MAIN_VARIANT (t2) == dfloat128_type_node) + return dfloat128_type_node; else if (TYPE_MAIN_VARIANT (t1) == dfloat64_type_node - || TYPE_MAIN_VARIANT (t2) == dfloat64_type_node) - return dfloat64_type_node; + || TYPE_MAIN_VARIANT (t2) == dfloat64_type_node) + return dfloat64_type_node; else if (TYPE_MAIN_VARIANT (t1) == dfloat32_type_node - || TYPE_MAIN_VARIANT (t2) == dfloat32_type_node) - return dfloat32_type_node; + || TYPE_MAIN_VARIANT (t2) == dfloat32_type_node) + return dfloat32_type_node; } /* Deal with fixed-point types. */ @@ -804,77 +823,77 @@ /* If one input type is saturating, the result type is saturating. */ if (TYPE_SATURATING (t1) || TYPE_SATURATING (t2)) - satp = 1; + satp = 1; /* If both fixed-point types are unsigned, the result type is unsigned. - When mixing fixed-point and integer types, follow the sign of the - fixed-point type. - Otherwise, the result type is signed. */ + When mixing fixed-point and integer types, follow the sign of the + fixed-point type. + Otherwise, the result type is signed. */ if ((TYPE_UNSIGNED (t1) && TYPE_UNSIGNED (t2) - && code1 == FIXED_POINT_TYPE && code2 == FIXED_POINT_TYPE) - || (code1 == FIXED_POINT_TYPE && code2 != FIXED_POINT_TYPE - && TYPE_UNSIGNED (t1)) - || (code1 != FIXED_POINT_TYPE && code2 == FIXED_POINT_TYPE - && TYPE_UNSIGNED (t2))) - unsignedp = 1; + && code1 == FIXED_POINT_TYPE && code2 == FIXED_POINT_TYPE) + || (code1 == FIXED_POINT_TYPE && code2 != FIXED_POINT_TYPE + && TYPE_UNSIGNED (t1)) + || (code1 != FIXED_POINT_TYPE && code2 == FIXED_POINT_TYPE + && TYPE_UNSIGNED (t2))) + unsignedp = 1; /* The result type is signed. */ if (unsignedp == 0) - { - /* If the input type is unsigned, we need to convert to the - signed type. */ - if (code1 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t1)) - { - enum mode_class mclass = (enum mode_class) 0; - if (GET_MODE_CLASS (m1) == MODE_UFRACT) - mclass = MODE_FRACT; - else if (GET_MODE_CLASS (m1) == MODE_UACCUM) - mclass = MODE_ACCUM; - else - gcc_unreachable (); - m1 = mode_for_size (GET_MODE_PRECISION (m1), mclass, 0); - } - if (code2 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t2)) - { - enum mode_class mclass = (enum mode_class) 0; - if (GET_MODE_CLASS (m2) == MODE_UFRACT) - mclass = MODE_FRACT; - else if (GET_MODE_CLASS (m2) == MODE_UACCUM) - mclass = MODE_ACCUM; - else - gcc_unreachable (); - m2 = mode_for_size (GET_MODE_PRECISION (m2), mclass, 0); - } - } + { + /* If the input type is unsigned, we need to convert to the + signed type. */ + if (code1 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t1)) + { + enum mode_class mclass = (enum mode_class) 0; + if (GET_MODE_CLASS (m1) == MODE_UFRACT) + mclass = MODE_FRACT; + else if (GET_MODE_CLASS (m1) == MODE_UACCUM) + mclass = MODE_ACCUM; + else + gcc_unreachable (); + m1 = mode_for_size (GET_MODE_PRECISION (m1), mclass, 0); + } + if (code2 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t2)) + { + enum mode_class mclass = (enum mode_class) 0; + if (GET_MODE_CLASS (m2) == MODE_UFRACT) + mclass = MODE_FRACT; + else if (GET_MODE_CLASS (m2) == MODE_UACCUM) + mclass = MODE_ACCUM; + else + gcc_unreachable (); + m2 = mode_for_size (GET_MODE_PRECISION (m2), mclass, 0); + } + } if (code1 == FIXED_POINT_TYPE) - { - fbit1 = GET_MODE_FBIT (m1); - ibit1 = GET_MODE_IBIT (m1); - } + { + fbit1 = GET_MODE_FBIT (m1); + ibit1 = GET_MODE_IBIT (m1); + } else - { - fbit1 = 0; - /* Signed integers need to subtract one sign bit. */ - ibit1 = TYPE_PRECISION (t1) - (!TYPE_UNSIGNED (t1)); - } + { + fbit1 = 0; + /* Signed integers need to subtract one sign bit. */ + ibit1 = TYPE_PRECISION (t1) - (!TYPE_UNSIGNED (t1)); + } if (code2 == FIXED_POINT_TYPE) - { - fbit2 = GET_MODE_FBIT (m2); - ibit2 = GET_MODE_IBIT (m2); - } + { + fbit2 = GET_MODE_FBIT (m2); + ibit2 = GET_MODE_IBIT (m2); + } else - { - fbit2 = 0; - /* Signed integers need to subtract one sign bit. */ - ibit2 = TYPE_PRECISION (t2) - (!TYPE_UNSIGNED (t2)); - } + { + fbit2 = 0; + /* Signed integers need to subtract one sign bit. */ + ibit2 = TYPE_PRECISION (t2) - (!TYPE_UNSIGNED (t2)); + } max_ibit = ibit1 >= ibit2 ? ibit1 : ibit2; max_fbit = fbit1 >= fbit2 ? fbit1 : fbit2; return c_common_fixed_point_type_for_size (max_ibit, max_fbit, unsignedp, - satp); + satp); } /* Both real or both integers; use the one with greater precision. */ @@ -896,9 +915,9 @@ || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node) { if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) - return long_long_unsigned_type_node; + return long_long_unsigned_type_node; else - return long_long_integer_type_node; + return long_long_integer_type_node; } if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node @@ -909,11 +928,11 @@ || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) { /* But preserve unsignedness from the other type, - since long cannot hold all the values of an unsigned int. */ + since long cannot hold all the values of an unsigned int. */ if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) - return long_unsigned_type_node; + return long_unsigned_type_node; else - return long_integer_type_node; + return long_integer_type_node; } /* Likewise, prefer long double to double even if same size. */ @@ -1090,8 +1109,8 @@ case POINTER_TYPE: /* Do not remove mode or aliasing information. */ if (TYPE_MODE (t1) != TYPE_MODE (t2) - || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)) - break; + || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)) + break; val = (TREE_TYPE (t1) == TREE_TYPE (t2) ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), enum_and_int_p, different_types_p)); @@ -1217,7 +1236,7 @@ if (val == 1 && enum_and_int_p && warn_cxx_compat) warning_at (location, OPT_Wc___compat, - "pointer target types incompatible in C++"); + "pointer target types incompatible in C++"); return val; } @@ -1235,11 +1254,11 @@ switch (TREE_CODE_CLASS (TREE_CODE (t1))) { case tcc_declaration: - t1 = DECL_CONTEXT (t1); break; + t1 = DECL_CONTEXT (t1); break; case tcc_type: - t1 = TYPE_CONTEXT (t1); break; + t1 = TYPE_CONTEXT (t1); break; case tcc_exceptional: - t1 = BLOCK_SUPERCONTEXT (t1); break; /* assume block */ + t1 = BLOCK_SUPERCONTEXT (t1); break; /* assume block */ default: gcc_unreachable (); } @@ -1247,11 +1266,11 @@ switch (TREE_CODE_CLASS (TREE_CODE (t2))) { case tcc_declaration: - t2 = DECL_CONTEXT (t2); break; + t2 = DECL_CONTEXT (t2); break; case tcc_type: - t2 = TYPE_CONTEXT (t2); break; + t2 = TYPE_CONTEXT (t2); break; case tcc_exceptional: - t2 = BLOCK_SUPERCONTEXT (t2); break; /* assume block */ + t2 = BLOCK_SUPERCONTEXT (t2); break; /* assume block */ default: gcc_unreachable (); } @@ -1295,7 +1314,7 @@ while (tu != tu_til) { const struct tagged_tu_seen_cache *const tu1 - = (const struct tagged_tu_seen_cache *) tu; + = (const struct tagged_tu_seen_cache *) tu; tu = tu1->next; free (CONST_CAST (struct tagged_tu_seen_cache *, tu1)); } @@ -1323,13 +1342,13 @@ In the case of compiler-created builtin structs the TYPE_DECL may be a dummy, with no DECL_ORIGINAL_TYPE. Don't fault. */ while (TYPE_NAME (t1) - && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL - && DECL_ORIGINAL_TYPE (TYPE_NAME (t1))) + && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL + && DECL_ORIGINAL_TYPE (TYPE_NAME (t1))) t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1)); while (TYPE_NAME (t2) - && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL - && DECL_ORIGINAL_TYPE (TYPE_NAME (t2))) + && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL + && DECL_ORIGINAL_TYPE (TYPE_NAME (t2))) t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2)); /* C90 didn't have the requirement that the two tags be the same. */ @@ -1347,61 +1366,61 @@ const struct tagged_tu_seen_cache * tts_i; for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next) if (tts_i->t1 == t1 && tts_i->t2 == t2) - return tts_i->val; + return tts_i->val; } switch (TREE_CODE (t1)) { case ENUMERAL_TYPE: { - struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2); - /* Speed up the case where the type values are in the same order. */ - tree tv1 = TYPE_VALUES (t1); - tree tv2 = TYPE_VALUES (t2); - - if (tv1 == tv2) - { - return 1; - } - - for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2)) - { - if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2)) - break; - if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1) - { - tu->val = 0; - return 0; - } - } - - if (tv1 == NULL_TREE && tv2 == NULL_TREE) - { - return 1; - } - if (tv1 == NULL_TREE || tv2 == NULL_TREE) - { - tu->val = 0; - return 0; - } - - if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2))) - { - tu->val = 0; - return 0; - } - - for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1)) - { - s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2)); - if (s2 == NULL - || simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1) - { - tu->val = 0; - return 0; - } - } - return 1; + struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2); + /* Speed up the case where the type values are in the same order. */ + tree tv1 = TYPE_VALUES (t1); + tree tv2 = TYPE_VALUES (t2); + + if (tv1 == tv2) + { + return 1; + } + + for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2)) + { + if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2)) + break; + if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1) + { + tu->val = 0; + return 0; + } + } + + if (tv1 == NULL_TREE && tv2 == NULL_TREE) + { + return 1; + } + if (tv1 == NULL_TREE || tv2 == NULL_TREE) + { + tu->val = 0; + return 0; + } + + if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2))) + { + tu->val = 0; + return 0; + } + + for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1)) + { + s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2)); + if (s2 == NULL + || simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1) + { + tu->val = 0; + return 0; + } + } + return 1; } case UNION_TYPE: @@ -1507,7 +1526,6 @@ break; if (result == 2) needs_warning = true; - if (TREE_CODE (s1) == FIELD_DECL && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1), DECL_FIELD_BIT_OFFSET (s2)) != 1) @@ -1552,7 +1570,7 @@ pedwarn (input_location, 0, "function return types not compatible due to %"); if (TYPE_VOLATILE (ret1)) ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1), - TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE); + TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE); if (TYPE_VOLATILE (ret2)) ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2), TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE); @@ -1573,10 +1591,10 @@ if (args1 == 0) { if (!self_promoting_args_p (args2)) - return 0; + return 0; /* If one of these types comes from a non-prototype fn definition, - compare that with the other type's arglist. - If they don't match, ask for a warning (but no error). */ + compare that with the other type's arglist. + If they don't match, ask for a warning (but no error). */ if (TYPE_ACTUAL_ARG_TYPES (f1) && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), enum_and_int_p, different_types_p)) @@ -1586,7 +1604,7 @@ if (args2 == 0) { if (!self_promoting_args_p (args1)) - return 0; + return 0; if (TYPE_ACTUAL_ARG_TYPES (f2) && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), enum_and_int_p, different_types_p)) @@ -1617,17 +1635,17 @@ { tree a1, mv1, a2, mv2; if (args1 == 0 && args2 == 0) - return val; + return val; /* If one list is shorter than the other, - they fail to match. */ + they fail to match. */ if (args1 == 0 || args2 == 0) - return 0; + return 0; mv1 = a1 = TREE_VALUE (args1); mv2 = a2 = TREE_VALUE (args2); if (mv1 && mv1 != error_mark_node && TREE_CODE (mv1) != ARRAY_TYPE) - mv1 = TYPE_MAIN_VARIANT (mv1); + mv1 = TYPE_MAIN_VARIANT (mv1); if (mv2 && mv2 != error_mark_node && TREE_CODE (mv2) != ARRAY_TYPE) - mv2 = TYPE_MAIN_VARIANT (mv2); + mv2 = TYPE_MAIN_VARIANT (mv2); /* A null pointer instead of a type means there is supposed to be an argument but nothing is specified about what type it has. @@ -1636,15 +1654,15 @@ && (a1 == 0) != (a2 == 0)) *different_types_p = true; if (a1 == 0) - { - if (c_type_promotes_to (a2) != a2) - return 0; - } + { + if (c_type_promotes_to (a2) != a2) + return 0; + } else if (a2 == 0) - { - if (c_type_promotes_to (a1) != a1) - return 0; - } + { + if (c_type_promotes_to (a1) != a1) + return 0; + } /* If one of the lists has an error marker, ignore this arg. */ else if (TREE_CODE (a1) == ERROR_MARK || TREE_CODE (a2) == ERROR_MARK) @@ -1706,7 +1724,7 @@ /* comptypes said ok, but record if it said to warn. */ if (newval > val) - val = newval; + val = newval; args1 = TREE_CHAIN (args1); args2 = TREE_CHAIN (args2); @@ -1731,8 +1749,8 @@ /* Convert in case a char is more than one unit. */ return size_binop_loc (input_location, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), - size_int (TYPE_PRECISION (char_type_node) - / BITS_PER_UNIT)); + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); } /* Return either DECL or its known constant value (if it has one). */ @@ -1741,8 +1759,8 @@ decl_constant_value (tree decl) { if (/* Don't change a variable array bound or initial value to a constant - in a place where a variable is invalid. Note that DECL_INITIAL - isn't valid for a PARM_DECL. */ + in a place where a variable is invalid. Note that DECL_INITIAL + isn't valid for a PARM_DECL. */ current_function_decl != 0 && TREE_CODE (decl) != PARM_DECL && !TREE_THIS_VOLATILE (decl) @@ -1750,8 +1768,8 @@ && DECL_INITIAL (decl) != 0 && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK /* This is invalid if initial value is not constant. - If it has either a function call, a memory reference, - or a variable, then re-evaluating it could give different results. */ + If it has either a function call, a memory reference, + or a variable, then re-evaluating it could give different results. */ && TREE_CONSTANT (DECL_INITIAL (decl)) /* Check for cases where this is sub-optimal, even though valid. */ && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) @@ -1848,32 +1866,32 @@ { case ARRAY_TYPE: { - bool not_lvalue = false; - bool lvalue_array_p; - - while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR - || CONVERT_EXPR_P (exp.value)) - && TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type) - { - if (TREE_CODE (exp.value) == NON_LVALUE_EXPR) - not_lvalue = true; - exp.value = TREE_OPERAND (exp.value, 0); - } - - if (TREE_NO_WARNING (orig_exp)) - TREE_NO_WARNING (exp.value) = 1; - - lvalue_array_p = !not_lvalue && lvalue_p (exp.value); - if (!flag_isoc99 && !lvalue_array_p) - { - /* Before C99, non-lvalue arrays do not decay to pointers. - Normally, using such an array would be invalid; but it can - be used correctly inside sizeof or as a statement expression. - Thus, do not give an error here; an error will result later. */ - return exp; - } - - exp.value = array_to_pointer_conversion (loc, exp.value); + bool not_lvalue = false; + bool lvalue_array_p; + + while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR + || CONVERT_EXPR_P (exp.value)) + && TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type) + { + if (TREE_CODE (exp.value) == NON_LVALUE_EXPR) + not_lvalue = true; + exp.value = TREE_OPERAND (exp.value, 0); + } + + if (TREE_NO_WARNING (orig_exp)) + TREE_NO_WARNING (exp.value) = 1; + + lvalue_array_p = !not_lvalue && lvalue_p (exp.value); + if (!flag_isoc99 && !lvalue_array_p) + { + /* Before C99, non-lvalue arrays do not decay to pointers. + Normally, using such an array would be invalid; but it can + be used correctly inside sizeof or as a statement expression. + Thus, do not give an error here; an error will result later. */ + return exp; + } + + exp.value = array_to_pointer_conversion (loc, exp.value); } break; case FUNCTION_TYPE: @@ -1909,10 +1927,10 @@ if (code == ENUMERAL_TYPE) { type = c_common_type_for_size (MAX (TYPE_PRECISION (type), - TYPE_PRECISION (integer_type_node)), - ((TYPE_PRECISION (type) - >= TYPE_PRECISION (integer_type_node)) - && TYPE_UNSIGNED (type))); + TYPE_PRECISION (integer_type_node)), + ((TYPE_PRECISION (type) + >= TYPE_PRECISION (integer_type_node)) + && TYPE_UNSIGNED (type))); return convert (type, exp); } @@ -1922,17 +1940,17 @@ if (TREE_CODE (exp) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)) /* If it's thinner than an int, promote it like a - c_promoting_integer_type_p, otherwise leave it alone. */ + c_promoting_integer_type_p, otherwise leave it alone. */ && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)), - TYPE_PRECISION (integer_type_node))) + TYPE_PRECISION (integer_type_node))) return convert (integer_type_node, exp); if (c_promoting_integer_type_p (type)) { /* Preserve unsignedness if not really getting any wider. */ if (TYPE_UNSIGNED (type) - && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - return convert (unsigned_type_node, exp); + && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) + return convert (unsigned_type_node, exp); return convert (integer_type_node, exp); } @@ -2067,9 +2085,9 @@ } if (DECL_NAME (field_array[bot]) == component) - field = field_array[bot]; + field = field_array[bot]; else if (DECL_NAME (field) != component) - return NULL_TREE; + return NULL_TREE; } else { @@ -2100,7 +2118,7 @@ } if (field == NULL_TREE) - return NULL_TREE; + return NULL_TREE; } return tree_cons (NULL_TREE, field, NULL_TREE); @@ -2132,71 +2150,71 @@ if (code == RECORD_TYPE || code == UNION_TYPE) { if (!COMPLETE_TYPE_P (type)) - { - c_incomplete_type_error (NULL_TREE, type); - return error_mark_node; - } + { + c_incomplete_type_error (NULL_TREE, type); + return error_mark_node; + } field = lookup_field (type, component); if (!field) - { - error_at (loc, "%qT has no member named %qE", type, component); - return error_mark_node; - } + { + error_at (loc, "%qT has no member named %qE", type, component); + return error_mark_node; + } /* Chain the COMPONENT_REFs if necessary down to the FIELD. - This might be better solved in future the way the C++ front - end does it - by giving the anonymous entities each a - separate name and type, and then have build_component_ref - recursively call itself. We can't do that here. */ + This might be better solved in future the way the C++ front + end does it - by giving the anonymous entities each a + separate name and type, and then have build_component_ref + recursively call itself. We can't do that here. */ do - { - tree subdatum = TREE_VALUE (field); - int quals; - tree subtype; - bool use_datum_quals; - - if (TREE_TYPE (subdatum) == error_mark_node) - return error_mark_node; - - /* If this is an rvalue, it does not have qualifiers in C - standard terms and we must avoid propagating such - qualifiers down to a non-lvalue array that is then - converted to a pointer. */ - use_datum_quals = (datum_lvalue - || TREE_CODE (TREE_TYPE (subdatum)) != ARRAY_TYPE); - - quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum))); - if (use_datum_quals) - quals |= TYPE_QUALS (TREE_TYPE (datum)); - subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals); - - ref = build3 (COMPONENT_REF, subtype, datum, subdatum, - NULL_TREE); - SET_EXPR_LOCATION (ref, loc); - if (TREE_READONLY (subdatum) - || (use_datum_quals && TREE_READONLY (datum))) - TREE_READONLY (ref) = 1; - if (TREE_THIS_VOLATILE (subdatum) - || (use_datum_quals && TREE_THIS_VOLATILE (datum))) - TREE_THIS_VOLATILE (ref) = 1; - - if (TREE_DEPRECATED (subdatum)) - warn_deprecated_use (subdatum, NULL_TREE); - - datum = ref; - - field = TREE_CHAIN (field); - } + { + tree subdatum = TREE_VALUE (field); + int quals; + tree subtype; + bool use_datum_quals; + + if (TREE_TYPE (subdatum) == error_mark_node) + return error_mark_node; + + /* If this is an rvalue, it does not have qualifiers in C + standard terms and we must avoid propagating such + qualifiers down to a non-lvalue array that is then + converted to a pointer. */ + use_datum_quals = (datum_lvalue + || TREE_CODE (TREE_TYPE (subdatum)) != ARRAY_TYPE); + + quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum))); + if (use_datum_quals) + quals |= TYPE_QUALS (TREE_TYPE (datum)); + subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals); + + ref = build3 (COMPONENT_REF, subtype, datum, subdatum, + NULL_TREE); + SET_EXPR_LOCATION (ref, loc); + if (TREE_READONLY (subdatum) + || (use_datum_quals && TREE_READONLY (datum))) + TREE_READONLY (ref) = 1; + if (TREE_THIS_VOLATILE (subdatum) + || (use_datum_quals && TREE_THIS_VOLATILE (datum))) + TREE_THIS_VOLATILE (ref) = 1; + + if (TREE_DEPRECATED (subdatum)) + warn_deprecated_use (subdatum, NULL_TREE); + + datum = ref; + + field = TREE_CHAIN (field); + } while (field); return ref; } else if (code != ERROR_MARK) error_at (loc, - "request for member %qE in something not a structure or union", - component); + "request for member %qE in something not a structure or union", + component); return error_mark_node; } @@ -2218,52 +2236,52 @@ { if (CONVERT_EXPR_P (pointer) || TREE_CODE (pointer) == VIEW_CONVERT_EXPR) - { - /* If a warning is issued, mark it to avoid duplicates from - the backend. This only needs to be done at - warn_strict_aliasing > 2. */ - if (warn_strict_aliasing > 2) - if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)), - type, TREE_OPERAND (pointer, 0))) - TREE_NO_WARNING (pointer) = 1; - } + { + /* If a warning is issued, mark it to avoid duplicates from + the backend. This only needs to be done at + warn_strict_aliasing > 2. */ + if (warn_strict_aliasing > 2) + if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)), + type, TREE_OPERAND (pointer, 0))) + TREE_NO_WARNING (pointer) = 1; + } if (TREE_CODE (pointer) == ADDR_EXPR - && (TREE_TYPE (TREE_OPERAND (pointer, 0)) - == TREE_TYPE (type))) - { - ref = TREE_OPERAND (pointer, 0); - protected_set_expr_location (ref, loc); - return ref; - } + && (TREE_TYPE (TREE_OPERAND (pointer, 0)) + == TREE_TYPE (type))) + { + ref = TREE_OPERAND (pointer, 0); + protected_set_expr_location (ref, loc); + return ref; + } else - { - tree t = TREE_TYPE (type); - - ref = build1 (INDIRECT_REF, t, pointer); - - if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE) - { - error_at (loc, "dereferencing pointer to incomplete type"); - return error_mark_node; - } - if (VOID_TYPE_P (t) && c_inhibit_evaluation_warnings == 0) - warning_at (loc, 0, "dereferencing % pointer"); - - /* We *must* set TREE_READONLY when dereferencing a pointer to const, - so that we get the proper error message if the result is used - to assign to. Also, &* is supposed to be a no-op. - And ANSI C seems to specify that the type of the result - should be the const type. */ - /* A de-reference of a pointer to const is not a const. It is valid - to change it via some other pointer. */ - TREE_READONLY (ref) = TYPE_READONLY (t); - TREE_SIDE_EFFECTS (ref) - = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer); - TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); - protected_set_expr_location (ref, loc); - return ref; - } + { + tree t = TREE_TYPE (type); + + ref = build1 (INDIRECT_REF, t, pointer); + + if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE) + { + error_at (loc, "dereferencing pointer to incomplete type"); + return error_mark_node; + } + if (VOID_TYPE_P (t) && c_inhibit_evaluation_warnings == 0) + warning_at (loc, 0, "dereferencing % pointer"); + + /* We *must* set TREE_READONLY when dereferencing a pointer to const, + so that we get the proper error message if the result is used + to assign to. Also, &* is supposed to be a no-op. + And ANSI C seems to specify that the type of the result + should be the const type. */ + /* A de-reference of a pointer to const is not a const. It is valid + to change it via some other pointer. */ + TREE_READONLY (ref) = TYPE_READONLY (t); + TREE_SIDE_EFFECTS (ref) + = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer); + TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); + protected_set_expr_location (ref, loc); + return ref; + } } else if (TREE_CODE (pointer) != ERROR_MARK) invalid_indirection_error (loc, type, errstring); @@ -2362,58 +2380,58 @@ tree rval, type; /* An array that is indexed by a non-constant - cannot be stored in a register; we must be able to do - address arithmetic on its address. - Likewise an array of elements of variable size. */ + cannot be stored in a register; we must be able to do + address arithmetic on its address. + Likewise an array of elements of variable size. */ if (TREE_CODE (index) != INTEGER_CST - || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array))) - && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) - { - if (!c_mark_addressable (array)) - return error_mark_node; - } + || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array))) + && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) + { + if (!c_mark_addressable (array)) + return error_mark_node; + } /* An array that is indexed by a constant value which is not within - the array bounds cannot be stored in a register either; because we - would get a crash in store_bit_field/extract_bit_field when trying - to access a non-existent part of the register. */ + the array bounds cannot be stored in a register either; because we + would get a crash in store_bit_field/extract_bit_field when trying + to access a non-existent part of the register. */ if (TREE_CODE (index) == INTEGER_CST - && TYPE_DOMAIN (TREE_TYPE (array)) - && !int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array)))) - { - if (!c_mark_addressable (array)) - return error_mark_node; - } + && TYPE_DOMAIN (TREE_TYPE (array)) + && !int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array)))) + { + if (!c_mark_addressable (array)) + return error_mark_node; + } if (pedantic) - { - tree foo = array; - while (TREE_CODE (foo) == COMPONENT_REF) - foo = TREE_OPERAND (foo, 0); - if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo)) - pedwarn (loc, OPT_pedantic, - "ISO C forbids subscripting % array"); - else if (!flag_isoc99 && !lvalue_p (foo)) - pedwarn (loc, OPT_pedantic, - "ISO C90 forbids subscripting non-lvalue array"); - } + { + tree foo = array; + while (TREE_CODE (foo) == COMPONENT_REF) + foo = TREE_OPERAND (foo, 0); + if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo)) + pedwarn (loc, OPT_pedantic, + "ISO C forbids subscripting % array"); + else if (!flag_isoc99 && !lvalue_p (foo)) + pedwarn (loc, OPT_pedantic, + "ISO C90 forbids subscripting non-lvalue array"); + } type = TREE_TYPE (TREE_TYPE (array)); rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE); /* Array ref is const/volatile if the array elements are - or if the array is. */ + or if the array is. */ TREE_READONLY (rval) - |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array))) - | TREE_READONLY (array)); + |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array))) + | TREE_READONLY (array)); TREE_SIDE_EFFECTS (rval) - |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) - | TREE_SIDE_EFFECTS (array)); + |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) + | TREE_SIDE_EFFECTS (array)); TREE_THIS_VOLATILE (rval) - |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) - /* This was added by rms on 16 Nov 91. - It fixes vol struct foo *a; a->elts[1] - in an inline function. - Hope it doesn't break something else. */ - | TREE_THIS_VOLATILE (array)); + |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) + /* This was added by rms on 16 Nov 91. + It fixes vol struct foo *a; a->elts[1] + in an inline function. + Hope it doesn't break something else. */ + | TREE_THIS_VOLATILE (array)); ret = require_complete_type (rval); protected_set_expr_location (ret, loc); return ret; @@ -2423,14 +2441,14 @@ tree ar = default_conversion (array); if (ar == error_mark_node) - return ar; + return ar; gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE); gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE); return build_indirect_ref - (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0), - RO_ARRAY_INDEXING); + (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0), + RO_ARRAY_INDEXING); } } @@ -2458,7 +2476,11 @@ } else if (fun) /* Implicit function declaration. */ +#ifndef noCbC + ref = implicitly_declare (loc, id, fun); +#else ref = implicitly_declare (loc, id); +#endif else if (decl == error_mark_node) /* Don't complain about something that's already been complained about. */ @@ -2484,11 +2506,11 @@ if (TREE_CODE (ref) == FUNCTION_DECL && !in_alignof) { if (!in_sizeof && !in_typeof) - C_DECL_USED (ref) = 1; + C_DECL_USED (ref) = 1; else if (DECL_INITIAL (ref) == 0 - && DECL_EXTERNAL (ref) - && !TREE_PUBLIC (ref)) - record_maybe_used_decl (ref); + && DECL_EXTERNAL (ref) + && !TREE_PUBLIC (ref)) + record_maybe_used_decl (ref); } if (TREE_CODE (ref) == CONST_DECL) @@ -2496,41 +2518,41 @@ used_types_insert (TREE_TYPE (ref)); if (warn_cxx_compat - && TREE_CODE (TREE_TYPE (ref)) == ENUMERAL_TYPE - && C_TYPE_DEFINED_IN_STRUCT (TREE_TYPE (ref))) - { - warning_at (loc, OPT_Wc___compat, - ("enum constant defined in struct or union " - "is not visible in C++")); - inform (DECL_SOURCE_LOCATION (ref), "enum constant defined here"); - } + && TREE_CODE (TREE_TYPE (ref)) == ENUMERAL_TYPE + && C_TYPE_DEFINED_IN_STRUCT (TREE_TYPE (ref))) + { + warning_at (loc, OPT_Wc___compat, + ("enum constant defined in struct or union " + "is not visible in C++")); + inform (DECL_SOURCE_LOCATION (ref), "enum constant defined here"); + } ref = DECL_INITIAL (ref); TREE_CONSTANT (ref) = 1; } else if (current_function_decl != 0 - && !DECL_FILE_SCOPE_P (current_function_decl) - && (TREE_CODE (ref) == VAR_DECL - || TREE_CODE (ref) == PARM_DECL - || TREE_CODE (ref) == FUNCTION_DECL)) + && !DECL_FILE_SCOPE_P (current_function_decl) + && (TREE_CODE (ref) == VAR_DECL + || TREE_CODE (ref) == PARM_DECL + || TREE_CODE (ref) == FUNCTION_DECL)) { tree context = decl_function_context (ref); if (context != 0 && context != current_function_decl) - DECL_NONLOCAL (ref) = 1; + DECL_NONLOCAL (ref) = 1; } /* C99 6.7.4p3: An inline definition of a function with external linkage ... shall not contain a reference to an identifier with internal linkage. */ else if (current_function_decl != 0 - && DECL_DECLARED_INLINE_P (current_function_decl) - && DECL_EXTERNAL (current_function_decl) - && VAR_OR_FUNCTION_DECL_P (ref) - && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref)) - && ! TREE_PUBLIC (ref) - && DECL_CONTEXT (ref) != current_function_decl) + && DECL_DECLARED_INLINE_P (current_function_decl) + && DECL_EXTERNAL (current_function_decl) + && VAR_OR_FUNCTION_DECL_P (ref) + && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref)) + && ! TREE_PUBLIC (ref) + && DECL_CONTEXT (ref) != current_function_decl) record_inline_static (loc, current_function_decl, ref, - csi_internal); + csi_internal); return ref; } @@ -2576,12 +2598,12 @@ while (p && p->level > cur_level) { if (used) - { - if (cur_level == 0) - C_DECL_USED (p->decl) = 1; - else - p->level = cur_level; - } + { + if (cur_level == 0) + C_DECL_USED (p->decl) = 1; + else + p->level = cur_level; + } p = p->next; } if (!used || cur_level == 0) @@ -2605,18 +2627,18 @@ { bool expr_const_operands = true; tree folded_expr = c_fully_fold (expr.value, require_constant_value, - &expr_const_operands); + &expr_const_operands); ret.value = c_sizeof (loc, TREE_TYPE (folded_expr)); ret.original_code = ERROR_MARK; ret.original_type = NULL; if (c_vla_type_p (TREE_TYPE (folded_expr))) - { - /* sizeof is evaluated when given a vla (C99 6.5.3.4p2). */ - ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value), - folded_expr, ret.value); - C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands; - SET_EXPR_LOCATION (ret.value, loc); - } + { + /* sizeof is evaluated when given a vla (C99 6.5.3.4p2). */ + ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value), + folded_expr, ret.value); + C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands; + SET_EXPR_LOCATION (ret.value, loc); + } pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr))); } return ret; @@ -2641,20 +2663,20 @@ && c_vla_type_p (type)) { /* If the type is a [*] array, it is a VLA but is represented as - having a size of zero. In such a case we must ensure that - the result of sizeof does not get folded to a constant by - c_fully_fold, because if the size is evaluated the result is - not constant and so constraints on zero or negative size - arrays must not be applied when this sizeof call is inside - another array declarator. */ + having a size of zero. In such a case we must ensure that + the result of sizeof does not get folded to a constant by + c_fully_fold, because if the size is evaluated the result is + not constant and so constraints on zero or negative size + arrays must not be applied when this sizeof call is inside + another array declarator. */ if (!type_expr) - type_expr = integer_zero_node; + type_expr = integer_zero_node; ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value), - type_expr, ret.value); + type_expr, ret.value); C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !type_expr_const; } pop_maybe_used (type != error_mark_node - ? C_TYPE_VARIABLE_SIZE (type) : false); + ? C_TYPE_VARIABLE_SIZE (type) : false); return ret; } @@ -2688,7 +2710,7 @@ tree build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params, - VEC(tree,gc) *origtypes) + VEC(tree,gc) *origtypes) { tree fntype, fundecl = 0; tree name = NULL_TREE, result; @@ -2704,12 +2726,12 @@ if (TREE_CODE (function) == FUNCTION_DECL) { /* Implement type-directed function overloading for builtins. - resolve_overloaded_builtin and targetm.resolve_overloaded_builtin - handle all the type checking. The result is a complete expression - that implements this function call. */ + resolve_overloaded_builtin and targetm.resolve_overloaded_builtin + handle all the type checking. The result is a complete expression + that implements this function call. */ tem = resolve_overloaded_builtin (loc, function, params); if (tem) - return tem; + return tem; name = DECL_NAME (function); fundecl = function; @@ -2721,7 +2743,7 @@ expressions, like those used for ObjC messenger dispatches. */ if (!VEC_empty (tree, params)) function = objc_rewrite_function_call (function, - VEC_index (tree, params, 0)); + VEC_index (tree, params, 0)); function = c_fully_fold (function, false, NULL); @@ -2731,7 +2753,7 @@ return error_mark_node; if (!(TREE_CODE (fntype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) + && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) { error_at (loc, "called object %qE is not a function", function); return error_mark_node; @@ -2747,7 +2769,7 @@ function prototype, or apply default promotions. */ nargs = convert_arguments (TYPE_ARG_TYPES (fntype), params, origtypes, - function, fundecl); + function, fundecl); if (nargs < 0) return error_mark_node; @@ -2763,29 +2785,29 @@ { tree return_type = TREE_TYPE (fntype); tree trap = build_function_call (loc, built_in_decls[BUILT_IN_TRAP], - NULL_TREE); + NULL_TREE); int i; /* This situation leads to run-time undefined behavior. We can't, - therefore, simply error unless we can prove that all possible - executions of the program must execute the code. */ + therefore, simply error unless we can prove that all possible + executions of the program must execute the code. */ if (warning_at (loc, 0, "function called through a non-compatible type")) - /* We can, however, treat "undefined" any way we please. - Call abort to encourage the user to fix the program. */ - inform (loc, "if this code is reached, the program will abort"); + /* We can, however, treat "undefined" any way we please. + Call abort to encourage the user to fix the program. */ + inform (loc, "if this code is reached, the program will abort"); /* Before the abort, allow the function arguments to exit or - call longjmp. */ + call longjmp. */ for (i = 0; i < nargs; i++) - trap = build2 (COMPOUND_EXPR, void_type_node, - VEC_index (tree, params, i), trap); + trap = build2 (COMPOUND_EXPR, void_type_node, + VEC_index (tree, params, i), trap); if (VOID_TYPE_P (return_type)) - { - if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED) - pedwarn (loc, 0, - "function with qualified void return type called"); - return trap; - } + { + if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED) + pedwarn (loc, 0, + "function with qualified void return type called"); + return trap; + } else { tree rhs; @@ -2813,31 +2835,31 @@ /* Check that the arguments to the function are valid. */ check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray, - TYPE_ARG_TYPES (fntype)); + TYPE_ARG_TYPES (fntype)); if (name != NULL_TREE && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10)) { if (require_constant_value) - result = - fold_build_call_array_initializer_loc (loc, TREE_TYPE (fntype), - function, nargs, argarray); + result = + fold_build_call_array_initializer_loc (loc, TREE_TYPE (fntype), + function, nargs, argarray); else - result = fold_build_call_array_loc (loc, TREE_TYPE (fntype), - function, nargs, argarray); + result = fold_build_call_array_loc (loc, TREE_TYPE (fntype), + function, nargs, argarray); if (TREE_CODE (result) == NOP_EXPR - && TREE_CODE (TREE_OPERAND (result, 0)) == INTEGER_CST) - STRIP_TYPE_NOPS (result); + && TREE_CODE (TREE_OPERAND (result, 0)) == INTEGER_CST) + STRIP_TYPE_NOPS (result); } else result = build_call_array_loc (loc, TREE_TYPE (fntype), - function, nargs, argarray); + function, nargs, argarray); if (VOID_TYPE_P (TREE_TYPE (result))) { if (TYPE_QUALS (TREE_TYPE (result)) != TYPE_UNQUALIFIED) - pedwarn (loc, 0, - "function with qualified void return type called"); + pedwarn (loc, 0, + "function with qualified void return type called"); return result; } return require_complete_type (result); @@ -2864,7 +2886,7 @@ static int convert_arguments (tree typelist, VEC(tree,gc) *values, - VEC(tree,gc) *origtypes, tree function, tree fundecl) + VEC(tree,gc) *origtypes, tree function, tree fundecl) { tree typetail, val; unsigned int parmnum; @@ -2891,20 +2913,20 @@ && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL) { switch (DECL_FUNCTION_CODE (fundecl)) - { - case BUILT_IN_ISFINITE: - case BUILT_IN_ISINF: - case BUILT_IN_ISINF_SIGN: - case BUILT_IN_ISNAN: - case BUILT_IN_ISNORMAL: - case BUILT_IN_FPCLASSIFY: - type_generic_remove_excess_precision = true; - break; - - default: - type_generic_remove_excess_precision = false; - break; - } + { + case BUILT_IN_ISFINITE: + case BUILT_IN_ISINF: + case BUILT_IN_ISINF_SIGN: + case BUILT_IN_ISNAN: + case BUILT_IN_ISNORMAL: + case BUILT_IN_FPCLASSIFY: + type_generic_remove_excess_precision = true; + break; + + default: + type_generic_remove_excess_precision = false; + break; + } } /* Scan the given expressions and types, producing individual @@ -2938,188 +2960,188 @@ } if (selector && argnum > 2) - { - rname = selector; - argnum -= 2; - } + { + rname = selector; + argnum -= 2; + } npc = null_pointer_constant_p (val); /* If there is excess precision and a prototype, convert once to - the required type rather than converting via the semantic - type. Likewise without a prototype a float value represented - as long double should be converted once to double. But for - type-generic classification functions excess precision must - be removed here. */ + the required type rather than converting via the semantic + type. Likewise without a prototype a float value represented + as long double should be converted once to double. But for + type-generic classification functions excess precision must + be removed here. */ if (TREE_CODE (val) == EXCESS_PRECISION_EXPR - && (type || !type_generic || !type_generic_remove_excess_precision)) - { - val = TREE_OPERAND (val, 0); - excess_precision = true; - } + && (type || !type_generic || !type_generic_remove_excess_precision)) + { + val = TREE_OPERAND (val, 0); + excess_precision = true; + } val = c_fully_fold (val, false, NULL); STRIP_TYPE_NOPS (val); val = require_complete_type (val); if (type != 0) - { - /* Formal parm type is specified by a function prototype. */ - - if (type == error_mark_node || !COMPLETE_TYPE_P (type)) - { - error ("type of formal parameter %d is incomplete", parmnum + 1); - parmval = val; - } - else - { - tree origtype; - - /* Optionally warn about conversions that - differ from the default conversions. */ - if (warn_traditional_conversion || warn_traditional) - { - unsigned int formal_prec = TYPE_PRECISION (type); - - if (INTEGRAL_TYPE_P (type) - && TREE_CODE (valtype) == REAL_TYPE) - warning (0, "passing argument %d of %qE as integer " - "rather than floating due to prototype", - argnum, rname); - if (INTEGRAL_TYPE_P (type) - && TREE_CODE (valtype) == COMPLEX_TYPE) - warning (0, "passing argument %d of %qE as integer " - "rather than complex due to prototype", - argnum, rname); - else if (TREE_CODE (type) == COMPLEX_TYPE - && TREE_CODE (valtype) == REAL_TYPE) - warning (0, "passing argument %d of %qE as complex " - "rather than floating due to prototype", - argnum, rname); - else if (TREE_CODE (type) == REAL_TYPE - && INTEGRAL_TYPE_P (valtype)) - warning (0, "passing argument %d of %qE as floating " - "rather than integer due to prototype", - argnum, rname); - else if (TREE_CODE (type) == COMPLEX_TYPE - && INTEGRAL_TYPE_P (valtype)) - warning (0, "passing argument %d of %qE as complex " - "rather than integer due to prototype", - argnum, rname); - else if (TREE_CODE (type) == REAL_TYPE - && TREE_CODE (valtype) == COMPLEX_TYPE) - warning (0, "passing argument %d of %qE as floating " - "rather than complex due to prototype", - argnum, rname); - /* ??? At some point, messages should be written about - conversions between complex types, but that's too messy - to do now. */ - else if (TREE_CODE (type) == REAL_TYPE - && TREE_CODE (valtype) == REAL_TYPE) - { - /* Warn if any argument is passed as `float', - since without a prototype it would be `double'. */ - if (formal_prec == TYPE_PRECISION (float_type_node) - && type != dfloat32_type_node) - warning (0, "passing argument %d of %qE as % " - "rather than % due to prototype", - argnum, rname); - - /* Warn if mismatch between argument and prototype - for decimal float types. Warn of conversions with - binary float types and of precision narrowing due to - prototype. */ - else if (type != valtype - && (type == dfloat32_type_node - || type == dfloat64_type_node - || type == dfloat128_type_node - || valtype == dfloat32_type_node - || valtype == dfloat64_type_node - || valtype == dfloat128_type_node) - && (formal_prec - <= TYPE_PRECISION (valtype) - || (type == dfloat128_type_node - && (valtype - != dfloat64_type_node - && (valtype - != dfloat32_type_node))) - || (type == dfloat64_type_node - && (valtype - != dfloat32_type_node)))) - warning (0, "passing argument %d of %qE as %qT " - "rather than %qT due to prototype", - argnum, rname, type, valtype); - - } - /* Detect integer changing in width or signedness. - These warnings are only activated with - -Wtraditional-conversion, not with -Wtraditional. */ - else if (warn_traditional_conversion && INTEGRAL_TYPE_P (type) - && INTEGRAL_TYPE_P (valtype)) - { - tree would_have_been = default_conversion (val); - tree type1 = TREE_TYPE (would_have_been); - - if (TREE_CODE (type) == ENUMERAL_TYPE - && (TYPE_MAIN_VARIANT (type) - == TYPE_MAIN_VARIANT (valtype))) - /* No warning if function asks for enum - and the actual arg is that enum type. */ - ; - else if (formal_prec != TYPE_PRECISION (type1)) - warning (OPT_Wtraditional_conversion, - "passing argument %d of %qE " - "with different width due to prototype", - argnum, rname); - else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1)) - ; - /* Don't complain if the formal parameter type - is an enum, because we can't tell now whether - the value was an enum--even the same enum. */ - else if (TREE_CODE (type) == ENUMERAL_TYPE) - ; - else if (TREE_CODE (val) == INTEGER_CST - && int_fits_type_p (val, type)) - /* Change in signedness doesn't matter - if a constant value is unaffected. */ - ; - /* If the value is extended from a narrower - unsigned type, it doesn't matter whether we - pass it as signed or unsigned; the value - certainly is the same either way. */ - else if (TYPE_PRECISION (valtype) < TYPE_PRECISION (type) - && TYPE_UNSIGNED (valtype)) - ; - else if (TYPE_UNSIGNED (type)) - warning (OPT_Wtraditional_conversion, - "passing argument %d of %qE " - "as unsigned due to prototype", - argnum, rname); - else - warning (OPT_Wtraditional_conversion, - "passing argument %d of %qE " - "as signed due to prototype", argnum, rname); - } - } - - /* Possibly restore an EXCESS_PRECISION_EXPR for the - sake of better warnings from convert_and_check. */ - if (excess_precision) - val = build1 (EXCESS_PRECISION_EXPR, valtype, val); - origtype = (origtypes == NULL - ? NULL_TREE - : VEC_index (tree, origtypes, parmnum)); - parmval = convert_for_assignment (input_location, type, val, - origtype, ic_argpass, npc, - fundecl, function, - parmnum + 1); - - if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0) - && INTEGRAL_TYPE_P (type) - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - parmval = default_conversion (parmval); - } - } + { + /* Formal parm type is specified by a function prototype. */ + + if (type == error_mark_node || !COMPLETE_TYPE_P (type)) + { + error ("type of formal parameter %d is incomplete", parmnum + 1); + parmval = val; + } + else + { + tree origtype; + + /* Optionally warn about conversions that + differ from the default conversions. */ + if (warn_traditional_conversion || warn_traditional) + { + unsigned int formal_prec = TYPE_PRECISION (type); + + if (INTEGRAL_TYPE_P (type) + && TREE_CODE (valtype) == REAL_TYPE) + warning (0, "passing argument %d of %qE as integer " + "rather than floating due to prototype", + argnum, rname); + if (INTEGRAL_TYPE_P (type) + && TREE_CODE (valtype) == COMPLEX_TYPE) + warning (0, "passing argument %d of %qE as integer " + "rather than complex due to prototype", + argnum, rname); + else if (TREE_CODE (type) == COMPLEX_TYPE + && TREE_CODE (valtype) == REAL_TYPE) + warning (0, "passing argument %d of %qE as complex " + "rather than floating due to prototype", + argnum, rname); + else if (TREE_CODE (type) == REAL_TYPE + && INTEGRAL_TYPE_P (valtype)) + warning (0, "passing argument %d of %qE as floating " + "rather than integer due to prototype", + argnum, rname); + else if (TREE_CODE (type) == COMPLEX_TYPE + && INTEGRAL_TYPE_P (valtype)) + warning (0, "passing argument %d of %qE as complex " + "rather than integer due to prototype", + argnum, rname); + else if (TREE_CODE (type) == REAL_TYPE + && TREE_CODE (valtype) == COMPLEX_TYPE) + warning (0, "passing argument %d of %qE as floating " + "rather than complex due to prototype", + argnum, rname); + /* ??? At some point, messages should be written about + conversions between complex types, but that's too messy + to do now. */ + else if (TREE_CODE (type) == REAL_TYPE + && TREE_CODE (valtype) == REAL_TYPE) + { + /* Warn if any argument is passed as `float', + since without a prototype it would be `double'. */ + if (formal_prec == TYPE_PRECISION (float_type_node) + && type != dfloat32_type_node) + warning (0, "passing argument %d of %qE as % " + "rather than % due to prototype", + argnum, rname); + + /* Warn if mismatch between argument and prototype + for decimal float types. Warn of conversions with + binary float types and of precision narrowing due to + prototype. */ + else if (type != valtype + && (type == dfloat32_type_node + || type == dfloat64_type_node + || type == dfloat128_type_node + || valtype == dfloat32_type_node + || valtype == dfloat64_type_node + || valtype == dfloat128_type_node) + && (formal_prec + <= TYPE_PRECISION (valtype) + || (type == dfloat128_type_node + && (valtype + != dfloat64_type_node + && (valtype + != dfloat32_type_node))) + || (type == dfloat64_type_node + && (valtype + != dfloat32_type_node)))) + warning (0, "passing argument %d of %qE as %qT " + "rather than %qT due to prototype", + argnum, rname, type, valtype); + + } + /* Detect integer changing in width or signedness. + These warnings are only activated with + -Wtraditional-conversion, not with -Wtraditional. */ + else if (warn_traditional_conversion && INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (valtype)) + { + tree would_have_been = default_conversion (val); + tree type1 = TREE_TYPE (would_have_been); + + if (TREE_CODE (type) == ENUMERAL_TYPE + && (TYPE_MAIN_VARIANT (type) + == TYPE_MAIN_VARIANT (valtype))) + /* No warning if function asks for enum + and the actual arg is that enum type. */ + ; + else if (formal_prec != TYPE_PRECISION (type1)) + warning (OPT_Wtraditional_conversion, + "passing argument %d of %qE " + "with different width due to prototype", + argnum, rname); + else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1)) + ; + /* Don't complain if the formal parameter type + is an enum, because we can't tell now whether + the value was an enum--even the same enum. */ + else if (TREE_CODE (type) == ENUMERAL_TYPE) + ; + else if (TREE_CODE (val) == INTEGER_CST + && int_fits_type_p (val, type)) + /* Change in signedness doesn't matter + if a constant value is unaffected. */ + ; + /* If the value is extended from a narrower + unsigned type, it doesn't matter whether we + pass it as signed or unsigned; the value + certainly is the same either way. */ + else if (TYPE_PRECISION (valtype) < TYPE_PRECISION (type) + && TYPE_UNSIGNED (valtype)) + ; + else if (TYPE_UNSIGNED (type)) + warning (OPT_Wtraditional_conversion, + "passing argument %d of %qE " + "as unsigned due to prototype", + argnum, rname); + else + warning (OPT_Wtraditional_conversion, + "passing argument %d of %qE " + "as signed due to prototype", argnum, rname); + } + } + + /* Possibly restore an EXCESS_PRECISION_EXPR for the + sake of better warnings from convert_and_check. */ + if (excess_precision) + val = build1 (EXCESS_PRECISION_EXPR, valtype, val); + origtype = (origtypes == NULL + ? NULL_TREE + : VEC_index (tree, origtypes, parmnum)); + parmval = convert_for_assignment (input_location, type, val, + origtype, ic_argpass, npc, + fundecl, function, + parmnum + 1); + + if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0) + && INTEGRAL_TYPE_P (type) + && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) + parmval = default_conversion (parmval); + } + } else if (TREE_CODE (valtype) == REAL_TYPE && (TYPE_PRECISION (valtype) < TYPE_PRECISION (double_type_node)) @@ -3139,30 +3161,36 @@ } } else if (excess_precision && !type_generic) - /* A "double" argument with excess precision being passed - without a prototype or in variable arguments. */ - parmval = convert (valtype, val); + /* A "double" argument with excess precision being passed + without a prototype or in variable arguments. */ + parmval = convert (valtype, val); else if ((invalid_func_diag = - targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val))) - { - error (invalid_func_diag); - return -1; - } + targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val))) + { + error (invalid_func_diag); + return -1; + } else - /* Convert `short' and `char' to full-size `int'. */ - parmval = default_conversion (val); + /* Convert `short' and `char' to full-size `int'. */ + parmval = default_conversion (val); VEC_replace (tree, values, parmnum, parmval); if (parmval == error_mark_node) - error_args = true; + error_args = true; if (typetail) - typetail = TREE_CHAIN (typetail); + typetail = TREE_CHAIN (typetail); } gcc_assert (parmnum == VEC_length (tree, values)); +#ifndef noCbC + if (typetail != 0 && TREE_VALUE (typetail) != void_type_node + //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(fundecl)) ) + && !(fundecl&&CbC_IS_CODE_SEGMENT(fundecl)) ) +#else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) +#endif { error_at (input_location, "too few arguments to function %qE", function); @@ -3207,7 +3235,7 @@ struct c_expr parser_build_binary_op (location_t location, enum tree_code code, - struct c_expr arg1, struct c_expr arg2) + struct c_expr arg1, struct c_expr arg2) { struct c_expr result; @@ -3221,7 +3249,7 @@ : TREE_TYPE (arg2.value)); result.value = build_binary_op (location, code, - arg1.value, arg2.value, 1); + arg1.value, arg2.value, 1); result.original_code = code; result.original_type = NULL; @@ -3238,21 +3266,21 @@ if (warn_logical_op) warn_logical_operator (input_location, code, TREE_TYPE (result.value), - code1, arg1.value, code2, arg2.value); + code1, arg1.value, code2, arg2.value); /* Warn about comparisons against string literals, with the exception of testing for equality or inequality of a string literal with NULL. */ if (code == EQ_EXPR || code == NE_EXPR) { if ((code1 == STRING_CST && !integer_zerop (arg2.value)) - || (code2 == STRING_CST && !integer_zerop (arg1.value))) - warning_at (location, OPT_Waddress, - "comparison with string literal results in unspecified behavior"); + || (code2 == STRING_CST && !integer_zerop (arg1.value))) + warning_at (location, OPT_Waddress, + "comparison with string literal results in unspecified behavior"); } else if (TREE_CODE_CLASS (code) == tcc_comparison - && (code1 == STRING_CST || code2 == STRING_CST)) + && (code1 == STRING_CST || code2 == STRING_CST)) warning_at (location, OPT_Waddress, - "comparison with string literal results in unspecified behavior"); + "comparison with string literal results in unspecified behavior"); if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg1.value) @@ -3266,8 +3294,8 @@ && TREE_CODE (type2) == ENUMERAL_TYPE && TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2)) warning_at (location, OPT_Wenum_compare, - "comparison between %qT and %qT", - type1, type2); + "comparison between %qT and %qT", + type1, type2); return result; } @@ -3296,10 +3324,10 @@ tree common_type; /* Determine the common superset address space. This is guaranteed - to exist because the caller verified that comp_target_types - returned non-zero. */ + to exist because the caller verified that comp_target_types + returned non-zero. */ if (!addr_space_superset (as0, as1, &as_common)) - gcc_unreachable (); + gcc_unreachable (); common_type = common_pointer_type (TREE_TYPE (op0), TREE_TYPE (op1)); op0 = convert (common_type, op0); @@ -3311,17 +3339,17 @@ type if pointers for the address space are wider than ptrdiff_t. */ if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0))) inttype = lang_hooks.types.type_for_size - (TYPE_PRECISION (TREE_TYPE (op0)), 0); + (TYPE_PRECISION (TREE_TYPE (op0)), 0); else inttype = restype; if (TREE_CODE (target_type) == VOID_TYPE) pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, - "pointer of type % used in subtraction"); + "pointer of type % used in subtraction"); if (TREE_CODE (target_type) == FUNCTION_TYPE) pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, - "pointer to a function used in subtraction"); + "pointer to a function used in subtraction"); /* If the conversion to ptrdiff_type does anything like widening or converting a partial to an integral mode, we get a convert_expression @@ -3333,13 +3361,13 @@ at least the cases that occur in legal static initializers. */ if (CONVERT_EXPR_P (op0) && (TYPE_PRECISION (TREE_TYPE (op0)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))))) + == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))))) con0 = TREE_OPERAND (op0, 0); else con0 = op0; if (CONVERT_EXPR_P (op1) && (TYPE_PRECISION (TREE_TYPE (op1)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))))) + == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))))) con1 = TREE_OPERAND (op1, 0); else con1 = op1; @@ -3373,8 +3401,8 @@ in case restype is a short type. */ op0 = build_binary_op (loc, - MINUS_EXPR, convert (inttype, op0), - convert (inttype, op1), 0); + MINUS_EXPR, convert (inttype, op0), + convert (inttype, op1), 0); /* This generates an error if op1 is pointer to incomplete type. */ if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1)))) error_at (loc, "arithmetic on pointer to an incomplete type"); @@ -3384,7 +3412,7 @@ /* Divide by the size, in easiest possible way. */ result = fold_build2_loc (loc, EXACT_DIV_EXPR, inttype, - op0, convert (inttype, op1)); + op0, convert (inttype, op1)); /* Convert to final result type if necessary. */ return convert (restype, result); @@ -3403,7 +3431,7 @@ tree build_unary_op (location_t location, - enum tree_code code, tree xarg, int flag) + enum tree_code code, tree xarg, int flag) { /* No default_conversion here. It causes trouble for ADDR_EXPR. */ tree arg = xarg; @@ -3446,92 +3474,92 @@ { case CONVERT_EXPR: /* This is used for unary plus, because a CONVERT_EXPR - is enough to prevent anybody from looking inside for - associativity, but won't generate any code. */ + is enough to prevent anybody from looking inside for + associativity, but won't generate any code. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE - || typecode == VECTOR_TYPE)) - { - error_at (location, "wrong type argument to unary plus"); - return error_mark_node; - } + || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE + || typecode == VECTOR_TYPE)) + { + error_at (location, "wrong type argument to unary plus"); + return error_mark_node; + } else if (!noconvert) - arg = default_conversion (arg); + arg = default_conversion (arg); arg = non_lvalue_loc (location, arg); break; case NEGATE_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE - || typecode == VECTOR_TYPE)) - { - error_at (location, "wrong type argument to unary minus"); - return error_mark_node; - } + || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE + || typecode == VECTOR_TYPE)) + { + error_at (location, "wrong type argument to unary minus"); + return error_mark_node; + } else if (!noconvert) - arg = default_conversion (arg); + arg = default_conversion (arg); break; case BIT_NOT_EXPR: /* ~ works on integer types and non float vectors. */ if (typecode == INTEGER_TYPE - || (typecode == VECTOR_TYPE - && !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg)))) - { - if (!noconvert) - arg = default_conversion (arg); - } + || (typecode == VECTOR_TYPE + && !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg)))) + { + if (!noconvert) + arg = default_conversion (arg); + } else if (typecode == COMPLEX_TYPE) - { - code = CONJ_EXPR; - pedwarn (location, OPT_pedantic, - "ISO C does not support %<~%> for complex conjugation"); - if (!noconvert) - arg = default_conversion (arg); - } + { + code = CONJ_EXPR; + pedwarn (location, OPT_pedantic, + "ISO C does not support %<~%> for complex conjugation"); + if (!noconvert) + arg = default_conversion (arg); + } else - { - error_at (location, "wrong type argument to bit-complement"); - return error_mark_node; - } + { + error_at (location, "wrong type argument to bit-complement"); + return error_mark_node; + } break; case ABS_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) - { - error_at (location, "wrong type argument to abs"); - return error_mark_node; - } + { + error_at (location, "wrong type argument to abs"); + return error_mark_node; + } else if (!noconvert) - arg = default_conversion (arg); + arg = default_conversion (arg); break; case CONJ_EXPR: /* Conjugating a real value is a no-op, but allow it anyway. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) - { - error_at (location, "wrong type argument to conjugation"); - return error_mark_node; - } + || typecode == COMPLEX_TYPE)) + { + error_at (location, "wrong type argument to conjugation"); + return error_mark_node; + } else if (!noconvert) - arg = default_conversion (arg); + arg = default_conversion (arg); break; case TRUTH_NOT_EXPR: if (typecode != INTEGER_TYPE && typecode != FIXED_POINT_TYPE - && typecode != REAL_TYPE && typecode != POINTER_TYPE - && typecode != COMPLEX_TYPE) - { - error_at (location, - "wrong type argument to unary exclamation mark"); - return error_mark_node; - } + && typecode != REAL_TYPE && typecode != POINTER_TYPE + && typecode != COMPLEX_TYPE) + { + error_at (location, + "wrong type argument to unary exclamation mark"); + return error_mark_node; + } arg = c_objc_common_truthvalue_conversion (location, arg); ret = invert_truthvalue_loc (location, arg); /* If the TRUTH_NOT_EXPR has been folded, reset the location. */ if (EXPR_P (ret) && EXPR_HAS_LOCATION (ret)) - location = EXPR_LOCATION (ret); + location = EXPR_LOCATION (ret); goto return_build_unary_op; case REALPART_EXPR: @@ -3540,7 +3568,7 @@ if (ret == error_mark_node) return error_mark_node; if (eptype && TREE_CODE (eptype) == COMPLEX_TYPE) - eptype = TREE_TYPE (eptype); + eptype = TREE_TYPE (eptype); goto return_build_unary_op; case PREINCREMENT_EXPR: @@ -3549,17 +3577,17 @@ case POSTDECREMENT_EXPR: if (TREE_CODE (arg) == C_MAYBE_CONST_EXPR) - { - tree inner = build_unary_op (location, code, - C_MAYBE_CONST_EXPR_EXPR (arg), flag); - if (inner == error_mark_node) - return error_mark_node; - ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner), - C_MAYBE_CONST_EXPR_PRE (arg), inner); - gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg)); - C_MAYBE_CONST_EXPR_NON_CONST (ret) = 1; - goto return_build_unary_op; - } + { + tree inner = build_unary_op (location, code, + C_MAYBE_CONST_EXPR_EXPR (arg), flag); + if (inner == error_mark_node) + return error_mark_node; + ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner), + C_MAYBE_CONST_EXPR_PRE (arg), inner); + gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg)); + C_MAYBE_CONST_EXPR_NON_CONST (ret) = 1; + goto return_build_unary_op; + } /* Complain about anything that is not a true lvalue. In Objective-C, skip this check for property_refs. */ @@ -3572,50 +3600,50 @@ return error_mark_node; if (warn_cxx_compat && TREE_CODE (TREE_TYPE (arg)) == ENUMERAL_TYPE) - { - if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - warning_at (location, OPT_Wc___compat, - "increment of enumeration value is invalid in C++"); - else - warning_at (location, OPT_Wc___compat, - "decrement of enumeration value is invalid in C++"); - } + { + if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) + warning_at (location, OPT_Wc___compat, + "increment of enumeration value is invalid in C++"); + else + warning_at (location, OPT_Wc___compat, + "decrement of enumeration value is invalid in C++"); + } /* Ensure the argument is fully folded inside any SAVE_EXPR. */ arg = c_fully_fold (arg, false, NULL); /* Increment or decrement the real part of the value, - and don't change the imaginary part. */ + and don't change the imaginary part. */ if (typecode == COMPLEX_TYPE) - { - tree real, imag; - - pedwarn (location, OPT_pedantic, - "ISO C does not support %<++%> and %<--%> on complex types"); - - arg = stabilize_reference (arg); - real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1); - imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1); - real = build_unary_op (EXPR_LOCATION (arg), code, real, 1); - if (real == error_mark_node || imag == error_mark_node) - return error_mark_node; - ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg), - real, imag); - goto return_build_unary_op; - } + { + tree real, imag; + + pedwarn (location, OPT_pedantic, + "ISO C does not support %<++%> and %<--%> on complex types"); + + arg = stabilize_reference (arg); + real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1); + imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1); + real = build_unary_op (EXPR_LOCATION (arg), code, real, 1); + if (real == error_mark_node || imag == error_mark_node) + return error_mark_node; + ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg), + real, imag); + goto return_build_unary_op; + } /* Report invalid types. */ if (typecode != POINTER_TYPE && typecode != FIXED_POINT_TYPE - && typecode != INTEGER_TYPE && typecode != REAL_TYPE) - { - if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - error_at (location, "wrong type argument to increment"); - else - error_at (location, "wrong type argument to decrement"); - - return error_mark_node; - } + && typecode != INTEGER_TYPE && typecode != REAL_TYPE) + { + if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) + error_at (location, "wrong type argument to increment"); + else + error_at (location, "wrong type argument to decrement"); + + return error_mark_node; + } { tree inc; @@ -3713,57 +3741,57 @@ /* Note that this operation never does default_conversion. */ /* The operand of unary '&' must be an lvalue (which excludes - expressions of type void), or, in C99, the result of a [] or - unary '*' operator. */ + expressions of type void), or, in C99, the result of a [] or + unary '*' operator. */ if (VOID_TYPE_P (TREE_TYPE (arg)) - && TYPE_QUALS (TREE_TYPE (arg)) == TYPE_UNQUALIFIED - && (TREE_CODE (arg) != INDIRECT_REF - || !flag_isoc99)) - pedwarn (location, 0, "taking address of expression of type %"); + && TYPE_QUALS (TREE_TYPE (arg)) == TYPE_UNQUALIFIED + && (TREE_CODE (arg) != INDIRECT_REF + || !flag_isoc99)) + pedwarn (location, 0, "taking address of expression of type %"); /* Let &* cancel out to simplify resulting code. */ if (TREE_CODE (arg) == INDIRECT_REF) - { - /* Don't let this be an lvalue. */ - if (lvalue_p (TREE_OPERAND (arg, 0))) - return non_lvalue_loc (location, TREE_OPERAND (arg, 0)); - ret = TREE_OPERAND (arg, 0); - goto return_build_unary_op; - } + { + /* Don't let this be an lvalue. */ + if (lvalue_p (TREE_OPERAND (arg, 0))) + return non_lvalue_loc (location, TREE_OPERAND (arg, 0)); + ret = TREE_OPERAND (arg, 0); + goto return_build_unary_op; + } /* For &x[y], return x+y */ if (TREE_CODE (arg) == ARRAY_REF) - { - tree op0 = TREE_OPERAND (arg, 0); - if (!c_mark_addressable (op0)) - return error_mark_node; - return build_binary_op (location, PLUS_EXPR, - (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE - ? array_to_pointer_conversion (location, - op0) - : op0), - TREE_OPERAND (arg, 1), 1); - } + { + tree op0 = TREE_OPERAND (arg, 0); + if (!c_mark_addressable (op0)) + return error_mark_node; + return build_binary_op (location, PLUS_EXPR, + (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE + ? array_to_pointer_conversion (location, + op0) + : op0), + TREE_OPERAND (arg, 1), 1); + } /* Anything not already handled and not a true memory reference - or a non-lvalue array is an error. */ + or a non-lvalue array is an error. */ else if (typecode != FUNCTION_TYPE && !flag && !lvalue_or_else (location, arg, lv_addressof)) return error_mark_node; /* Move address operations inside C_MAYBE_CONST_EXPR to simplify - folding later. */ + folding later. */ if (TREE_CODE (arg) == C_MAYBE_CONST_EXPR) - { - tree inner = build_unary_op (location, code, - C_MAYBE_CONST_EXPR_EXPR (arg), flag); - ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner), - C_MAYBE_CONST_EXPR_PRE (arg), inner); - gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg)); - C_MAYBE_CONST_EXPR_NON_CONST (ret) - = C_MAYBE_CONST_EXPR_NON_CONST (arg); - goto return_build_unary_op; - } + { + tree inner = build_unary_op (location, code, + C_MAYBE_CONST_EXPR_EXPR (arg), flag); + ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner), + C_MAYBE_CONST_EXPR_PRE (arg), inner); + gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg)); + C_MAYBE_CONST_EXPR_NON_CONST (ret) + = C_MAYBE_CONST_EXPR_NON_CONST (arg); + goto return_build_unary_op; + } /* Ordinary case; arg is a COMPONENT_REF or a decl. */ argtype = TREE_TYPE (arg); @@ -3789,26 +3817,26 @@ } if (!c_mark_addressable (arg)) - return error_mark_node; + return error_mark_node; gcc_assert (TREE_CODE (arg) != COMPONENT_REF - || !DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1))); + || !DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1))); argtype = build_pointer_type (argtype); /* ??? Cope with user tricks that amount to offsetof. Delete this - when we have proper support for integer constant expressions. */ + when we have proper support for integer constant expressions. */ val = get_base_address (arg); if (val && TREE_CODE (val) == INDIRECT_REF && TREE_CONSTANT (TREE_OPERAND (val, 0))) - { - tree op0 = fold_convert_loc (location, sizetype, - fold_offsetof (arg, val)), op1; - - op1 = fold_convert_loc (location, argtype, TREE_OPERAND (val, 0)); - ret = fold_build2_loc (location, POINTER_PLUS_EXPR, argtype, op1, op0); - goto return_build_unary_op; - } + { + tree op0 = fold_convert_loc (location, sizetype, + fold_offsetof (arg, val)), op1; + + op1 = fold_convert_loc (location, argtype, TREE_OPERAND (val, 0)); + ret = fold_build2_loc (location, POINTER_PLUS_EXPR, argtype, op1, op0); + goto return_build_unary_op; + } val = build1 (ADDR_EXPR, argtype, arg); @@ -3823,8 +3851,8 @@ argtype = TREE_TYPE (arg); if (TREE_CODE (arg) == INTEGER_CST) ret = (require_constant_value - ? fold_build1_initializer_loc (location, code, argtype, arg) - : fold_build1_loc (location, code, argtype, arg)); + ? fold_build1_initializer_loc (location, code, argtype, arg) + : fold_build1_loc (location, code, argtype, arg)); else ret = build1 (code, argtype, arg); return_build_unary_op: @@ -3870,7 +3898,7 @@ case RESULT_DECL: case ERROR_MARK: return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE); + && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE); case BIND_EXPR: return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE; @@ -3879,7 +3907,7 @@ return 0; } } - + /* Give a warning for storing in something that is read-only in GCC terms but not const in ISO C terms. */ @@ -3933,57 +3961,57 @@ switch (TREE_CODE (x)) { case COMPONENT_REF: - if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) - { - error - ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); - return false; - } - - /* ... fall through ... */ + if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) + { + error + ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); + return false; + } + + /* ... fall through ... */ case ADDR_EXPR: case ARRAY_REF: case REALPART_EXPR: case IMAGPART_EXPR: - x = TREE_OPERAND (x, 0); - break; + x = TREE_OPERAND (x, 0); + break; case COMPOUND_LITERAL_EXPR: case CONSTRUCTOR: - TREE_ADDRESSABLE (x) = 1; - return true; + TREE_ADDRESSABLE (x) = 1; + return true; case VAR_DECL: case CONST_DECL: case PARM_DECL: case RESULT_DECL: - if (C_DECL_REGISTER (x) - && DECL_NONLOCAL (x)) - { - if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) - { - error - ("global register variable %qD used in nested function", x); - return false; - } - pedwarn (input_location, 0, "register variable %qD used in nested function", x); - } - else if (C_DECL_REGISTER (x)) - { - if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) - error ("address of global register variable %qD requested", x); - else - error ("address of register variable %qD requested", x); - return false; - } - - /* drops in */ + if (C_DECL_REGISTER (x) + && DECL_NONLOCAL (x)) + { + if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) + { + error + ("global register variable %qD used in nested function", x); + return false; + } + pedwarn (input_location, 0, "register variable %qD used in nested function", x); + } + else if (C_DECL_REGISTER (x)) + { + if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) + error ("address of global register variable %qD requested", x); + else + error ("address of register variable %qD requested", x); + return false; + } + + /* drops in */ case FUNCTION_DECL: - TREE_ADDRESSABLE (x) = 1; - /* drops out */ + TREE_ADDRESSABLE (x) = 1; + /* drops out */ default: - return true; + return true; } } @@ -4023,8 +4051,8 @@ tree build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, - tree op1, tree op1_original_type, tree op2, - tree op2_original_type) + tree op1, tree op1_original_type, tree op2, + tree op2_original_type) { tree type1; tree type2; @@ -4075,23 +4103,23 @@ if ((TREE_CODE (op1) == EXCESS_PRECISION_EXPR || TREE_CODE (op2) == EXCESS_PRECISION_EXPR) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE) + || code1 == COMPLEX_TYPE) && (code2 == INTEGER_TYPE || code2 == REAL_TYPE - || code2 == COMPLEX_TYPE)) + || code2 == COMPLEX_TYPE)) { semantic_result_type = c_common_type (type1, type2); if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR) - { - op1 = TREE_OPERAND (op1, 0); - type1 = TREE_TYPE (op1); - gcc_assert (TREE_CODE (type1) == code1); - } + { + op1 = TREE_OPERAND (op1, 0); + type1 = TREE_TYPE (op1); + gcc_assert (TREE_CODE (type1) == code1); + } if (TREE_CODE (op2) == EXCESS_PRECISION_EXPR) - { - op2 = TREE_OPERAND (op2, 0); - type2 = TREE_TYPE (op2); - gcc_assert (TREE_CODE (type2) == code2); - } + { + op2 = TREE_OPERAND (op2, 0); + type2 = TREE_TYPE (op2); + gcc_assert (TREE_CODE (type2) == code2); + } } if (warn_cxx_compat) @@ -4100,12 +4128,12 @@ tree t2 = op2_original_type ? op2_original_type : TREE_TYPE (orig_op2); if (TREE_CODE (t1) == ENUMERAL_TYPE - && TREE_CODE (t2) == ENUMERAL_TYPE - && TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2)) - warning_at (colon_loc, OPT_Wc___compat, - ("different enum types in conditional is " - "invalid in C++: %qT vs %qT"), - t1, t2); + && TREE_CODE (t2) == ENUMERAL_TYPE + && TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2)) + warning_at (colon_loc, OPT_Wc___compat, + ("different enum types in conditional is " + "invalid in C++: %qT vs %qT"), + t1, t2); } /* Quickly detect the usual case where op1 and op2 have the same type @@ -4113,14 +4141,14 @@ if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) { if (type1 == type2) - result_type = type1; + result_type = type1; else - result_type = TYPE_MAIN_VARIANT (type1); + result_type = TYPE_MAIN_VARIANT (type1); } else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE) - && (code2 == INTEGER_TYPE || code2 == REAL_TYPE - || code2 == COMPLEX_TYPE)) + || code1 == COMPLEX_TYPE) + && (code2 == INTEGER_TYPE || code2 == REAL_TYPE + || code2 == COMPLEX_TYPE)) { result_type = c_common_type (type1, type2); do_warn_double_promotion (result_type, type1, type2, @@ -4129,76 +4157,76 @@ colon_loc); /* If -Wsign-compare, warn here if type1 and type2 have - different signedness. We'll promote the signed to unsigned - and later code won't know it used to be different. - Do this check on the original types, so that explicit casts - will be considered, but default promotions won't. */ + different signedness. We'll promote the signed to unsigned + and later code won't know it used to be different. + Do this check on the original types, so that explicit casts + will be considered, but default promotions won't. */ if (c_inhibit_evaluation_warnings == 0) - { - int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1)); - int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2)); - - if (unsigned_op1 ^ unsigned_op2) - { - bool ovf; - - /* Do not warn if the result type is signed, since the - signed type will only be chosen if it can represent - all the values of the unsigned type. */ - if (!TYPE_UNSIGNED (result_type)) - /* OK */; - else - { - bool op1_maybe_const = true; - bool op2_maybe_const = true; - - /* Do not warn if the signed quantity is an - unsuffixed integer literal (or some static - constant expression involving such literals) and - it is non-negative. This warning requires the - operands to be folded for best results, so do - that folding in this case even without - warn_sign_compare to avoid warning options - possibly affecting code generation. */ - c_inhibit_evaluation_warnings - += (ifexp == truthvalue_false_node); - op1 = c_fully_fold (op1, require_constant_value, - &op1_maybe_const); - c_inhibit_evaluation_warnings - -= (ifexp == truthvalue_false_node); - - c_inhibit_evaluation_warnings - += (ifexp == truthvalue_true_node); - op2 = c_fully_fold (op2, require_constant_value, - &op2_maybe_const); - c_inhibit_evaluation_warnings - -= (ifexp == truthvalue_true_node); - - if (warn_sign_compare) - { - if ((unsigned_op2 - && tree_expr_nonnegative_warnv_p (op1, &ovf)) - || (unsigned_op1 - && tree_expr_nonnegative_warnv_p (op2, &ovf))) - /* OK */; - else - warning_at (colon_loc, OPT_Wsign_compare, - ("signed and unsigned type in " - "conditional expression")); - } - if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST) - op1 = c_wrap_maybe_const (op1, !op1_maybe_const); - if (!op2_maybe_const || TREE_CODE (op2) != INTEGER_CST) - op2 = c_wrap_maybe_const (op2, !op2_maybe_const); - } - } - } + { + int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1)); + int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2)); + + if (unsigned_op1 ^ unsigned_op2) + { + bool ovf; + + /* Do not warn if the result type is signed, since the + signed type will only be chosen if it can represent + all the values of the unsigned type. */ + if (!TYPE_UNSIGNED (result_type)) + /* OK */; + else + { + bool op1_maybe_const = true; + bool op2_maybe_const = true; + + /* Do not warn if the signed quantity is an + unsuffixed integer literal (or some static + constant expression involving such literals) and + it is non-negative. This warning requires the + operands to be folded for best results, so do + that folding in this case even without + warn_sign_compare to avoid warning options + possibly affecting code generation. */ + c_inhibit_evaluation_warnings + += (ifexp == truthvalue_false_node); + op1 = c_fully_fold (op1, require_constant_value, + &op1_maybe_const); + c_inhibit_evaluation_warnings + -= (ifexp == truthvalue_false_node); + + c_inhibit_evaluation_warnings + += (ifexp == truthvalue_true_node); + op2 = c_fully_fold (op2, require_constant_value, + &op2_maybe_const); + c_inhibit_evaluation_warnings + -= (ifexp == truthvalue_true_node); + + if (warn_sign_compare) + { + if ((unsigned_op2 + && tree_expr_nonnegative_warnv_p (op1, &ovf)) + || (unsigned_op1 + && tree_expr_nonnegative_warnv_p (op2, &ovf))) + /* OK */; + else + warning_at (colon_loc, OPT_Wsign_compare, + ("signed and unsigned type in " + "conditional expression")); + } + if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST) + op1 = c_wrap_maybe_const (op1, !op1_maybe_const); + if (!op2_maybe_const || TREE_CODE (op2) != INTEGER_CST) + op2 = c_wrap_maybe_const (op2, !op2_maybe_const); + } + } + } } else if (code1 == VOID_TYPE || code2 == VOID_TYPE) { if (code1 != VOID_TYPE || code2 != VOID_TYPE) - pedwarn (colon_loc, OPT_pedantic, - "ISO C forbids conditional expr with only one void side"); + pedwarn (colon_loc, OPT_pedantic, + "ISO C forbids conditional expr with only one void side"); result_type = void_type_node; } else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) @@ -4208,26 +4236,26 @@ addr_space_t as_common; if (comp_target_types (colon_loc, type1, type2)) - result_type = common_pointer_type (type1, type2); + result_type = common_pointer_type (type1, type2); else if (null_pointer_constant_p (orig_op1)) - result_type = type2; + result_type = type2; else if (null_pointer_constant_p (orig_op2)) - result_type = type1; + result_type = type1; else if (!addr_space_superset (as1, as2, &as_common)) - { - error_at (colon_loc, "pointers to disjoint address spaces " - "used in conditional expression"); - return error_mark_node; - } + { + error_at (colon_loc, "pointers to disjoint address spaces " + "used in conditional expression"); + return error_mark_node; + } else if (VOID_TYPE_P (TREE_TYPE (type1))) - { - if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) - pedwarn (colon_loc, OPT_pedantic, - "ISO C forbids conditional expr between " - "% and function pointer"); - result_type = build_pointer_type (qualify_type (TREE_TYPE (type1), - TREE_TYPE (type2))); - } + { + if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) + pedwarn (colon_loc, OPT_pedantic, + "ISO C forbids conditional expr between " + "% and function pointer"); + result_type = build_pointer_type (qualify_type (TREE_TYPE (type1), + TREE_TYPE (type2))); + } else if (VOID_TYPE_P (TREE_TYPE (type2))) { if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) @@ -4253,42 +4281,42 @@ else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) { if (!null_pointer_constant_p (orig_op2)) - pedwarn (colon_loc, 0, - "pointer/integer type mismatch in conditional expression"); + pedwarn (colon_loc, 0, + "pointer/integer type mismatch in conditional expression"); else - { - op2 = null_pointer_node; - } + { + op2 = null_pointer_node; + } result_type = type1; } else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) { if (!null_pointer_constant_p (orig_op1)) - pedwarn (colon_loc, 0, - "pointer/integer type mismatch in conditional expression"); + pedwarn (colon_loc, 0, + "pointer/integer type mismatch in conditional expression"); else - { - op1 = null_pointer_node; - } + { + op1 = null_pointer_node; + } result_type = type2; } if (!result_type) { if (flag_cond_mismatch) - result_type = void_type_node; + result_type = void_type_node; else - { - error_at (colon_loc, "type mismatch in conditional expression"); - return error_mark_node; - } + { + error_at (colon_loc, "type mismatch in conditional expression"); + return error_mark_node; + } } /* Merge const and volatile flags of the incoming types. */ result_type = build_type_variant (result_type, - TYPE_READONLY (type1) || TYPE_READONLY (type2), - TYPE_VOLATILE (type1) || TYPE_VOLATILE (type2)); + TYPE_READONLY (type1) || TYPE_READONLY (type2), + TYPE_VOLATILE (type1) || TYPE_VOLATILE (type2)); op1 = ep_convert_and_check (result_type, op1, semantic_result_type); op2 = ep_convert_and_check (result_type, op2, semantic_result_type); @@ -4304,16 +4332,16 @@ op2 = c_fully_fold (op2, require_constant_value, NULL); } int_const = int_operands = (ifexp_int_operands - && op1_int_operands - && op2_int_operands); + && op1_int_operands + && op2_int_operands); if (int_operands) { int_const = ((ifexp == truthvalue_true_node - && TREE_CODE (orig_op1) == INTEGER_CST - && !TREE_OVERFLOW (orig_op1)) - || (ifexp == truthvalue_false_node - && TREE_CODE (orig_op2) == INTEGER_CST - && !TREE_OVERFLOW (orig_op2))); + && TREE_CODE (orig_op1) == INTEGER_CST + && !TREE_OVERFLOW (orig_op1)) + || (ifexp == truthvalue_false_node + && TREE_CODE (orig_op2) == INTEGER_CST + && !TREE_OVERFLOW (orig_op2))); } if (int_const || (ifexp_bcp && TREE_CODE (ifexp) == INTEGER_CST)) ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2); @@ -4321,7 +4349,7 @@ { ret = build3 (COND_EXPR, result_type, ifexp, op1, op2); if (int_operands) - ret = note_integer_operands (ret); + ret = note_integer_operands (ret); } if (semantic_result_type) ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret); @@ -4360,21 +4388,21 @@ if (!TREE_SIDE_EFFECTS (expr1)) { /* The left-hand operand of a comma expression is like an expression - statement: with -Wunused, we should warn if it doesn't have - any side-effects, unless it was explicitly cast to (void). */ + statement: with -Wunused, we should warn if it doesn't have + any side-effects, unless it was explicitly cast to (void). */ if (warn_unused_value) - { - if (VOID_TYPE_P (TREE_TYPE (expr1)) - && CONVERT_EXPR_P (expr1)) - ; /* (void) a, b */ - else if (VOID_TYPE_P (TREE_TYPE (expr1)) - && TREE_CODE (expr1) == COMPOUND_EXPR - && CONVERT_EXPR_P (TREE_OPERAND (expr1, 1))) - ; /* (void) a, (void) b, c */ - else - warning_at (loc, OPT_Wunused_value, - "left-hand operand of comma expression has no effect"); - } + { + if (VOID_TYPE_P (TREE_TYPE (expr1)) + && CONVERT_EXPR_P (expr1)) + ; /* (void) a, b */ + else if (VOID_TYPE_P (TREE_TYPE (expr1)) + && TREE_CODE (expr1) == COMPOUND_EXPR + && CONVERT_EXPR_P (TREE_OPERAND (expr1, 1))) + ; /* (void) a, (void) b, c */ + else + warning_at (loc, OPT_Wunused_value, + "left-hand operand of comma expression has no effect"); + } } /* With -Wunused, we should also warn if the left-hand operand does have @@ -4427,19 +4455,19 @@ in_type = TREE_TYPE (in_type); /* GNU C allows cv-qualified function types. 'const' means the - function is very pure, 'volatile' means it can't return. We - need to warn when such qualifiers are added, not when they're - taken away. */ + function is very pure, 'volatile' means it can't return. We + need to warn when such qualifiers are added, not when they're + taken away. */ if (TREE_CODE (in_otype) == FUNCTION_TYPE - && TREE_CODE (in_type) == FUNCTION_TYPE) - added |= (TYPE_QUALS_NO_ADDR_SPACE (in_type) - & ~TYPE_QUALS_NO_ADDR_SPACE (in_otype)); + && TREE_CODE (in_type) == FUNCTION_TYPE) + added |= (TYPE_QUALS_NO_ADDR_SPACE (in_type) + & ~TYPE_QUALS_NO_ADDR_SPACE (in_otype)); else - discarded |= (TYPE_QUALS_NO_ADDR_SPACE (in_otype) - & ~TYPE_QUALS_NO_ADDR_SPACE (in_type)); + discarded |= (TYPE_QUALS_NO_ADDR_SPACE (in_otype) + & ~TYPE_QUALS_NO_ADDR_SPACE (in_type)); } while (TREE_CODE (in_type) == POINTER_TYPE - && TREE_CODE (in_otype) == POINTER_TYPE); + && TREE_CODE (in_otype) == POINTER_TYPE); if (added) warning_at (loc, OPT_Wcast_qual, @@ -4490,7 +4518,7 @@ break; } if (is_const) - is_const = TYPE_READONLY (in_type); + is_const = TYPE_READONLY (in_type); } while (TREE_CODE (in_type) == POINTER_TYPE); } @@ -4535,15 +4563,15 @@ { value = require_complete_type (value); if (value == error_mark_node) - return error_mark_node; + return error_mark_node; } if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value))) { if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - pedwarn (loc, OPT_pedantic, - "ISO C forbids casting nonscalar to the same type"); + || TREE_CODE (type) == UNION_TYPE) + pedwarn (loc, OPT_pedantic, + "ISO C forbids casting nonscalar to the same type"); } else if (TREE_CODE (type) == UNION_TYPE) { @@ -4578,11 +4606,11 @@ tree otype, ovalue; if (type == void_type_node) - { - tree t = build1 (CONVERT_EXPR, type, value); - SET_EXPR_LOCATION (t, loc); - return t; - } + { + tree t = build1 (CONVERT_EXPR, type, value); + SET_EXPR_LOCATION (t, loc); + return t; + } otype = TREE_TYPE (value); @@ -4593,120 +4621,120 @@ handle_warn_cast_qual (loc, type, otype); /* Warn about conversions between pointers to disjoint - address spaces. */ + address spaces. */ if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && !null_pointer_constant_p (value)) - { - addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type)); - addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (otype)); - addr_space_t as_common; - - if (!addr_space_superset (as_to, as_from, &as_common)) - { - if (ADDR_SPACE_GENERIC_P (as_from)) - warning_at (loc, 0, "cast to %s address space pointer " - "from disjoint generic address space pointer", - c_addr_space_name (as_to)); - - else if (ADDR_SPACE_GENERIC_P (as_to)) - warning_at (loc, 0, "cast to generic address space pointer " - "from disjoint %s address space pointer", - c_addr_space_name (as_from)); - - else - warning_at (loc, 0, "cast to %s address space pointer " - "from disjoint %s address space pointer", - c_addr_space_name (as_to), - c_addr_space_name (as_from)); - } - } + && TREE_CODE (otype) == POINTER_TYPE + && !null_pointer_constant_p (value)) + { + addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type)); + addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (otype)); + addr_space_t as_common; + + if (!addr_space_superset (as_to, as_from, &as_common)) + { + if (ADDR_SPACE_GENERIC_P (as_from)) + warning_at (loc, 0, "cast to %s address space pointer " + "from disjoint generic address space pointer", + c_addr_space_name (as_to)); + + else if (ADDR_SPACE_GENERIC_P (as_to)) + warning_at (loc, 0, "cast to generic address space pointer " + "from disjoint %s address space pointer", + c_addr_space_name (as_from)); + + else + warning_at (loc, 0, "cast to %s address space pointer " + "from disjoint %s address space pointer", + c_addr_space_name (as_to), + c_addr_space_name (as_from)); + } + } /* Warn about possible alignment problems. */ if (STRICT_ALIGNMENT - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE - && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE - /* Don't warn about opaque types, where the actual alignment - restriction is unknown. */ - && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE - || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE) - && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode) - && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) - warning_at (loc, OPT_Wcast_align, - "cast increases required alignment of target type"); + && TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE + && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE + /* Don't warn about opaque types, where the actual alignment + restriction is unknown. */ + && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE + || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE) + && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode) + && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) + warning_at (loc, OPT_Wcast_align, + "cast increases required alignment of target type"); if (TREE_CODE (type) == INTEGER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype)) + && TREE_CODE (otype) == POINTER_TYPE + && TYPE_PRECISION (type) != TYPE_PRECISION (otype)) /* Unlike conversion of integers to pointers, where the warning is disabled for converting constants because of cases such as SIG_*, warn about converting constant pointers to integers. In some cases it may cause unwanted sign extension, and a warning is appropriate. */ - warning_at (loc, OPT_Wpointer_to_int_cast, - "cast from pointer to integer of different size"); + warning_at (loc, OPT_Wpointer_to_int_cast, + "cast from pointer to integer of different size"); if (TREE_CODE (value) == CALL_EXPR - && TREE_CODE (type) != TREE_CODE (otype)) - warning_at (loc, OPT_Wbad_function_cast, - "cast from function call of type %qT " - "to non-matching type %qT", otype, type); + && TREE_CODE (type) != TREE_CODE (otype)) + warning_at (loc, OPT_Wbad_function_cast, + "cast from function call of type %qT " + "to non-matching type %qT", otype, type); if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == INTEGER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype) - /* Don't warn about converting any constant. */ - && !TREE_CONSTANT (value)) - warning_at (loc, - OPT_Wint_to_pointer_cast, "cast to pointer from integer " - "of different size"); + && TREE_CODE (otype) == INTEGER_TYPE + && TYPE_PRECISION (type) != TYPE_PRECISION (otype) + /* Don't warn about converting any constant. */ + && !TREE_CONSTANT (value)) + warning_at (loc, + OPT_Wint_to_pointer_cast, "cast to pointer from integer " + "of different size"); if (warn_strict_aliasing <= 2) strict_aliasing_warning (otype, type, expr); /* If pedantic, warn for conversions between function and object - pointer types, except for converting a null pointer constant - to function pointer type. */ + pointer types, except for converting a null pointer constant + to function pointer type. */ if (pedantic - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE) - pedwarn (loc, OPT_pedantic, "ISO C forbids " - "conversion of function pointer to object pointer type"); + && TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE) + pedwarn (loc, OPT_pedantic, "ISO C forbids " + "conversion of function pointer to object pointer type"); if (pedantic - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE - && !null_pointer_constant_p (value)) - pedwarn (loc, OPT_pedantic, "ISO C forbids " - "conversion of object pointer to function pointer type"); + && TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE + && !null_pointer_constant_p (value)) + pedwarn (loc, OPT_pedantic, "ISO C forbids " + "conversion of object pointer to function pointer type"); ovalue = value; value = convert (type, value); /* Ignore any integer overflow caused by the cast. */ if (TREE_CODE (value) == INTEGER_CST && !FLOAT_TYPE_P (otype)) - { - if (CONSTANT_CLASS_P (ovalue) && TREE_OVERFLOW (ovalue)) - { - if (!TREE_OVERFLOW (value)) - { - /* Avoid clobbering a shared constant. */ - value = copy_node (value); - TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); - } - } - else if (TREE_OVERFLOW (value)) - /* Reset VALUE's overflow flags, ensuring constant sharing. */ - value = build_int_cst_wide (TREE_TYPE (value), - TREE_INT_CST_LOW (value), - TREE_INT_CST_HIGH (value)); - } + { + if (CONSTANT_CLASS_P (ovalue) && TREE_OVERFLOW (ovalue)) + { + if (!TREE_OVERFLOW (value)) + { + /* Avoid clobbering a shared constant. */ + value = copy_node (value); + TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); + } + } + else if (TREE_OVERFLOW (value)) + /* Reset VALUE's overflow flags, ensuring constant sharing. */ + value = build_int_cst_wide (TREE_TYPE (value), + TREE_INT_CST_LOW (value), + TREE_INT_CST_HIGH (value)); + } } /* Don't let a cast be an lvalue. */ @@ -4721,10 +4749,10 @@ if (TREE_CODE (value) == REAL_CST || TREE_CODE (value) == COMPLEX_CST || (TREE_CODE (value) == INTEGER_CST - && !((TREE_CODE (expr) == INTEGER_CST - && INTEGRAL_TYPE_P (TREE_TYPE (expr))) - || TREE_CODE (expr) == REAL_CST - || TREE_CODE (expr) == COMPLEX_CST))) + && !((TREE_CODE (expr) == INTEGER_CST + && INTEGRAL_TYPE_P (TREE_TYPE (expr))) + || TREE_CODE (expr) == REAL_CST + || TREE_CODE (expr) == COMPLEX_CST))) value = build1 (NOP_EXPR, type, value); if (CAN_HAVE_LOCATION_P (value)) @@ -4766,7 +4794,7 @@ allows references to incomplete types. */ if (warn_cxx_compat && type_name->specs->typespec_kind == ctsk_tagdef) warning_at (loc, OPT_Wc___compat, - "defining a type in a cast is invalid in C++"); + "defining a type in a cast is invalid in C++"); return ret; } @@ -4785,8 +4813,8 @@ tree build_modify_expr (location_t location, tree lhs, tree lhs_origtype, - enum tree_code modifycode, - location_t rhs_loc, tree rhs, tree rhs_origtype) + enum tree_code modifycode, + location_t rhs_loc, tree rhs, tree rhs_origtype) { tree result; tree newrhs; @@ -4817,12 +4845,12 @@ if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR) { tree inner = build_modify_expr (location, C_MAYBE_CONST_EXPR_EXPR (lhs), - lhs_origtype, modifycode, rhs_loc, rhs, - rhs_origtype); + lhs_origtype, modifycode, rhs_loc, rhs, + rhs_origtype); if (inner == error_mark_node) - return error_mark_node; + return error_mark_node; result = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner), - C_MAYBE_CONST_EXPR_PRE (lhs), inner); + C_MAYBE_CONST_EXPR_PRE (lhs), inner); gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (lhs)); C_MAYBE_CONST_EXPR_NON_CONST (result) = 1; protected_set_expr_location (result, location); @@ -4837,10 +4865,10 @@ lhs = c_fully_fold (lhs, false, NULL); lhs = stabilize_reference (lhs); newrhs = build_binary_op (location, - modifycode, lhs, rhs, 1); + modifycode, lhs, rhs, 1); /* The original type of the right hand side is no longer - meaningful. */ + meaningful. */ rhs_origtype = NULL_TREE; } @@ -4861,8 +4889,8 @@ if (TYPE_READONLY (lhstype) || ((TREE_CODE (lhstype) == RECORD_TYPE - || TREE_CODE (lhstype) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (lhstype))) + || TREE_CODE (lhstype) == UNION_TYPE) + && C_TYPE_FIELDS_READONLY (lhstype))) { readonly_error (lhs, lv_assign); return error_mark_node; @@ -4877,9 +4905,9 @@ if (TREE_CODE (lhs) == COMPONENT_REF && (TREE_CODE (lhstype) == INTEGER_TYPE - || TREE_CODE (lhstype) == BOOLEAN_TYPE - || TREE_CODE (lhstype) == REAL_TYPE - || TREE_CODE (lhstype) == ENUMERAL_TYPE)) + || TREE_CODE (lhstype) == BOOLEAN_TYPE + || TREE_CODE (lhstype) == REAL_TYPE + || TREE_CODE (lhstype) == ENUMERAL_TYPE)) lhstype = TREE_TYPE (get_unwidened (lhs, 0)); /* If storing in a field that is in actuality a short or narrower than one, @@ -4900,12 +4928,12 @@ && TREE_CODE (lhs_origtype) == ENUMERAL_TYPE) { tree checktype = (rhs_origtype != NULL_TREE - ? rhs_origtype - : TREE_TYPE (rhs)); + ? rhs_origtype + : TREE_TYPE (rhs)); if (checktype != error_mark_node - && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (lhs_origtype)) - warning_at (location, OPT_Wc___compat, - "enum conversion in assignment is invalid in C++"); + && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (lhs_origtype)) + warning_at (location, OPT_Wc___compat, + "enum conversion in assignment is invalid in C++"); } /* Convert new value to destination type. Fold it first, then @@ -4917,7 +4945,7 @@ if (rhs_semantic_type) newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs); newrhs = convert_for_assignment (location, lhstype, newrhs, rhs_origtype, - ic_assign, npc, NULL_TREE, NULL_TREE, 0); + ic_assign, npc, NULL_TREE, NULL_TREE, 0); if (TREE_CODE (newrhs) == ERROR_MARK) return error_mark_node; @@ -4926,10 +4954,10 @@ { result = objc_generate_write_barrier (lhs, modifycode, newrhs); if (result) - { - protected_set_expr_location (result, location); - return result; - } + { + protected_set_expr_location (result, location); + return result; + } } /* Scan operands. */ @@ -4947,7 +4975,7 @@ return result; result = convert_for_assignment (location, olhstype, result, rhs_origtype, - ic_assign, false, NULL_TREE, NULL_TREE, 0); + ic_assign, false, NULL_TREE, NULL_TREE, 0); protected_set_expr_location (result, location); return result; } @@ -5069,9 +5097,9 @@ static tree convert_for_assignment (location_t location, tree type, tree rhs, - tree origtype, enum impl_conv errtype, - bool null_pointer_constant, tree fundecl, - tree function, int parmnum) + tree origtype, enum impl_conv errtype, + bool null_pointer_constant, tree fundecl, + tree function, int parmnum) { enum tree_code codel = TREE_CODE (type); tree orig_rhs = rhs; @@ -5084,32 +5112,32 @@ { tree selector; /* Change pointer to function to the function itself for - diagnostics. */ + diagnostics. */ if (TREE_CODE (function) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) - function = TREE_OPERAND (function, 0); + && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) + function = TREE_OPERAND (function, 0); /* Handle an ObjC selector specially for diagnostics. */ selector = objc_message_selector (); rname = function; if (selector && parmnum > 2) - { - rname = selector; - parmnum -= 2; - } + { + rname = selector; + parmnum -= 2; + } } /* This macro is used to emit diagnostics to ensure that all format strings are complete sentences, visible to gettext and checked at compile time. */ -#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \ +#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \ do { \ switch (errtype) \ { \ case ic_argpass: \ if (pedwarn (LOCATION, OPT, AR, parmnum, rname)) \ - inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \ - ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \ + inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \ + ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \ "expected %qT but argument is of type %qT", \ type, rhstype); \ break; \ @@ -5120,7 +5148,7 @@ pedwarn_init (LOCATION, OPT, IN); \ break; \ case ic_return: \ - pedwarn (LOCATION, OPT, RE); \ + pedwarn (LOCATION, OPT, RE); \ break; \ default: \ gcc_unreachable (); \ @@ -5171,23 +5199,23 @@ int parmno; switch (errtype) - { - case ic_return: - parmno = 0; - break; - - case ic_assign: - parmno = -1; - break; - - case ic_init: - parmno = -2; - break; - - default: - parmno = parmnum; - break; - } + { + case ic_return: + parmno = 0; + break; + + case ic_assign: + parmno = -1; + break; + + case ic_init: + parmno = -2; + break; + + default: + parmno = parmnum; + break; + } objc_ok = objc_compare_types (type, rhstype, parmno, rname); } @@ -5196,19 +5224,19 @@ { tree checktype = origtype != NULL_TREE ? origtype : rhstype; if (checktype != error_mark_node - && TREE_CODE (type) == ENUMERAL_TYPE - && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type)) - { - WARN_FOR_ASSIGNMENT (input_location, OPT_Wc___compat, - G_("enum conversion when passing argument " - "%d of %qE is invalid in C++"), - G_("enum conversion in assignment is " - "invalid in C++"), - G_("enum conversion in initialization is " - "invalid in C++"), - G_("enum conversion in return is " - "invalid in C++")); - } + && TREE_CODE (type) == ENUMERAL_TYPE + && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type)) + { + WARN_FOR_ASSIGNMENT (input_location, OPT_Wc___compat, + G_("enum conversion when passing argument " + "%d of %qE is invalid in C++"), + G_("enum conversion in assignment is " + "invalid in C++"), + G_("enum conversion in initialization is " + "invalid in C++"), + G_("enum conversion in return is " + "invalid in C++")); + } } if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) @@ -5217,10 +5245,10 @@ if (coder == VOID_TYPE) { /* Except for passing an argument to an unprototyped function, - this is a constraint violation. When passing an argument to - an unprototyped function, it is compile-time undefined; - making it a constraint in that case was rejected in - DR#252. */ + this is a constraint violation. When passing an argument to + an unprototyped function, it is compile-time undefined; + making it a constraint in that case was rejected in + DR#252. */ error_at (location, "void value not ignored as it ought to be"); return error_mark_node; } @@ -5234,25 +5262,25 @@ && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1) { if (!lvalue_p (rhs)) - { - error_at (location, "cannot pass rvalue to reference parameter"); - return error_mark_node; - } + { + error_at (location, "cannot pass rvalue to reference parameter"); + return error_mark_node; + } if (!c_mark_addressable (rhs)) - return error_mark_node; + return error_mark_node; rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs); SET_EXPR_LOCATION (rhs, location); /* We already know that these two types are compatible, but they - may not be exactly identical. In fact, `TREE_TYPE (type)' is - likely to be __builtin_va_list and `TREE_TYPE (rhs)' is - likely to be va_list, a typedef to __builtin_va_list, which - is different enough that it will cause problems later. */ + may not be exactly identical. In fact, `TREE_TYPE (type)' is + likely to be __builtin_va_list and `TREE_TYPE (rhs)' is + likely to be va_list, a typedef to __builtin_va_list, which + is different enough that it will cause problems later. */ if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type)) - { - rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs); - SET_EXPR_LOCATION (rhs, location); - } + { + rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs); + SET_EXPR_LOCATION (rhs, location); + } rhs = build1 (NOP_EXPR, type, rhs); SET_EXPR_LOCATION (rhs, location); @@ -5260,17 +5288,17 @@ } /* Some types can interconvert without explicit casts. */ else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE - && vector_types_convertible_p (type, TREE_TYPE (rhs), true)) + && vector_types_convertible_p (type, TREE_TYPE (rhs), true)) return convert (type, rhs); /* Arithmetic types all interconvert, and enum is treated like int. */ else if ((codel == INTEGER_TYPE || codel == REAL_TYPE - || codel == FIXED_POINT_TYPE - || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE - || codel == BOOLEAN_TYPE) - && (coder == INTEGER_TYPE || coder == REAL_TYPE - || coder == FIXED_POINT_TYPE - || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE - || coder == BOOLEAN_TYPE)) + || codel == FIXED_POINT_TYPE + || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE + || codel == BOOLEAN_TYPE) + && (coder == INTEGER_TYPE || coder == REAL_TYPE + || coder == FIXED_POINT_TYPE + || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE + || coder == BOOLEAN_TYPE)) { tree ret; bool save = in_late_binary_op; @@ -5390,7 +5418,6 @@ G_("return discards %qv qualifier from " "pointer target type"), TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)); - memb = marginal_memb; } @@ -5405,7 +5432,7 @@ /* Conversions among pointers */ else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE) - && (coder == codel)) + && (coder == codel)) { tree ttl = TREE_TYPE (type); tree ttr = TREE_TYPE (rhstype); @@ -5417,9 +5444,9 @@ addr_space_t asr; if (TREE_CODE (mvl) != ARRAY_TYPE) - mvl = TYPE_MAIN_VARIANT (mvl); + mvl = TYPE_MAIN_VARIANT (mvl); if (TREE_CODE (mvr) != ARRAY_TYPE) - mvr = TYPE_MAIN_VARIANT (mvr); + mvr = TYPE_MAIN_VARIANT (mvr); /* Opaque pointers are treated like void pointers. */ is_opaque_pointer = vector_targets_convertible_p (ttl, ttr); @@ -5443,83 +5470,83 @@ } /* C++ does not allow the implicit conversion void* -> T*. However, - for the purpose of reducing the number of false positives, we - tolerate the special case of - - int *p = NULL; - - where NULL is typically defined in C to be '(void *) 0'. */ + for the purpose of reducing the number of false positives, we + tolerate the special case of + + int *p = NULL; + + where NULL is typically defined in C to be '(void *) 0'. */ if (VOID_TYPE_P (ttr) && rhs != null_pointer_node && !VOID_TYPE_P (ttl)) - warning_at (location, OPT_Wc___compat, - "request for implicit conversion " - "from %qT to %qT not permitted in C++", rhstype, type); + warning_at (location, OPT_Wc___compat, + "request for implicit conversion " + "from %qT to %qT not permitted in C++", rhstype, type); /* See if the pointers point to incompatible address spaces. */ asl = TYPE_ADDR_SPACE (ttl); asr = TYPE_ADDR_SPACE (ttr); if (!null_pointer_constant_p (rhs) - && asr != asl && !targetm.addr_space.subset_p (asr, asl)) - { - switch (errtype) - { - case ic_argpass: - error_at (location, "passing argument %d of %qE from pointer to " - "non-enclosed address space", parmnum, rname); - break; - case ic_assign: - error_at (location, "assignment from pointer to " - "non-enclosed address space"); - break; - case ic_init: - error_at (location, "initialization from pointer to " - "non-enclosed address space"); - break; - case ic_return: - error_at (location, "return from pointer to " - "non-enclosed address space"); - break; - default: - gcc_unreachable (); - } - return error_mark_node; - } + && asr != asl && !targetm.addr_space.subset_p (asr, asl)) + { + switch (errtype) + { + case ic_argpass: + error_at (location, "passing argument %d of %qE from pointer to " + "non-enclosed address space", parmnum, rname); + break; + case ic_assign: + error_at (location, "assignment from pointer to " + "non-enclosed address space"); + break; + case ic_init: + error_at (location, "initialization from pointer to " + "non-enclosed address space"); + break; + case ic_return: + error_at (location, "return from pointer to " + "non-enclosed address space"); + break; + default: + gcc_unreachable (); + } + return error_mark_node; + } /* Check if the right-hand side has a format attribute but the - left-hand side doesn't. */ + left-hand side doesn't. */ if (warn_missing_format_attribute - && check_missing_format_attribute (type, rhstype)) - { - switch (errtype) - { - case ic_argpass: - warning_at (location, OPT_Wmissing_format_attribute, - "argument %d of %qE might be " - "a candidate for a format attribute", - parmnum, rname); - break; - case ic_assign: - warning_at (location, OPT_Wmissing_format_attribute, - "assignment left-hand side might be " - "a candidate for a format attribute"); - break; - case ic_init: - warning_at (location, OPT_Wmissing_format_attribute, - "initialization left-hand side might be " - "a candidate for a format attribute"); - break; - case ic_return: - warning_at (location, OPT_Wmissing_format_attribute, - "return type might be " - "a candidate for a format attribute"); - break; - default: - gcc_unreachable (); - } - } + && check_missing_format_attribute (type, rhstype)) + { + switch (errtype) + { + case ic_argpass: + warning_at (location, OPT_Wmissing_format_attribute, + "argument %d of %qE might be " + "a candidate for a format attribute", + parmnum, rname); + break; + case ic_assign: + warning_at (location, OPT_Wmissing_format_attribute, + "assignment left-hand side might be " + "a candidate for a format attribute"); + break; + case ic_init: + warning_at (location, OPT_Wmissing_format_attribute, + "initialization left-hand side might be " + "a candidate for a format attribute"); + break; + case ic_return: + warning_at (location, OPT_Wmissing_format_attribute, + "return type might be " + "a candidate for a format attribute"); + break; + default: + gcc_unreachable (); + } + } /* Any non-function converts to a [const][volatile] void * - and vice versa; otherwise, targets must be the same. - Meanwhile, the lhs target must have all the qualifiers of the rhs. */ + and vice versa; otherwise, targets must be the same. + Meanwhile, the lhs target must have all the qualifiers of the rhs. */ if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) || (target_cmp = comp_target_types (location, type, rhstype)) || is_opaque_pointer @@ -5601,54 +5628,54 @@ } } else - /* Avoid warning about the volatile ObjC EH puts on decls. */ - if (!objc_ok) - WARN_FOR_ASSIGNMENT (location, 0, - G_("passing argument %d of %qE from " - "incompatible pointer type"), - G_("assignment from incompatible pointer type"), - G_("initialization from incompatible " - "pointer type"), - G_("return from incompatible pointer type")); + /* Avoid warning about the volatile ObjC EH puts on decls. */ + if (!objc_ok) + WARN_FOR_ASSIGNMENT (location, 0, + G_("passing argument %d of %qE from " + "incompatible pointer type"), + G_("assignment from incompatible pointer type"), + G_("initialization from incompatible " + "pointer type"), + G_("return from incompatible pointer type")); return convert (type, rhs); } else if (codel == POINTER_TYPE && coder == ARRAY_TYPE) { /* ??? This should not be an error when inlining calls to - unprototyped functions. */ + unprototyped functions. */ error_at (location, "invalid use of non-lvalue array"); return error_mark_node; } else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) { /* An explicit constant 0 can convert to a pointer, - or one that results from arithmetic, even including - a cast to integer type. */ + or one that results from arithmetic, even including + a cast to integer type. */ if (!null_pointer_constant) - WARN_FOR_ASSIGNMENT (location, 0, - G_("passing argument %d of %qE makes " - "pointer from integer without a cast"), - G_("assignment makes pointer from integer " - "without a cast"), - G_("initialization makes pointer from " - "integer without a cast"), - G_("return makes pointer from integer " - "without a cast")); + WARN_FOR_ASSIGNMENT (location, 0, + G_("passing argument %d of %qE makes " + "pointer from integer without a cast"), + G_("assignment makes pointer from integer " + "without a cast"), + G_("initialization makes pointer from " + "integer without a cast"), + G_("return makes pointer from integer " + "without a cast")); return convert (type, rhs); } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { WARN_FOR_ASSIGNMENT (location, 0, - G_("passing argument %d of %qE makes integer " - "from pointer without a cast"), - G_("assignment makes integer from pointer " - "without a cast"), - G_("initialization makes integer from pointer " - "without a cast"), - G_("return makes integer from pointer " - "without a cast")); + G_("passing argument %d of %qE makes integer " + "from pointer without a cast"), + G_("assignment makes integer from pointer " + "without a cast"), + G_("initialization makes integer from pointer " + "without a cast"), + G_("return makes integer from pointer " + "without a cast")); return convert (type, rhs); } else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE) @@ -5666,22 +5693,22 @@ case ic_argpass: error_at (location, "incompatible type for argument %d of %qE", parmnum, rname); inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) - ? DECL_SOURCE_LOCATION (fundecl) : input_location, - "expected %qT but argument is of type %qT", type, rhstype); + ? DECL_SOURCE_LOCATION (fundecl) : input_location, + "expected %qT but argument is of type %qT", type, rhstype); break; case ic_assign: error_at (location, "incompatible types when assigning to type %qT from " - "type %qT", type, rhstype); + "type %qT", type, rhstype); break; case ic_init: error_at (location, - "incompatible types when initializing type %qT using type %qT", - type, rhstype); + "incompatible types when initializing type %qT using type %qT", + type, rhstype); break; case ic_return: error_at (location, - "incompatible types when returning type %qT but %qT was " - "expected", rhstype, type); + "incompatible types when returning type %qT but %qT was " + "expected", rhstype, type); break; default: gcc_unreachable (); @@ -5702,10 +5729,10 @@ if (TREE_CODE (value) == COMPOUND_EXPR) { if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype) - == error_mark_node) - return error_mark_node; + == error_mark_node) + return error_mark_node; return valid_compound_expr_initializer (TREE_OPERAND (value, 1), - endtype); + endtype); } else if (!initializer_constant_valid_p (value, endtype)) return error_mark_node; @@ -5738,14 +5765,14 @@ if (init) npc = null_pointer_constant_p (init); value = digest_init (init_loc, type, init, origtype, npc, - true, TREE_STATIC (decl)); + true, TREE_STATIC (decl)); /* Store the expression if valid; else report error. */ if (!in_system_header && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && !TREE_STATIC (decl)) warning (OPT_Wtraditional, "traditional C rejects automatic " - "aggregate initialization"); + "aggregate initialization"); DECL_INITIAL (decl) = value; @@ -5765,21 +5792,21 @@ inside_init = fold (inside_init); if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) - { - tree cldecl = COMPOUND_LITERAL_EXPR_DECL (inside_init); - - if (TYPE_DOMAIN (TREE_TYPE (cldecl))) - { - /* For int foo[] = (int [3]){1}; we need to set array size - now since later on array initializer will be just the - brace enclosed list of the compound literal. */ - type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); - TREE_TYPE (decl) = type; - TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl)); - layout_type (type); - layout_decl (cldecl, 0); - } - } + { + tree cldecl = COMPOUND_LITERAL_EXPR_DECL (inside_init); + + if (TYPE_DOMAIN (TREE_TYPE (cldecl))) + { + /* For int foo[] = (int [3]){1}; we need to set array size + now since later on array initializer will be just the + brace enclosed list of the compound literal. */ + type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); + TREE_TYPE (decl) = type; + TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl)); + layout_type (type); + layout_decl (cldecl, 0); + } + } } } @@ -5802,9 +5829,9 @@ #define SPELLING_MEMBER 2 #define SPELLING_BOUNDS 3 -static struct spelling *spelling; /* Next stack element (unused). */ -static struct spelling *spelling_base; /* Spelling stack base. */ -static int spelling_size; /* Size of the spelling stack. */ +static struct spelling *spelling; /* Next stack element (unused). */ +static struct spelling *spelling_base; /* Spelling stack base. */ +static int spelling_size; /* Size of the spelling stack. */ /* Macros to save and restore the spelling stack around push_... functions. Alternative to SAVE_SPELLING_STACK. */ @@ -5815,21 +5842,21 @@ /* Push an element on the spelling stack with type KIND and assign VALUE to MEMBER. */ -#define PUSH_SPELLING(KIND, VALUE, MEMBER) \ -{ \ - int depth = SPELLING_DEPTH (); \ - \ - if (depth >= spelling_size) \ - { \ - spelling_size += 10; \ - spelling_base = XRESIZEVEC (struct spelling, spelling_base, \ - spelling_size); \ - RESTORE_SPELLING_DEPTH (depth); \ - } \ - \ - spelling->kind = (KIND); \ - spelling->MEMBER = (VALUE); \ - spelling++; \ +#define PUSH_SPELLING(KIND, VALUE, MEMBER) \ +{ \ + int depth = SPELLING_DEPTH (); \ + \ + if (depth >= spelling_size) \ + { \ + spelling_size += 10; \ + spelling_base = XRESIZEVEC (struct spelling, spelling_base, \ + spelling_size); \ + RESTORE_SPELLING_DEPTH (depth); \ + } \ + \ + spelling->kind = (KIND); \ + spelling->MEMBER = (VALUE); \ + spelling++; \ } /* Push STRING on the stack. Printed literally. */ @@ -5871,9 +5898,9 @@ for (p = spelling_base; p < spelling; p++) { if (p->kind == SPELLING_BOUNDS) - size += 25; + size += 25; else - size += strlen (p->u.s) + 1; + size += strlen (p->u.s) + 1; } return size; @@ -5890,16 +5917,16 @@ for (p = spelling_base; p < spelling; p++) if (p->kind == SPELLING_BOUNDS) { - sprintf (d, "[" HOST_WIDE_INT_PRINT_UNSIGNED "]", p->u.i); - d += strlen (d); + sprintf (d, "[" HOST_WIDE_INT_PRINT_UNSIGNED "]", p->u.i); + d += strlen (d); } else { - const char *s; - if (p->kind == SPELLING_MEMBER) - *d++ = '.'; - for (s = p->u.s; (*d = *s++); d++) - ; + const char *s; + if (p->kind == SPELLING_MEMBER) + *d++ = '.'; + for (s = p->u.s; (*d = *s++); d++) + ; } *d++ = '\0'; return buffer; @@ -5968,7 +5995,7 @@ && TREE_CODE (expr.value) == STRING_CST && expr.original_code != STRING_CST) pedwarn_init (input_location, OPT_pedantic, - "array initialized from parenthesized string constant"); + "array initialized from parenthesized string constant"); } /* Digest the parser output INIT as an initializer for type TYPE. @@ -5989,8 +6016,8 @@ static tree digest_init (location_t init_loc, tree type, tree init, tree origtype, - bool null_pointer_constant, bool strict_string, - int require_constant) + bool null_pointer_constant, bool strict_string, + int require_constant) { enum tree_code code = TREE_CODE (type); tree inside_init = init; @@ -6021,88 +6048,88 @@ { tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); /* Note that an array could be both an array of character type - and an array of wchar_t if wchar_t is signed char or unsigned - char. */ + and an array of wchar_t if wchar_t is signed char or unsigned + char. */ bool char_array = (typ1 == char_type_node - || typ1 == signed_char_type_node - || typ1 == unsigned_char_type_node); + || typ1 == signed_char_type_node + || typ1 == unsigned_char_type_node); bool wchar_array = !!comptypes (typ1, wchar_type_node); bool char16_array = !!comptypes (typ1, char16_type_node); bool char32_array = !!comptypes (typ1, char32_type_node); if (char_array || wchar_array || char16_array || char32_array) - { - struct c_expr expr; - tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))); - expr.value = inside_init; - expr.original_code = (strict_string ? STRING_CST : ERROR_MARK); - expr.original_type = NULL; - maybe_warn_string_init (type, expr); - - if (TYPE_DOMAIN (type) && !TYPE_MAX_VALUE (TYPE_DOMAIN (type))) - pedwarn_init (init_loc, OPT_pedantic, - "initialization of a flexible array member"); - - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), - TYPE_MAIN_VARIANT (type))) - return inside_init; - - if (char_array) - { - if (typ2 != char_type_node) - { - error_init ("char-array initialized from wide string"); - return error_mark_node; - } - } - else - { - if (typ2 == char_type_node) - { - error_init ("wide character array initialized from non-wide " - "string"); - return error_mark_node; - } - else if (!comptypes(typ1, typ2)) - { - error_init ("wide character array initialized from " - "incompatible wide string"); - return error_mark_node; - } - } - - TREE_TYPE (inside_init) = type; - if (TYPE_DOMAIN (type) != 0 - && TYPE_SIZE (type) != 0 - && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) - { - unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init); - - /* Subtract the size of a single (possibly wide) character - because it's ok to ignore the terminating null char - that is counted in the length of the constant. */ - if (0 > compare_tree_int (TYPE_SIZE_UNIT (type), - (len - - (TYPE_PRECISION (typ1) - / BITS_PER_UNIT)))) - pedwarn_init (init_loc, 0, - ("initializer-string for array of chars " - "is too long")); - else if (warn_cxx_compat - && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), len)) - warning_at (init_loc, OPT_Wc___compat, - ("initializer-string for array chars " - "is too long for C++")); - } - - return inside_init; - } + { + struct c_expr expr; + tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))); + expr.value = inside_init; + expr.original_code = (strict_string ? STRING_CST : ERROR_MARK); + expr.original_type = NULL; + maybe_warn_string_init (type, expr); + + if (TYPE_DOMAIN (type) && !TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + pedwarn_init (init_loc, OPT_pedantic, + "initialization of a flexible array member"); + + if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), + TYPE_MAIN_VARIANT (type))) + return inside_init; + + if (char_array) + { + if (typ2 != char_type_node) + { + error_init ("char-array initialized from wide string"); + return error_mark_node; + } + } + else + { + if (typ2 == char_type_node) + { + error_init ("wide character array initialized from non-wide " + "string"); + return error_mark_node; + } + else if (!comptypes(typ1, typ2)) + { + error_init ("wide character array initialized from " + "incompatible wide string"); + return error_mark_node; + } + } + + TREE_TYPE (inside_init) = type; + if (TYPE_DOMAIN (type) != 0 + && TYPE_SIZE (type) != 0 + && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) + { + unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init); + + /* Subtract the size of a single (possibly wide) character + because it's ok to ignore the terminating null char + that is counted in the length of the constant. */ + if (0 > compare_tree_int (TYPE_SIZE_UNIT (type), + (len + - (TYPE_PRECISION (typ1) + / BITS_PER_UNIT)))) + pedwarn_init (init_loc, 0, + ("initializer-string for array of chars " + "is too long")); + else if (warn_cxx_compat + && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), len)) + warning_at (init_loc, OPT_Wc___compat, + ("initializer-string for array chars " + "is too long for C++")); + } + + return inside_init; + } else if (INTEGRAL_TYPE_P (typ1)) - { - error_init ("array of inappropriate type initialized " - "from string constant"); - return error_mark_node; - } + { + error_init ("array of inappropriate type initialized " + "from string constant"); + return error_mark_node; + } } /* Build a VECTOR_CST from a *constant* vector constructor. If the @@ -6114,29 +6141,29 @@ && TREE_CONSTANT (inside_init)) { if (TREE_CODE (inside_init) == VECTOR_CST - && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), - TYPE_MAIN_VARIANT (type))) - return inside_init; + && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), + TYPE_MAIN_VARIANT (type))) + return inside_init; if (TREE_CODE (inside_init) == CONSTRUCTOR) - { - unsigned HOST_WIDE_INT ix; - tree value; - bool constant_p = true; - - /* Iterate through elements and check if all constructor - elements are *_CSTs. */ - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (inside_init), ix, value) - if (!CONSTANT_CLASS_P (value)) - { - constant_p = false; - break; - } - - if (constant_p) - return build_vector_from_ctor (type, - CONSTRUCTOR_ELTS (inside_init)); - } + { + unsigned HOST_WIDE_INT ix; + tree value; + bool constant_p = true; + + /* Iterate through elements and check if all constructor + elements are *_CSTs. */ + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (inside_init), ix, value) + if (!CONSTANT_CLASS_P (value)) + { + constant_p = false; + break; + } + + if (constant_p) + return build_vector_from_ctor (type, + CONSTRUCTOR_ELTS (inside_init)); + } } if (warn_sequence_point) @@ -6147,90 +6174,90 @@ if (inside_init && TREE_TYPE (inside_init) != 0 && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), - TYPE_MAIN_VARIANT (type)) - || (code == ARRAY_TYPE - && comptypes (TREE_TYPE (inside_init), type)) - || (code == VECTOR_TYPE - && comptypes (TREE_TYPE (inside_init), type)) - || (code == POINTER_TYPE - && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE - && comptypes (TREE_TYPE (TREE_TYPE (inside_init)), - TREE_TYPE (type))))) + TYPE_MAIN_VARIANT (type)) + || (code == ARRAY_TYPE + && comptypes (TREE_TYPE (inside_init), type)) + || (code == VECTOR_TYPE + && comptypes (TREE_TYPE (inside_init), type)) + || (code == POINTER_TYPE + && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE + && comptypes (TREE_TYPE (TREE_TYPE (inside_init)), + TREE_TYPE (type))))) { if (code == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE) - { - if (TREE_CODE (inside_init) == STRING_CST - || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) - inside_init = array_to_pointer_conversion - (init_loc, inside_init); - else - { - error_init ("invalid use of non-lvalue array"); - return error_mark_node; - } - } - } + { + if (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE) + { + if (TREE_CODE (inside_init) == STRING_CST + || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) + inside_init = array_to_pointer_conversion + (init_loc, inside_init); + else + { + error_init ("invalid use of non-lvalue array"); + return error_mark_node; + } + } + } if (code == VECTOR_TYPE) - /* Although the types are compatible, we may require a - conversion. */ - inside_init = convert (type, inside_init); + /* Although the types are compatible, we may require a + conversion. */ + inside_init = convert (type, inside_init); if (require_constant - && (code == VECTOR_TYPE || !flag_isoc99) - && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) - { - /* As an extension, allow initializing objects with static storage - duration with compound literals (which are then treated just as - the brace enclosed list they contain). Also allow this for - vectors, as we can only assign them with compound literals. */ - tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init); - inside_init = DECL_INITIAL (decl); - } + && (code == VECTOR_TYPE || !flag_isoc99) + && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) + { + /* As an extension, allow initializing objects with static storage + duration with compound literals (which are then treated just as + the brace enclosed list they contain). Also allow this for + vectors, as we can only assign them with compound literals. */ + tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init); + inside_init = DECL_INITIAL (decl); + } if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST - && TREE_CODE (inside_init) != CONSTRUCTOR) - { - error_init ("array initialized from non-constant array expression"); - return error_mark_node; - } + && TREE_CODE (inside_init) != CONSTRUCTOR) + { + error_init ("array initialized from non-constant array expression"); + return error_mark_node; + } /* Compound expressions can only occur here if -pedantic or - -pedantic-errors is specified. In the later case, we always want - an error. In the former case, we simply want a warning. */ + -pedantic-errors is specified. In the later case, we always want + an error. In the former case, we simply want a warning. */ if (require_constant && pedantic - && TREE_CODE (inside_init) == COMPOUND_EXPR) - { - inside_init - = valid_compound_expr_initializer (inside_init, - TREE_TYPE (inside_init)); - if (inside_init == error_mark_node) - error_init ("initializer element is not constant"); - else - pedwarn_init (init_loc, OPT_pedantic, - "initializer element is not constant"); - if (flag_pedantic_errors) - inside_init = error_mark_node; - } + && TREE_CODE (inside_init) == COMPOUND_EXPR) + { + inside_init + = valid_compound_expr_initializer (inside_init, + TREE_TYPE (inside_init)); + if (inside_init == error_mark_node) + error_init ("initializer element is not constant"); + else + pedwarn_init (init_loc, OPT_pedantic, + "initializer element is not constant"); + if (flag_pedantic_errors) + inside_init = error_mark_node; + } else if (require_constant - && !initializer_constant_valid_p (inside_init, - TREE_TYPE (inside_init))) - { - error_init ("initializer element is not constant"); - inside_init = error_mark_node; - } + && !initializer_constant_valid_p (inside_init, + TREE_TYPE (inside_init))) + { + error_init ("initializer element is not constant"); + inside_init = error_mark_node; + } else if (require_constant && !maybe_const) - pedwarn_init (init_loc, 0, - "initializer element is not a constant expression"); + pedwarn_init (init_loc, 0, + "initializer element is not a constant expression"); /* Added to enable additional -Wmissing-format-attribute warnings. */ if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE) - inside_init = convert_for_assignment (init_loc, type, inside_init, - origtype, - ic_init, null_pointer_constant, - NULL_TREE, NULL_TREE, 0); + inside_init = convert_for_assignment (init_loc, type, inside_init, + origtype, + ic_init, null_pointer_constant, + NULL_TREE, NULL_TREE, 0); return inside_init; } @@ -6241,35 +6268,35 @@ || code == COMPLEX_TYPE || code == VECTOR_TYPE) { if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE - && (TREE_CODE (init) == STRING_CST - || TREE_CODE (init) == COMPOUND_LITERAL_EXPR)) - inside_init = init = array_to_pointer_conversion (init_loc, init); + && (TREE_CODE (init) == STRING_CST + || TREE_CODE (init) == COMPOUND_LITERAL_EXPR)) + inside_init = init = array_to_pointer_conversion (init_loc, init); if (semantic_type) - inside_init = build1 (EXCESS_PRECISION_EXPR, semantic_type, - inside_init); + inside_init = build1 (EXCESS_PRECISION_EXPR, semantic_type, + inside_init); inside_init - = convert_for_assignment (init_loc, type, inside_init, origtype, - ic_init, null_pointer_constant, - NULL_TREE, NULL_TREE, 0); + = convert_for_assignment (init_loc, type, inside_init, origtype, + ic_init, null_pointer_constant, + NULL_TREE, NULL_TREE, 0); /* Check to see if we have already given an error message. */ if (inside_init == error_mark_node) - ; + ; else if (require_constant && !TREE_CONSTANT (inside_init)) - { - error_init ("initializer element is not constant"); - inside_init = error_mark_node; - } + { + error_init ("initializer element is not constant"); + inside_init = error_mark_node; + } else if (require_constant - && !initializer_constant_valid_p (inside_init, - TREE_TYPE (inside_init))) - { - error_init ("initializer element is not computable at load time"); - inside_init = error_mark_node; - } + && !initializer_constant_valid_p (inside_init, + TREE_TYPE (inside_init))) + { + error_init ("initializer element is not computable at load time"); + inside_init = error_mark_node; + } else if (require_constant && !maybe_const) - pedwarn_init (init_loc, 0, - "initializer element is not a constant expression"); + pedwarn_init (init_loc, 0, + "initializer element is not a constant expression"); return inside_init; } @@ -6478,13 +6505,13 @@ { require_constant_value = TREE_STATIC (decl); require_constant_elements - = ((TREE_STATIC (decl) || (pedantic && !flag_isoc99)) - /* For a scalar, you can always use any value to initialize, - even within braces. */ - && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE - || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE)); + = ((TREE_STATIC (decl) || (pedantic && !flag_isoc99)) + /* For a scalar, you can always use any value to initialize, + even within braces. */ + && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE + || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE + || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE)); locus = identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (decl))); } else @@ -6631,10 +6658,10 @@ TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); } else - { - constructor_index = bitsize_zero_node; - constructor_max_index = NULL_TREE; - } + { + constructor_index = bitsize_zero_node; + constructor_max_index = NULL_TREE; + } constructor_unfilled_index = constructor_index; } @@ -6642,7 +6669,7 @@ { /* Vectors are like simple fixed-size arrays. */ constructor_max_index = - build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1); + build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1); constructor_index = bitsize_zero_node; constructor_unfilled_index = constructor_index; } @@ -6750,17 +6777,17 @@ if (constructor_type == 0) ; else if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) + || TREE_CODE (constructor_type) == UNION_TYPE) { /* Don't die if there are extra init elts at the end. */ if (constructor_fields == 0) - constructor_type = 0; + constructor_type = 0; else - { - constructor_type = TREE_TYPE (constructor_fields); - push_member_name (constructor_fields); - constructor_depth++; - } + { + constructor_type = TREE_TYPE (constructor_fields); + push_member_name (constructor_fields); + constructor_depth++; + } } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { @@ -6796,7 +6823,7 @@ } if (TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) + || TREE_CODE (constructor_type) == UNION_TYPE) { constructor_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ @@ -6811,7 +6838,7 @@ { /* Vectors are like simple fixed-size arrays. */ constructor_max_index = - build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1); + build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1); constructor_index = convert (bitsizetype, integer_zero_node); constructor_unfilled_index = constructor_index; } @@ -6839,7 +6866,7 @@ TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); } else - constructor_index = bitsize_zero_node; + constructor_index = bitsize_zero_node; constructor_unfilled_index = constructor_index; if (value && TREE_CODE (value) == STRING_CST) @@ -6853,7 +6880,7 @@ else { if (constructor_type != error_mark_node) - warning_init (0, "braces around scalar initializer"); + warning_init (0, "braces around scalar initializer"); constructor_fields = constructor_type; constructor_unfilled_fields = constructor_type; } @@ -6882,7 +6909,7 @@ if (implicit == 0) { /* When we come to an explicit close brace, - pop any inner levels that didn't have explicit braces. */ + pop any inner levels that didn't have explicit braces. */ while (constructor_stack->implicit) { process_init_element (pop_init_level (1, braced_init_obstack), @@ -6905,9 +6932,9 @@ && !TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type))) { /* Silently discard empty initializations. The parser will - already have pedwarned for empty brackets. */ + already have pedwarned for empty brackets. */ if (integer_zerop (constructor_unfilled_index)) - constructor_type = NULL_TREE; + constructor_type = NULL_TREE; else { gcc_assert (!TYPE_SIZE (constructor_type)); @@ -6918,6 +6945,7 @@ pedwarn_init (input_location, OPT_pedantic, "initialization of a flexible array member"); + /* We have already issued an error message for the existence of a flexible array member not at the end of the structure. Discard the initializer so that we do not die later. */ @@ -6945,8 +6973,8 @@ push_member_name (constructor_unfilled_fields); warning_init (OPT_Wmissing_field_initializers, "missing initializer"); - RESTORE_SPELLING_DEPTH (constructor_depth); - } + RESTORE_SPELLING_DEPTH (constructor_depth); + } } /* Pad out the end of the structure. */ @@ -6957,49 +6985,49 @@ else if (constructor_type == 0) ; else if (TREE_CODE (constructor_type) != RECORD_TYPE - && TREE_CODE (constructor_type) != UNION_TYPE - && TREE_CODE (constructor_type) != ARRAY_TYPE - && TREE_CODE (constructor_type) != VECTOR_TYPE) + && TREE_CODE (constructor_type) != UNION_TYPE + && TREE_CODE (constructor_type) != ARRAY_TYPE + && TREE_CODE (constructor_type) != VECTOR_TYPE) { /* A nonincremental scalar initializer--just return - the element, after verifying there is just one. */ + the element, after verifying there is just one. */ if (VEC_empty (constructor_elt,constructor_elements)) - { - if (!constructor_erroneous) - error_init ("empty scalar initializer"); - ret.value = error_mark_node; - } + { + if (!constructor_erroneous) + error_init ("empty scalar initializer"); + ret.value = error_mark_node; + } else if (VEC_length (constructor_elt,constructor_elements) != 1) - { - error_init ("extra elements in scalar initializer"); - ret.value = VEC_index (constructor_elt,constructor_elements,0)->value; - } + { + error_init ("extra elements in scalar initializer"); + ret.value = VEC_index (constructor_elt,constructor_elements,0)->value; + } else - ret.value = VEC_index (constructor_elt,constructor_elements,0)->value; + ret.value = VEC_index (constructor_elt,constructor_elements,0)->value; } else { if (constructor_erroneous) - ret.value = error_mark_node; + ret.value = error_mark_node; else - { - ret.value = build_constructor (constructor_type, - constructor_elements); - if (constructor_constant) - TREE_CONSTANT (ret.value) = 1; - if (constructor_constant && constructor_simple) - TREE_STATIC (ret.value) = 1; - if (constructor_nonconst) - CONSTRUCTOR_NON_CONST (ret.value) = 1; - } + { + ret.value = build_constructor (constructor_type, + constructor_elements); + if (constructor_constant) + TREE_CONSTANT (ret.value) = 1; + if (constructor_constant && constructor_simple) + TREE_STATIC (ret.value) = 1; + if (constructor_nonconst) + CONSTRUCTOR_NON_CONST (ret.value) = 1; + } } if (ret.value && TREE_CODE (ret.value) != CONSTRUCTOR) { if (constructor_nonconst) - ret.original_code = C_MAYBE_CONST_EXPR; + ret.original_code = C_MAYBE_CONST_EXPR; else if (ret.original_code == C_MAYBE_CONST_EXPR) - ret.original_code = ERROR_MARK; + ret.original_code = ERROR_MARK; } constructor_type = p->type; @@ -7054,7 +7082,7 @@ gcc_assert (!constructor_range_stack); /* Designator list starts at the level of closest explicit - braces. */ + braces. */ while (constructor_stack->implicit) { process_init_element (pop_init_level (1, braced_init_obstack), @@ -7070,7 +7098,7 @@ case UNION_TYPE: subtype = TREE_TYPE (constructor_fields); if (subtype != error_mark_node) - subtype = TYPE_MAIN_VARIANT (subtype); + subtype = TYPE_MAIN_VARIANT (subtype); break; case ARRAY_TYPE: subtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); @@ -7144,18 +7172,18 @@ { first = c_fully_fold (first, false, NULL); if (TREE_CODE (first) == INTEGER_CST) - pedwarn_init (input_location, OPT_pedantic, - "array index in initializer is not " - "an integer constant expression"); + pedwarn_init (input_location, OPT_pedantic, + "array index in initializer is not " + "an integer constant expression"); } if (last && TREE_CODE (last) != INTEGER_CST) { last = c_fully_fold (last, false, NULL); if (TREE_CODE (last) == INTEGER_CST) - pedwarn_init (input_location, OPT_pedantic, - "array index in initializer is not " - "an integer constant expression"); + pedwarn_init (input_location, OPT_pedantic, + "array index in initializer is not " + "an integer constant expression"); } if (TREE_CODE (first) != INTEGER_CST) @@ -7167,35 +7195,35 @@ else if (tree_int_cst_sgn (first) == -1) error_init ("array index in initializer exceeds array bounds"); else if (constructor_max_index - && tree_int_cst_lt (constructor_max_index, first)) + && tree_int_cst_lt (constructor_max_index, first)) error_init ("array index in initializer exceeds array bounds"); else { constant_expression_warning (first); if (last) - constant_expression_warning (last); + constant_expression_warning (last); constructor_index = convert (bitsizetype, first); if (last) - { - if (tree_int_cst_equal (first, last)) - last = 0; - else if (tree_int_cst_lt (last, first)) - { - error_init ("empty index range in initializer"); - last = 0; - } - else - { - last = convert (bitsizetype, last); - if (constructor_max_index != 0 - && tree_int_cst_lt (constructor_max_index, last)) - { - error_init ("array index range in initializer exceeds array bounds"); - last = 0; - } - } - } + { + if (tree_int_cst_equal (first, last)) + last = 0; + else if (tree_int_cst_lt (last, first)) + { + error_init ("empty index range in initializer"); + last = 0; + } + else + { + last = convert (bitsizetype, last); + if (constructor_max_index != 0 + && tree_int_cst_lt (constructor_max_index, last)) + { + error_init ("array index range in initializer exceeds array bounds"); + last = 0; + } + } + } designator_depth++; designator_erroneous = 0; @@ -7227,7 +7255,7 @@ if (field == 0) error ("unknown field %qE specified in initializer", fieldname); - else + else do { constructor_fields = TREE_VALUE (field); @@ -7243,8 +7271,9 @@ } } while (field != NULL_TREE); -} - + +} + /* Add a new initializer to the tree of pending initializers. PURPOSE identifies the initializer, either array index or field in a structure. VALUE is the value of that index or field. If ORIGTYPE is not @@ -7267,26 +7296,26 @@ if (TREE_CODE (constructor_type) == ARRAY_TYPE) { while (*q != 0) - { - p = *q; - if (tree_int_cst_lt (purpose, p->purpose)) - q = &p->left; - else if (tree_int_cst_lt (p->purpose, purpose)) - q = &p->right; - else - { - if (!implicit) - { - if (TREE_SIDE_EFFECTS (p->value)) - warning_init (0, "initialized field with side-effects overwritten"); - else if (warn_override_init) - warning_init (OPT_Woverride_init, "initialized field overwritten"); - } - p->value = value; - p->origtype = origtype; - return; - } - } + { + p = *q; + if (tree_int_cst_lt (purpose, p->purpose)) + q = &p->left; + else if (tree_int_cst_lt (p->purpose, purpose)) + q = &p->right; + else + { + if (!implicit) + { + if (TREE_SIDE_EFFECTS (p->value)) + warning_init (0, "initialized field with side-effects overwritten"); + else if (warn_override_init) + warning_init (OPT_Woverride_init, "initialized field overwritten"); + } + p->value = value; + p->origtype = origtype; + return; + } + } } else { @@ -7294,26 +7323,26 @@ bitpos = bit_position (purpose); while (*q != NULL) - { - p = *q; - if (tree_int_cst_lt (bitpos, bit_position (p->purpose))) - q = &p->left; - else if (p->purpose != purpose) - q = &p->right; - else - { - if (!implicit) - { - if (TREE_SIDE_EFFECTS (p->value)) - warning_init (0, "initialized field with side-effects overwritten"); - else if (warn_override_init) - warning_init (OPT_Woverride_init, "initialized field overwritten"); - } - p->value = value; - p->origtype = origtype; - return; - } - } + { + p = *q; + if (tree_int_cst_lt (bitpos, bit_position (p->purpose))) + q = &p->left; + else if (p->purpose != purpose) + q = &p->right; + else + { + if (!implicit) + { + if (TREE_SIDE_EFFECTS (p->value)) + warning_init (0, "initialized field with side-effects overwritten"); + else if (warn_override_init) + warning_init (OPT_Woverride_init, "initialized field overwritten"); + } + p->value = value; + p->origtype = origtype; + return; + } + } } r = (struct init_node *) obstack_alloc (braced_init_obstack, @@ -7333,150 +7362,150 @@ struct init_node *s; if (r == p->left) - { - if (p->balance == 0) - p->balance = -1; - else if (p->balance < 0) - { - if (r->balance < 0) - { - /* L rotation. */ - p->left = r->right; - if (p->left) - p->left->parent = p; - r->right = p; - - p->balance = 0; - r->balance = 0; - - s = p->parent; - p->parent = r; - r->parent = s; - if (s) - { - if (s->left == p) - s->left = r; - else - s->right = r; - } - else - constructor_pending_elts = r; - } - else - { - /* LR rotation. */ - struct init_node *t = r->right; - - r->right = t->left; - if (r->right) - r->right->parent = r; - t->left = r; - - p->left = t->right; - if (p->left) - p->left->parent = p; - t->right = p; - - p->balance = t->balance < 0; - r->balance = -(t->balance > 0); - t->balance = 0; - - s = p->parent; - p->parent = t; - r->parent = t; - t->parent = s; - if (s) - { - if (s->left == p) - s->left = t; - else - s->right = t; - } - else - constructor_pending_elts = t; - } - break; - } - else - { - /* p->balance == +1; growth of left side balances the node. */ - p->balance = 0; - break; - } - } + { + if (p->balance == 0) + p->balance = -1; + else if (p->balance < 0) + { + if (r->balance < 0) + { + /* L rotation. */ + p->left = r->right; + if (p->left) + p->left->parent = p; + r->right = p; + + p->balance = 0; + r->balance = 0; + + s = p->parent; + p->parent = r; + r->parent = s; + if (s) + { + if (s->left == p) + s->left = r; + else + s->right = r; + } + else + constructor_pending_elts = r; + } + else + { + /* LR rotation. */ + struct init_node *t = r->right; + + r->right = t->left; + if (r->right) + r->right->parent = r; + t->left = r; + + p->left = t->right; + if (p->left) + p->left->parent = p; + t->right = p; + + p->balance = t->balance < 0; + r->balance = -(t->balance > 0); + t->balance = 0; + + s = p->parent; + p->parent = t; + r->parent = t; + t->parent = s; + if (s) + { + if (s->left == p) + s->left = t; + else + s->right = t; + } + else + constructor_pending_elts = t; + } + break; + } + else + { + /* p->balance == +1; growth of left side balances the node. */ + p->balance = 0; + break; + } + } else /* r == p->right */ - { - if (p->balance == 0) - /* Growth propagation from right side. */ - p->balance++; - else if (p->balance > 0) - { - if (r->balance > 0) - { - /* R rotation. */ - p->right = r->left; - if (p->right) - p->right->parent = p; - r->left = p; - - p->balance = 0; - r->balance = 0; - - s = p->parent; - p->parent = r; - r->parent = s; - if (s) - { - if (s->left == p) - s->left = r; - else - s->right = r; - } - else - constructor_pending_elts = r; - } - else /* r->balance == -1 */ - { - /* RL rotation */ - struct init_node *t = r->left; - - r->left = t->right; - if (r->left) - r->left->parent = r; - t->right = r; - - p->right = t->left; - if (p->right) - p->right->parent = p; - t->left = p; - - r->balance = (t->balance < 0); - p->balance = -(t->balance > 0); - t->balance = 0; - - s = p->parent; - p->parent = t; - r->parent = t; - t->parent = s; - if (s) - { - if (s->left == p) - s->left = t; - else - s->right = t; - } - else - constructor_pending_elts = t; - } - break; - } - else - { - /* p->balance == -1; growth of right side balances the node. */ - p->balance = 0; - break; - } - } + { + if (p->balance == 0) + /* Growth propagation from right side. */ + p->balance++; + else if (p->balance > 0) + { + if (r->balance > 0) + { + /* R rotation. */ + p->right = r->left; + if (p->right) + p->right->parent = p; + r->left = p; + + p->balance = 0; + r->balance = 0; + + s = p->parent; + p->parent = r; + r->parent = s; + if (s) + { + if (s->left == p) + s->left = r; + else + s->right = r; + } + else + constructor_pending_elts = r; + } + else /* r->balance == -1 */ + { + /* RL rotation */ + struct init_node *t = r->left; + + r->left = t->right; + if (r->left) + r->left->parent = r; + t->right = r; + + p->right = t->left; + if (p->right) + p->right->parent = p; + t->left = p; + + r->balance = (t->balance < 0); + p->balance = -(t->balance > 0); + t->balance = 0; + + s = p->parent; + p->parent = t; + r->parent = t; + t->parent = s; + if (s) + { + if (s->left == p) + s->left = t; + else + s->right = t; + } + else + constructor_pending_elts = t; + } + break; + } + else + { + /* p->balance == -1; growth of right side balances the node. */ + p->balance = 0; + break; + } + } r = p; p = p->parent; @@ -7506,19 +7535,19 @@ constructor_unfilled_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ while (constructor_unfilled_fields != 0 - && DECL_C_BIT_FIELD (constructor_unfilled_fields) - && DECL_NAME (constructor_unfilled_fields) == 0) - constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); + && DECL_C_BIT_FIELD (constructor_unfilled_fields) + && DECL_NAME (constructor_unfilled_fields) == 0) + constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { if (TYPE_DOMAIN (constructor_type)) - constructor_unfilled_index - = convert (bitsizetype, - TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); + constructor_unfilled_index + = convert (bitsizetype, + TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); else - constructor_unfilled_index = bitsize_zero_node; + constructor_unfilled_index = bitsize_zero_node; } constructor_incremental = 0; } @@ -7547,47 +7576,47 @@ purpose = size_binop (PLUS_EXPR, purpose, bitsize_one_node)) { if (wchar_bytes == 1) - { - val[1] = (unsigned char) *p++; - val[0] = 0; - } + { + val[1] = (unsigned char) *p++; + val[0] = 0; + } else - { - val[0] = 0; - val[1] = 0; - for (byte = 0; byte < wchar_bytes; byte++) - { - if (BYTES_BIG_ENDIAN) - bitpos = (wchar_bytes - byte - 1) * charwidth; - else - bitpos = byte * charwidth; - val[bitpos < HOST_BITS_PER_WIDE_INT] - |= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++)) - << (bitpos % HOST_BITS_PER_WIDE_INT); - } - } + { + val[0] = 0; + val[1] = 0; + for (byte = 0; byte < wchar_bytes; byte++) + { + if (BYTES_BIG_ENDIAN) + bitpos = (wchar_bytes - byte - 1) * charwidth; + else + bitpos = byte * charwidth; + val[bitpos < HOST_BITS_PER_WIDE_INT] + |= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++)) + << (bitpos % HOST_BITS_PER_WIDE_INT); + } + } if (!TYPE_UNSIGNED (type)) - { - bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR; - if (bitpos < HOST_BITS_PER_WIDE_INT) - { - if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1))) - { - val[1] |= ((HOST_WIDE_INT) -1) << bitpos; - val[0] = -1; - } - } - else if (bitpos == HOST_BITS_PER_WIDE_INT) - { - if (val[1] < 0) - val[0] = -1; - } - else if (val[0] & (((HOST_WIDE_INT) 1) - << (bitpos - 1 - HOST_BITS_PER_WIDE_INT))) - val[0] |= ((HOST_WIDE_INT) -1) - << (bitpos - HOST_BITS_PER_WIDE_INT); - } + { + bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR; + if (bitpos < HOST_BITS_PER_WIDE_INT) + { + if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1))) + { + val[1] |= ((HOST_WIDE_INT) -1) << bitpos; + val[0] = -1; + } + } + else if (bitpos == HOST_BITS_PER_WIDE_INT) + { + if (val[1] < 0) + val[0] = -1; + } + else if (val[0] & (((HOST_WIDE_INT) 1) + << (bitpos - 1 - HOST_BITS_PER_WIDE_INT))) + val[0] |= ((HOST_WIDE_INT) -1) + << (bitpos - HOST_BITS_PER_WIDE_INT); + } value = build_int_cst_wide (type, val[1], val[0]); add_pending_init (purpose, value, NULL_TREE, false, @@ -7613,14 +7642,14 @@ p = constructor_pending_elts; while (p) - { - if (tree_int_cst_lt (field, p->purpose)) - p = p->left; - else if (tree_int_cst_lt (p->purpose, field)) - p = p->right; - else - return p->value; - } + { + if (tree_int_cst_lt (field, p->purpose)) + p = p->left; + else if (tree_int_cst_lt (p->purpose, field)) + p = p->right; + else + return p->value; + } } else if (TREE_CODE (constructor_type) == RECORD_TYPE) { @@ -7634,21 +7663,21 @@ p = constructor_pending_elts; while (p) - { - if (field == p->purpose) - return p->value; - else if (tree_int_cst_lt (bitpos, bit_position (p->purpose))) - p = p->left; - else - p = p->right; - } + { + if (field == p->purpose) + return p->value; + else if (tree_int_cst_lt (bitpos, bit_position (p->purpose))) + p = p->left; + else + p = p->right; + } } else if (TREE_CODE (constructor_type) == UNION_TYPE) { if (!VEC_empty (constructor_elt, constructor_elements) - && (VEC_last (constructor_elt, constructor_elements)->index - == field)) - return VEC_last (constructor_elt, constructor_elements)->value; + && (VEC_last (constructor_elt, constructor_elements)->index + == field)) + return VEC_last (constructor_elt, constructor_elements)->value; } return 0; } @@ -7689,20 +7718,20 @@ } if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE && (TREE_CODE (value) == STRING_CST - || TREE_CODE (value) == COMPOUND_LITERAL_EXPR) + || TREE_CODE (value) == COMPOUND_LITERAL_EXPR) && !(TREE_CODE (value) == STRING_CST - && TREE_CODE (type) == ARRAY_TYPE - && INTEGRAL_TYPE_P (TREE_TYPE (type))) + && TREE_CODE (type) == ARRAY_TYPE + && INTEGRAL_TYPE_P (TREE_TYPE (type))) && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)), - TYPE_MAIN_VARIANT (type))) + TYPE_MAIN_VARIANT (type))) value = array_to_pointer_conversion (input_location, value); if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR && require_constant_value && !flag_isoc99 && pending) { /* As an extension, allow initializing objects with static storage - duration with compound literals (which are then treated just as - the brace enclosed list they contain). */ + duration with compound literals (which are then treated just as + the brace enclosed list they contain). */ tree decl = COMPOUND_LITERAL_EXPR_DECL (value); value = DECL_INITIAL (decl); } @@ -7720,10 +7749,10 @@ else if (!TREE_CONSTANT (value)) constructor_constant = 0; else if (!initializer_constant_valid_p (value, TREE_TYPE (value)) - || ((TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - && DECL_C_BIT_FIELD (field) - && TREE_CODE (value) != INTEGER_CST)) + || ((TREE_CODE (constructor_type) == RECORD_TYPE + || TREE_CODE (constructor_type) == UNION_TYPE) + && DECL_C_BIT_FIELD (field) + && TREE_CODE (value) != INTEGER_CST)) constructor_simple = 0; if (!maybe_const) constructor_nonconst = 1; @@ -7731,18 +7760,18 @@ if (!initializer_constant_valid_p (value, TREE_TYPE (value))) { if (require_constant_value) - { - error_init ("initializer element is not constant"); - value = error_mark_node; - } + { + error_init ("initializer element is not constant"); + value = error_mark_node; + } else if (require_constant_elements) - pedwarn (input_location, 0, - "initializer element is not computable at load time"); + pedwarn (input_location, 0, + "initializer element is not computable at load time"); } else if (!maybe_const - && (require_constant_value || require_constant_elements)) + && (require_constant_value || require_constant_elements)) pedwarn_init (input_location, 0, - "initializer element is not a constant expression"); + "initializer element is not a constant expression"); /* Issue -Wc++-compat warnings about initializing a bitfield with enum type. */ @@ -7751,15 +7780,15 @@ && TREE_CODE (field) == FIELD_DECL && DECL_BIT_FIELD_TYPE (field) != NULL_TREE && (TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field)) - != TYPE_MAIN_VARIANT (type)) + != TYPE_MAIN_VARIANT (type)) && TREE_CODE (DECL_BIT_FIELD_TYPE (field)) == ENUMERAL_TYPE) { tree checktype = origtype != NULL_TREE ? origtype : TREE_TYPE (value); if (checktype != error_mark_node - && (TYPE_MAIN_VARIANT (checktype) - != TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field)))) - warning_init (OPT_Wc___compat, - "enum conversion in initialization is invalid in C++"); + && (TYPE_MAIN_VARIANT (checktype) + != TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field)))) + warning_init (OPT_Wc___compat, + "enum conversion in initialization is invalid in C++"); } /* If this field is empty (and not at the end of structure), @@ -7775,7 +7804,7 @@ if (semantic_type) value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value); value = digest_init (input_location, type, value, origtype, npc, - strict_string, require_constant_value); + strict_string, require_constant_value); if (value == error_mark_node) { constructor_erroneous = 1; @@ -7788,7 +7817,7 @@ put it on constructor_pending_elts. */ if (TREE_CODE (constructor_type) == ARRAY_TYPE && (!constructor_incremental - || !tree_int_cst_equal (field, constructor_unfilled_index))) + || !tree_int_cst_equal (field, constructor_unfilled_index))) { if (constructor_incremental && tree_int_cst_lt (field, constructor_unfilled_index)) @@ -7799,12 +7828,12 @@ return; } else if (TREE_CODE (constructor_type) == RECORD_TYPE - && (!constructor_incremental - || field != constructor_unfilled_fields)) + && (!constructor_incremental + || field != constructor_unfilled_fields)) { /* We do this for records but not for unions. In a union, - no matter which field is specified, it can be initialized - right away since it starts at the beginning of the union. */ + no matter which field is specified, it can be initialized + right away since it starts at the beginning of the union. */ if (constructor_incremental) { if (!constructor_unfilled_fields) @@ -7826,17 +7855,17 @@ return; } else if (TREE_CODE (constructor_type) == UNION_TYPE - && !VEC_empty (constructor_elt, constructor_elements)) + && !VEC_empty (constructor_elt, constructor_elements)) { if (!implicit) - { - if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt, - constructor_elements)->value)) - warning_init (0, - "initialized field with side-effects overwritten"); - else if (warn_override_init) - warning_init (OPT_Woverride_init, "initialized field overwritten"); - } + { + if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt, + constructor_elements)->value)) + warning_init (0, + "initialized field with side-effects overwritten"); + else if (warn_override_init) + warning_init (OPT_Woverride_init, "initialized field overwritten"); + } /* We can have just one union field set. */ constructor_elements = 0; @@ -7853,7 +7882,7 @@ if (TREE_CODE (constructor_type) == ARRAY_TYPE) constructor_unfilled_index = size_binop_loc (input_location, PLUS_EXPR, constructor_unfilled_index, - bitsize_one_node); + bitsize_one_node); else if (TREE_CODE (constructor_type) == RECORD_TYPE) { constructor_unfilled_fields @@ -8052,7 +8081,7 @@ && integer_zerop (constructor_unfilled_index)) { if (constructor_stack->replacement_value.value) - error_init ("excess elements in char array initializer"); + error_init ("excess elements in char array initializer"); constructor_stack->replacement_value = value; return; } @@ -8085,29 +8114,29 @@ process_init_element (pop_init_level (1, braced_init_obstack), true, braced_init_obstack); else - break; + break; } /* In the case of [LO ... HI] = VALUE, only evaluate VALUE once. */ if (constructor_range_stack) { /* If value is a compound literal and we'll be just using its - content, don't put it into a SAVE_EXPR. */ + content, don't put it into a SAVE_EXPR. */ if (TREE_CODE (value.value) != COMPOUND_LITERAL_EXPR - || !require_constant_value - || flag_isoc99) - { - tree semantic_type = NULL_TREE; - if (TREE_CODE (value.value) == EXCESS_PRECISION_EXPR) - { - semantic_type = TREE_TYPE (value.value); - value.value = TREE_OPERAND (value.value, 0); - } - value.value = c_save_expr (value.value); - if (semantic_type) - value.value = build1 (EXCESS_PRECISION_EXPR, semantic_type, - value.value); - } + || !require_constant_value + || flag_isoc99) + { + tree semantic_type = NULL_TREE; + if (TREE_CODE (value.value) == EXCESS_PRECISION_EXPR) + { + semantic_type = TREE_TYPE (value.value); + value.value = TREE_OPERAND (value.value, 0); + } + value.value = c_save_expr (value.value); + if (semantic_type) + value.value = build1 (EXCESS_PRECISION_EXPR, semantic_type, + value.value); + } } while (1) @@ -8357,14 +8386,14 @@ } /* Handle the sole element allowed in a braced initializer - for a scalar variable. */ + for a scalar variable. */ else if (constructor_type != error_mark_node - && constructor_fields == 0) - { - pedwarn_init (input_location, 0, - "excess elements in scalar initializer"); - break; - } + && constructor_fields == 0) + { + pedwarn_init (input_location, 0, + "excess elements in scalar initializer"); + break; + } else { if (value.value) @@ -8376,7 +8405,7 @@ } /* Handle range initializers either at this level or anywhere higher - in the designator stack. */ + in the designator stack. */ if (constructor_range_stack) { struct constructor_range_stack *p, *range_stack; @@ -8452,7 +8481,7 @@ are subtly different. We use a ASM_EXPR node to represent this. */ tree build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, - tree clobbers, tree labels, bool simple) + tree clobbers, tree labels, bool simple) { tree tail; tree args; @@ -8474,37 +8503,37 @@ tree output = TREE_VALUE (tail); /* ??? Really, this should not be here. Users should be using a - proper lvalue, dammit. But there's a long history of using casts - in the output operands. In cases like longlong.h, this becomes a - primitive form of typechecking -- if the cast can be removed, then - the output operand had a type of the proper width; otherwise we'll - get an error. Gross, but ... */ + proper lvalue, dammit. But there's a long history of using casts + in the output operands. In cases like longlong.h, this becomes a + primitive form of typechecking -- if the cast can be removed, then + the output operand had a type of the proper width; otherwise we'll + get an error. Gross, but ... */ STRIP_NOPS (output); if (!lvalue_or_else (loc, output, lv_asm)) output = error_mark_node; if (output != error_mark_node - && (TREE_READONLY (output) - || TYPE_READONLY (TREE_TYPE (output)) - || ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (output)) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (TREE_TYPE (output))))) - readonly_error (output, lv_asm); + && (TREE_READONLY (output) + || TYPE_READONLY (TREE_TYPE (output)) + || ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE + || TREE_CODE (TREE_TYPE (output)) == UNION_TYPE) + && C_TYPE_FIELDS_READONLY (TREE_TYPE (output))))) + readonly_error (output, lv_asm); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail))); oconstraints[i] = constraint; if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) - { - /* If the operand is going to end up in memory, - mark it addressable. */ - if (!allows_reg && !c_mark_addressable (output)) - output = error_mark_node; - } + &allows_mem, &allows_reg, &is_inout)) + { + /* If the operand is going to end up in memory, + mark it addressable. */ + if (!allows_reg && !c_mark_addressable (output)) + output = error_mark_node; + } else - output = error_mark_node; + output = error_mark_node; TREE_VALUE (tail) = output; } @@ -8517,21 +8546,21 @@ input = TREE_VALUE (tail); if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - oconstraints, &allows_mem, &allows_reg)) - { - /* If the operand is going to end up in memory, - mark it addressable. */ - if (!allows_reg && allows_mem) - { - /* Strip the nops as we allow this case. FIXME, this really - should be rejected or made deprecated. */ - STRIP_NOPS (input); - if (!c_mark_addressable (input)) - input = error_mark_node; - } - } + oconstraints, &allows_mem, &allows_reg)) + { + /* If the operand is going to end up in memory, + mark it addressable. */ + if (!allows_reg && allows_mem) + { + /* Strip the nops as we allow this case. FIXME, this really + should be rejected or made deprecated. */ + STRIP_NOPS (input); + if (!c_mark_addressable (input)) + input = error_mark_node; + } + } else - input = error_mark_node; + input = error_mark_node; TREE_VALUE (tail) = input; } @@ -8596,117 +8625,117 @@ if (TREE_THIS_VOLATILE (current_function_decl)) warning_at (loc, 0, - "function declared % has a % statement"); + "function declared % has a % statement"); if (retval) { tree semantic_type = NULL_TREE; npc = null_pointer_constant_p (retval); if (TREE_CODE (retval) == EXCESS_PRECISION_EXPR) - { - semantic_type = TREE_TYPE (retval); - retval = TREE_OPERAND (retval, 0); - } + { + semantic_type = TREE_TYPE (retval); + retval = TREE_OPERAND (retval, 0); + } retval = c_fully_fold (retval, false, NULL); if (semantic_type) - retval = build1 (EXCESS_PRECISION_EXPR, semantic_type, retval); + retval = build1 (EXCESS_PRECISION_EXPR, semantic_type, retval); } if (!retval) { current_function_returns_null = 1; if ((warn_return_type || flag_isoc99) - && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) - { - pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wreturn_type, - "% with no value, in " - "function returning non-void"); - no_warning = true; - } + && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) + { + pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wreturn_type, + "% with no value, in " + "function returning non-void"); + no_warning = true; + } } else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) { current_function_returns_null = 1; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - pedwarn (loc, 0, - "% with a value, in function returning void"); + pedwarn (loc, 0, + "% with a value, in function returning void"); else - pedwarn (loc, OPT_pedantic, "ISO C forbids " - "% with expression, in function returning void"); + pedwarn (loc, OPT_pedantic, "ISO C forbids " + "% with expression, in function returning void"); } else { tree t = convert_for_assignment (loc, valtype, retval, origtype, - ic_return, - npc, NULL_TREE, NULL_TREE, 0); + ic_return, + npc, NULL_TREE, NULL_TREE, 0); tree res = DECL_RESULT (current_function_decl); tree inner; current_function_returns_value = 1; if (t == error_mark_node) - return NULL_TREE; + return NULL_TREE; inner = t = convert (TREE_TYPE (res), t); /* Strip any conversions, additions, and subtractions, and see if - we are returning the address of a local variable. Warn if so. */ + we are returning the address of a local variable. Warn if so. */ while (1) - { - switch (TREE_CODE (inner)) - { - CASE_CONVERT: - case NON_LVALUE_EXPR: - case PLUS_EXPR: - case POINTER_PLUS_EXPR: - inner = TREE_OPERAND (inner, 0); - continue; - - case MINUS_EXPR: - /* If the second operand of the MINUS_EXPR has a pointer - type (or is converted from it), this may be valid, so - don't give a warning. */ - { - tree op1 = TREE_OPERAND (inner, 1); - - while (!POINTER_TYPE_P (TREE_TYPE (op1)) - && (CONVERT_EXPR_P (op1) - || TREE_CODE (op1) == NON_LVALUE_EXPR)) - op1 = TREE_OPERAND (op1, 0); - - if (POINTER_TYPE_P (TREE_TYPE (op1))) - break; - - inner = TREE_OPERAND (inner, 0); - continue; - } - - case ADDR_EXPR: - inner = TREE_OPERAND (inner, 0); - - while (REFERENCE_CLASS_P (inner) - && TREE_CODE (inner) != INDIRECT_REF) - inner = TREE_OPERAND (inner, 0); - - if (DECL_P (inner) - && !DECL_EXTERNAL (inner) - && !TREE_STATIC (inner) - && DECL_CONTEXT (inner) == current_function_decl) - warning_at (loc, - 0, "function returns address of local variable"); - break; - - default: - break; - } - - break; - } + { + switch (TREE_CODE (inner)) + { + CASE_CONVERT: + case NON_LVALUE_EXPR: + case PLUS_EXPR: + case POINTER_PLUS_EXPR: + inner = TREE_OPERAND (inner, 0); + continue; + + case MINUS_EXPR: + /* If the second operand of the MINUS_EXPR has a pointer + type (or is converted from it), this may be valid, so + don't give a warning. */ + { + tree op1 = TREE_OPERAND (inner, 1); + + while (!POINTER_TYPE_P (TREE_TYPE (op1)) + && (CONVERT_EXPR_P (op1) + || TREE_CODE (op1) == NON_LVALUE_EXPR)) + op1 = TREE_OPERAND (op1, 0); + + if (POINTER_TYPE_P (TREE_TYPE (op1))) + break; + + inner = TREE_OPERAND (inner, 0); + continue; + } + + case ADDR_EXPR: + inner = TREE_OPERAND (inner, 0); + + while (REFERENCE_CLASS_P (inner) + && TREE_CODE (inner) != INDIRECT_REF) + inner = TREE_OPERAND (inner, 0); + + if (DECL_P (inner) + && !DECL_EXTERNAL (inner) + && !TREE_STATIC (inner) + && DECL_CONTEXT (inner) == current_function_decl) + warning_at (loc, + 0, "function returns address of local variable"); + break; + + default: + break; + } + + break; + } retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t); SET_EXPR_LOCATION (retval, loc); if (warn_sequence_point) - verify_sequence_points (retval); + verify_sequence_points (retval); } ret_stmt = build_stmt (loc, RETURN_EXPR, retval); @@ -8751,8 +8780,8 @@ tree c_start_case (location_t switch_loc, - location_t switch_cond_loc, - tree exp) + location_t switch_cond_loc, + tree exp) { tree orig_type = error_mark_node; struct c_switch *cs; @@ -8762,31 +8791,31 @@ orig_type = TREE_TYPE (exp); if (!INTEGRAL_TYPE_P (orig_type)) - { - if (orig_type != error_mark_node) - { - error_at (switch_cond_loc, "switch quantity not an integer"); - orig_type = error_mark_node; - } - exp = integer_zero_node; - } + { + if (orig_type != error_mark_node) + { + error_at (switch_cond_loc, "switch quantity not an integer"); + orig_type = error_mark_node; + } + exp = integer_zero_node; + } else - { - tree type = TYPE_MAIN_VARIANT (orig_type); - - if (!in_system_header - && (type == long_integer_type_node - || type == long_unsigned_type_node)) - warning_at (switch_cond_loc, - OPT_Wtraditional, "% switch expression not " - "converted to % in ISO C"); - - exp = c_fully_fold (exp, false, NULL); - exp = default_conversion (exp); - - if (warn_sequence_point) - verify_sequence_points (exp); - } + { + tree type = TYPE_MAIN_VARIANT (orig_type); + + if (!in_system_header + && (type == long_integer_type_node + || type == long_unsigned_type_node)) + warning_at (switch_cond_loc, + OPT_Wtraditional, "% switch expression not " + "converted to % in ISO C"); + + exp = c_fully_fold (exp, false, NULL); + exp = default_conversion (exp); + + if (warn_sequence_point) + verify_sequence_points (exp); + } } /* Add this new SWITCH_EXPR to the stack. */ @@ -8813,36 +8842,36 @@ { low_value = c_fully_fold (low_value, false, NULL); if (TREE_CODE (low_value) == INTEGER_CST) - pedwarn (input_location, OPT_pedantic, - "case label is not an integer constant expression"); + pedwarn (input_location, OPT_pedantic, + "case label is not an integer constant expression"); } if (high_value && TREE_CODE (high_value) != INTEGER_CST) { high_value = c_fully_fold (high_value, false, NULL); if (TREE_CODE (high_value) == INTEGER_CST) - pedwarn (input_location, OPT_pedantic, - "case label is not an integer constant expression"); + pedwarn (input_location, OPT_pedantic, + "case label is not an integer constant expression"); } if (c_switch_stack == NULL) { if (low_value) - error_at (loc, "case label not within a switch statement"); + error_at (loc, "case label not within a switch statement"); else - error_at (loc, "% label not within a switch statement"); + error_at (loc, "% label not within a switch statement"); return NULL_TREE; } if (c_check_switch_jump_warnings (c_switch_stack->bindings, - EXPR_LOCATION (c_switch_stack->switch_expr), - loc)) + EXPR_LOCATION (c_switch_stack->switch_expr), + loc)) return NULL_TREE; label = c_add_case_label (loc, c_switch_stack->cases, - SWITCH_COND (c_switch_stack->switch_expr), - c_switch_stack->orig_type, - low_value, high_value); + SWITCH_COND (c_switch_stack->switch_expr), + c_switch_stack->orig_type, + low_value, high_value); if (label == error_mark_node) label = NULL_TREE; return label; @@ -8861,8 +8890,8 @@ /* Emit warnings as needed. */ switch_location = EXPR_LOCATION (cs->switch_expr); c_do_switch_warnings (cs->cases, switch_location, - TREE_TYPE (cs->switch_expr), - SWITCH_COND (cs->switch_expr)); + TREE_TYPE (cs->switch_expr), + SWITCH_COND (cs->switch_expr)); /* Pop the stack. */ c_switch_stack = cs->next; @@ -8878,7 +8907,7 @@ void c_finish_if_stmt (location_t if_locus, tree cond, tree then_block, - tree else_block, bool nested_if) + tree else_block, bool nested_if) { tree stmt; @@ -8888,32 +8917,32 @@ tree inner_if = then_block; /* We know from the grammar productions that there is an IF nested - within THEN_BLOCK. Due to labels and c99 conditional declarations, - it might not be exactly THEN_BLOCK, but should be the last - non-container statement within. */ + within THEN_BLOCK. Due to labels and c99 conditional declarations, + it might not be exactly THEN_BLOCK, but should be the last + non-container statement within. */ while (1) - switch (TREE_CODE (inner_if)) - { - case COND_EXPR: - goto found; - case BIND_EXPR: - inner_if = BIND_EXPR_BODY (inner_if); - break; - case STATEMENT_LIST: - inner_if = expr_last (then_block); - break; - case TRY_FINALLY_EXPR: - case TRY_CATCH_EXPR: - inner_if = TREE_OPERAND (inner_if, 0); - break; - default: - gcc_unreachable (); - } + switch (TREE_CODE (inner_if)) + { + case COND_EXPR: + goto found; + case BIND_EXPR: + inner_if = BIND_EXPR_BODY (inner_if); + break; + case STATEMENT_LIST: + inner_if = expr_last (then_block); + break; + case TRY_FINALLY_EXPR: + case TRY_CATCH_EXPR: + inner_if = TREE_OPERAND (inner_if, 0); + break; + default: + gcc_unreachable (); + } found: if (COND_EXPR_ELSE (inner_if)) - warning_at (if_locus, OPT_Wparentheses, - "suggest explicit braces to avoid ambiguous %"); + warning_at (if_locus, OPT_Wparentheses, + "suggest explicit braces to avoid ambiguous %"); } stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block); @@ -8929,7 +8958,7 @@ void c_finish_loop (location_t start_locus, tree cond, tree incr, tree body, - tree blab, tree clab, bool cond_is_first) + tree blab, tree clab, bool cond_is_first) { tree entry = NULL, exit = NULL, t; @@ -8937,47 +8966,47 @@ if (cond && integer_zerop (cond)) { if (cond_is_first) - { - t = build_and_jump (&blab); - SET_EXPR_LOCATION (t, start_locus); - add_stmt (t); - } + { + t = build_and_jump (&blab); + SET_EXPR_LOCATION (t, start_locus); + add_stmt (t); + } } else { tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE); /* If we have an exit condition, then we build an IF with gotos either - out of the loop, or to the top of it. If there's no exit condition, - then we just build a jump back to the top. */ + out of the loop, or to the top of it. If there's no exit condition, + then we just build a jump back to the top. */ exit = build_and_jump (&LABEL_EXPR_LABEL (top)); if (cond && !integer_nonzerop (cond)) - { - /* Canonicalize the loop condition to the end. This means - generating a branch to the loop condition. Reuse the - continue label, if possible. */ - if (cond_is_first) - { - if (incr || !clab) - { - entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE); - t = build_and_jump (&LABEL_EXPR_LABEL (entry)); - } - else - t = build1 (GOTO_EXPR, void_type_node, clab); - SET_EXPR_LOCATION (t, start_locus); - add_stmt (t); - } - - t = build_and_jump (&blab); - if (cond_is_first) - exit = fold_build3_loc (start_locus, - COND_EXPR, void_type_node, cond, exit, t); - else - exit = fold_build3_loc (input_location, - COND_EXPR, void_type_node, cond, exit, t); - } + { + /* Canonicalize the loop condition to the end. This means + generating a branch to the loop condition. Reuse the + continue label, if possible. */ + if (cond_is_first) + { + if (incr || !clab) + { + entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE); + t = build_and_jump (&LABEL_EXPR_LABEL (entry)); + } + else + t = build1 (GOTO_EXPR, void_type_node, clab); + SET_EXPR_LOCATION (t, start_locus); + add_stmt (t); + } + + t = build_and_jump (&blab); + if (cond_is_first) + exit = fold_build3_loc (start_locus, + COND_EXPR, void_type_node, cond, exit, t); + else + exit = fold_build3_loc (input_location, + COND_EXPR, void_type_node, cond, exit, t); + } add_stmt (top); } @@ -9014,7 +9043,7 @@ if (!label) { if (!skip) - *label_p = label = create_artificial_label (loc); + *label_p = label = create_artificial_label (loc); } else if (TREE_CODE (label) == LABEL_DECL) ; @@ -9022,9 +9051,9 @@ { case 0: if (is_break) - error_at (loc, "break statement not within loop or switch"); + error_at (loc, "break statement not within loop or switch"); else - error_at (loc, "continue statement not within a loop"); + error_at (loc, "continue statement not within a loop"); return NULL_TREE; case 1: @@ -9055,7 +9084,7 @@ else if (!TREE_SIDE_EFFECTS (expr)) { if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr)) - warning_at (loc, OPT_Wunused_value, "statement with no effect"); + warning_at (loc, OPT_Wunused_value, "statement with no effect"); } else warn_if_unused_value (expr, loc); @@ -9134,8 +9163,8 @@ ret = c_begin_compound_stmt (true); c_bindings_start_stmt_expr (c_switch_stack == NULL - ? NULL - : c_switch_stack->bindings); + ? NULL + : c_switch_stack->bindings); /* Mark the current statement list as belonging to a statement list. */ STATEMENT_LIST_STMT_EXPR (ret) = 1; @@ -9155,8 +9184,8 @@ body = c_end_compound_stmt (loc, body, true); c_bindings_end_stmt_expr (c_switch_stack == NULL - ? NULL - : c_switch_stack->bindings); + ? NULL + : c_switch_stack->bindings); /* Locate the last statement in BODY. See c_end_compound_stmt about always returning a BIND_EXPR. */ @@ -9170,23 +9199,23 @@ /* This can happen with degenerate cases like ({ }). No value. */ if (!TREE_SIDE_EFFECTS (last)) - return body; + return body; /* If we're supposed to generate side effects warnings, process - all of the statements except the last. */ + all of the statements except the last. */ if (warn_unused_value) - { - for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i)) - { - location_t tloc; - tree t = tsi_stmt (i); - - tloc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) : loc; - emit_side_effect_warnings (tloc, t); - } - } + { + for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i)) + { + location_t tloc; + tree t = tsi_stmt (i); + + tloc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) : loc; + emit_side_effect_warnings (tloc, t); + } + } else - i = tsi_last (last); + i = tsi_last (last); last_p = tsi_stmt_ptr (i); last = *last_p; } @@ -9210,10 +9239,10 @@ && BIND_EXPR_VARS (body) == NULL) { /* Even if this looks constant, do not allow it in a constant - expression. */ + expression. */ last = c_wrap_maybe_const (last, true); /* Do not warn if the return value of a statement expression is - unused. */ + unused. */ TREE_NO_WARNING (last) = 1; return last; } @@ -9272,7 +9301,7 @@ if (do_scope) { if (c_dialect_objc ()) - objc_clear_super_receiver (); + objc_clear_super_receiver (); block = pop_scope (); } @@ -9334,7 +9363,7 @@ tree build_binary_op (location_t location, enum tree_code code, - tree orig_op0, tree orig_op1, int convert_p) + tree orig_op0, tree orig_op1, int convert_p) { tree type0, type1, orig_type0, orig_type1; tree eptype; @@ -9418,10 +9447,10 @@ if (int_operands) { int_const_or_overflow = (TREE_CODE (orig_op0) == INTEGER_CST - && TREE_CODE (orig_op1) == INTEGER_CST); + && TREE_CODE (orig_op1) == INTEGER_CST); int_const = (int_const_or_overflow - && !TREE_OVERFLOW (orig_op0) - && !TREE_OVERFLOW (orig_op1)); + && !TREE_OVERFLOW (orig_op0) + && !TREE_OVERFLOW (orig_op1)); } else int_const = int_const_or_overflow = false; @@ -9479,7 +9508,7 @@ type0 = TREE_TYPE (op0); } else if (may_need_excess_precision - && (eptype = excess_precision_type (type0)) != NULL_TREE) + && (eptype = excess_precision_type (type0)) != NULL_TREE) { type0 = eptype; op0 = convert (eptype, op0); @@ -9490,7 +9519,7 @@ type1 = TREE_TYPE (op1); } else if (may_need_excess_precision - && (eptype = excess_precision_type (type1)) != NULL_TREE) + && (eptype = excess_precision_type (type1)) != NULL_TREE) { type1 = eptype; op1 = convert (eptype, op1); @@ -9503,36 +9532,36 @@ case PLUS_EXPR: /* Handle the pointer + int case. */ if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - ret = pointer_int_sum (location, PLUS_EXPR, op0, op1); - goto return_build_binary_op; - } + { + ret = pointer_int_sum (location, PLUS_EXPR, op0, op1); + goto return_build_binary_op; + } else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) - { - ret = pointer_int_sum (location, PLUS_EXPR, op1, op0); - goto return_build_binary_op; - } + { + ret = pointer_int_sum (location, PLUS_EXPR, op1, op0); + goto return_build_binary_op; + } else - common = 1; + common = 1; break; case MINUS_EXPR: /* Subtraction of two similar pointers. - We must subtract them as integers, then divide by object size. */ + We must subtract them as integers, then divide by object size. */ if (code0 == POINTER_TYPE && code1 == POINTER_TYPE - && comp_target_types (location, type0, type1)) - { - ret = pointer_diff (location, op0, op1); - goto return_build_binary_op; - } + && comp_target_types (location, type0, type1)) + { + ret = pointer_diff (location, op0, op1); + goto return_build_binary_op; + } /* Handle pointer minus int. Just like pointer plus int. */ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - ret = pointer_int_sum (location, MINUS_EXPR, op0, op1); - goto return_build_binary_op; - } + { + ret = pointer_int_sum (location, MINUS_EXPR, op0, op1); + goto return_build_binary_op; + } else - common = 1; + common = 1; break; case MULT_EXPR: @@ -9547,46 +9576,46 @@ warn_for_div_by_zero (location, op1); if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == FIXED_POINT_TYPE - || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == FIXED_POINT_TYPE - || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) - { - enum tree_code tcode0 = code0, tcode1 = code1; - - if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) - tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0))); - if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE) - tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1))); - - if (!((tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE) - || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE))) - resultcode = RDIV_EXPR; - else - /* Although it would be tempting to shorten always here, that - loses on some targets, since the modulo instruction is - undefined if the quotient can't be represented in the - computation mode. We shorten only if unsigned or if - dividing by something we know != -1. */ - shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0)) - || (TREE_CODE (op1) == INTEGER_CST - && !integer_all_onesp (op1))); - common = 1; - } + || code0 == FIXED_POINT_TYPE + || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) + && (code1 == INTEGER_TYPE || code1 == REAL_TYPE + || code1 == FIXED_POINT_TYPE + || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) + { + enum tree_code tcode0 = code0, tcode1 = code1; + + if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) + tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0))); + if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE) + tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1))); + + if (!((tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE) + || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE))) + resultcode = RDIV_EXPR; + else + /* Although it would be tempting to shorten always here, that + loses on some targets, since the modulo instruction is + undefined if the quotient can't be represented in the + computation mode. We shorten only if unsigned or if + dividing by something we know != -1. */ + shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0)) + || (TREE_CODE (op1) == INTEGER_CST + && !integer_all_onesp (op1))); + common = 1; + } break; case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - shorten = -1; + shorten = -1; /* Allow vector types which are not floating point types. */ else if (code0 == VECTOR_TYPE - && code1 == VECTOR_TYPE - && !VECTOR_FLOAT_TYPE_P (type0) - && !VECTOR_FLOAT_TYPE_P (type1)) - common = 1; + && code1 == VECTOR_TYPE + && !VECTOR_FLOAT_TYPE_P (type0) + && !VECTOR_FLOAT_TYPE_P (type1)) + common = 1; break; case TRUNC_MOD_EXPR: @@ -9594,20 +9623,20 @@ warn_for_div_by_zero (location, op1); if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) - common = 1; + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE) + common = 1; else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - /* Although it would be tempting to shorten always here, that loses - on some targets, since the modulo instruction is undefined if the - quotient can't be represented in the computation mode. We shorten - only if unsigned or if dividing by something we know != -1. */ - shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0)) - || (TREE_CODE (op1) == INTEGER_CST - && !integer_all_onesp (op1))); - common = 1; - } + { + /* Although it would be tempting to shorten always here, that loses + on some targets, since the modulo instruction is undefined if the + quotient can't be represented in the computation mode. We shorten + only if unsigned or if dividing by something we know != -1. */ + shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0)) + || (TREE_CODE (op1) == INTEGER_CST + && !integer_all_onesp (op1))); + common = 1; + } break; case TRUTH_ANDIF_EXPR: @@ -9632,32 +9661,32 @@ boolean_op = true; } if (code == TRUTH_ANDIF_EXPR) - { - int_const_or_overflow = (int_operands - && TREE_CODE (orig_op0) == INTEGER_CST - && (op0 == truthvalue_false_node - || TREE_CODE (orig_op1) == INTEGER_CST)); - int_const = (int_const_or_overflow - && !TREE_OVERFLOW (orig_op0) - && (op0 == truthvalue_false_node - || !TREE_OVERFLOW (orig_op1))); - } + { + int_const_or_overflow = (int_operands + && TREE_CODE (orig_op0) == INTEGER_CST + && (op0 == truthvalue_false_node + || TREE_CODE (orig_op1) == INTEGER_CST)); + int_const = (int_const_or_overflow + && !TREE_OVERFLOW (orig_op0) + && (op0 == truthvalue_false_node + || !TREE_OVERFLOW (orig_op1))); + } else if (code == TRUTH_ORIF_EXPR) - { - int_const_or_overflow = (int_operands - && TREE_CODE (orig_op0) == INTEGER_CST - && (op0 == truthvalue_true_node - || TREE_CODE (orig_op1) == INTEGER_CST)); - int_const = (int_const_or_overflow - && !TREE_OVERFLOW (orig_op0) - && (op0 == truthvalue_true_node - || !TREE_OVERFLOW (orig_op1))); - } + { + int_const_or_overflow = (int_operands + && TREE_CODE (orig_op0) == INTEGER_CST + && (op0 == truthvalue_true_node + || TREE_CODE (orig_op1) == INTEGER_CST)); + int_const = (int_const_or_overflow + && !TREE_OVERFLOW (orig_op0) + && (op0 == truthvalue_true_node + || !TREE_OVERFLOW (orig_op1))); + } break; /* Shift operations: result has same type as first operand; - always convert second operand to int. - Also set SHORT_SHIFT if shifting rightward. */ + always convert second operand to int. + Also set SHORT_SHIFT if shifting rightward. */ case RSHIFT_EXPR: if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE @@ -9761,11 +9790,11 @@ case EQ_EXPR: case NE_EXPR: if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)) - warning_at (location, - OPT_Wfloat_equal, - "comparing floating point with == or != is unsafe"); + warning_at (location, + OPT_Wfloat_equal, + "comparing floating point with == or != is unsafe"); /* Result of comparison is always int, - but don't convert the args to int! */ + but don't convert the args to int! */ build_type = integer_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == FIXED_POINT_TYPE || code0 == COMPLEX_TYPE) @@ -9857,15 +9886,15 @@ } } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - pedwarn (location, 0, "comparison between pointer and integer"); - } + { + result_type = type0; + pedwarn (location, 0, "comparison between pointer and integer"); + } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - result_type = type1; - pedwarn (location, 0, "comparison between pointer and integer"); - } + { + result_type = type1; + pedwarn (location, 0, "comparison between pointer and integer"); + } break; case LE_EXPR: @@ -9874,10 +9903,10 @@ case GT_EXPR: build_type = integer_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == FIXED_POINT_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == FIXED_POINT_TYPE)) - short_compare = 1; + || code0 == FIXED_POINT_TYPE) + && (code1 == INTEGER_TYPE || code1 == REAL_TYPE + || code1 == FIXED_POINT_TYPE)) + short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (type0)); @@ -9936,15 +9965,15 @@ "ordered comparison of pointer with integer zero"); } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - pedwarn (location, 0, "comparison between pointer and integer"); - } + { + result_type = type0; + pedwarn (location, 0, "comparison between pointer and integer"); + } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - result_type = type1; - pedwarn (location, 0, "comparison between pointer and integer"); - } + { + result_type = type1; + pedwarn (location, 0, "comparison between pointer and integer"); + } break; default: @@ -9956,8 +9985,8 @@ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)) - || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0), - TREE_TYPE (type1)))) + || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0), + TREE_TYPE (type1)))) { binary_op_error (location, code, type0, type1); return error_mark_node; @@ -10069,122 +10098,122 @@ } /* For certain operations (which identify themselves by shorten != 0) - if both args were extended from the same smaller type, - do the arithmetic in that type and then extend. - - shorten !=0 and !=1 indicates a bitwise operation. - For them, this optimization is safe only if - both args are zero-extended or both are sign-extended. - Otherwise, we might change the result. - Eg, (short)-1 | (unsigned short)-1 is (int)-1 - but calculated in (unsigned short) it would be (unsigned short)-1. */ + if both args were extended from the same smaller type, + do the arithmetic in that type and then extend. + + shorten !=0 and !=1 indicates a bitwise operation. + For them, this optimization is safe only if + both args are zero-extended or both are sign-extended. + Otherwise, we might change the result. + Eg, (short)-1 | (unsigned short)-1 is (int)-1 + but calculated in (unsigned short) it would be (unsigned short)-1. */ if (shorten && none_complex) - { - final_type = result_type; - result_type = shorten_binary_op (result_type, op0, op1, - shorten == -1); - } + { + final_type = result_type; + result_type = shorten_binary_op (result_type, op0, op1, + shorten == -1); + } /* Shifts can be shortened if shifting right. */ if (short_shift) - { - int unsigned_arg; - tree arg0 = get_narrower (op0, &unsigned_arg); - - final_type = result_type; - - if (arg0 == op0 && final_type == TREE_TYPE (op0)) - unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0)); - - if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) - && tree_int_cst_sgn (op1) > 0 - /* We can shorten only if the shift count is less than the - number of bits in the smaller type size. */ - && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0 - /* We cannot drop an unsigned shift after sign-extension. */ - && (!TYPE_UNSIGNED (final_type) || unsigned_arg)) - { - /* Do an unsigned shift if the operand was zero-extended. */ - result_type - = c_common_signed_or_unsigned_type (unsigned_arg, - TREE_TYPE (arg0)); - /* Convert value-to-be-shifted to that type. */ - if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); - converted = 1; - } - } + { + int unsigned_arg; + tree arg0 = get_narrower (op0, &unsigned_arg); + + final_type = result_type; + + if (arg0 == op0 && final_type == TREE_TYPE (op0)) + unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0)); + + if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) + && tree_int_cst_sgn (op1) > 0 + /* We can shorten only if the shift count is less than the + number of bits in the smaller type size. */ + && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0 + /* We cannot drop an unsigned shift after sign-extension. */ + && (!TYPE_UNSIGNED (final_type) || unsigned_arg)) + { + /* Do an unsigned shift if the operand was zero-extended. */ + result_type + = c_common_signed_or_unsigned_type (unsigned_arg, + TREE_TYPE (arg0)); + /* Convert value-to-be-shifted to that type. */ + if (TREE_TYPE (op0) != result_type) + op0 = convert (result_type, op0); + converted = 1; + } + } /* Comparison operations are shortened too but differently. - They identify themselves by setting short_compare = 1. */ + They identify themselves by setting short_compare = 1. */ if (short_compare) - { - /* Don't write &op0, etc., because that would prevent op0 - from being kept in a register. - Instead, make copies of the our local variables and - pass the copies by reference, then copy them back afterward. */ - tree xop0 = op0, xop1 = op1, xresult_type = result_type; - enum tree_code xresultcode = resultcode; - tree val - = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); - - if (val != 0) - { - ret = val; - goto return_build_binary_op; - } - - op0 = xop0, op1 = xop1; - converted = 1; - resultcode = xresultcode; - - if (c_inhibit_evaluation_warnings == 0) - { - bool op0_maybe_const = true; - bool op1_maybe_const = true; - tree orig_op0_folded, orig_op1_folded; - - if (in_late_binary_op) - { - orig_op0_folded = orig_op0; - orig_op1_folded = orig_op1; - } - else - { - /* Fold for the sake of possible warnings, as in - build_conditional_expr. This requires the - "original" values to be folded, not just op0 and - op1. */ - c_inhibit_evaluation_warnings++; - op0 = c_fully_fold (op0, require_constant_value, - &op0_maybe_const); - op1 = c_fully_fold (op1, require_constant_value, - &op1_maybe_const); - c_inhibit_evaluation_warnings--; - orig_op0_folded = c_fully_fold (orig_op0, - require_constant_value, - NULL); - orig_op1_folded = c_fully_fold (orig_op1, - require_constant_value, - NULL); - } - - if (warn_sign_compare) - warn_for_sign_compare (location, orig_op0_folded, - orig_op1_folded, op0, op1, - result_type, resultcode); - if (!in_late_binary_op) - { - if (!op0_maybe_const || TREE_CODE (op0) != INTEGER_CST) - op0 = c_wrap_maybe_const (op0, !op0_maybe_const); - if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST) - op1 = c_wrap_maybe_const (op1, !op1_maybe_const); - } - } - } + { + /* Don't write &op0, etc., because that would prevent op0 + from being kept in a register. + Instead, make copies of the our local variables and + pass the copies by reference, then copy them back afterward. */ + tree xop0 = op0, xop1 = op1, xresult_type = result_type; + enum tree_code xresultcode = resultcode; + tree val + = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); + + if (val != 0) + { + ret = val; + goto return_build_binary_op; + } + + op0 = xop0, op1 = xop1; + converted = 1; + resultcode = xresultcode; + + if (c_inhibit_evaluation_warnings == 0) + { + bool op0_maybe_const = true; + bool op1_maybe_const = true; + tree orig_op0_folded, orig_op1_folded; + + if (in_late_binary_op) + { + orig_op0_folded = orig_op0; + orig_op1_folded = orig_op1; + } + else + { + /* Fold for the sake of possible warnings, as in + build_conditional_expr. This requires the + "original" values to be folded, not just op0 and + op1. */ + c_inhibit_evaluation_warnings++; + op0 = c_fully_fold (op0, require_constant_value, + &op0_maybe_const); + op1 = c_fully_fold (op1, require_constant_value, + &op1_maybe_const); + c_inhibit_evaluation_warnings--; + orig_op0_folded = c_fully_fold (orig_op0, + require_constant_value, + NULL); + orig_op1_folded = c_fully_fold (orig_op1, + require_constant_value, + NULL); + } + + if (warn_sign_compare) + warn_for_sign_compare (location, orig_op0_folded, + orig_op1_folded, op0, op1, + result_type, resultcode); + if (!in_late_binary_op) + { + if (!op0_maybe_const || TREE_CODE (op0) != INTEGER_CST) + op0 = c_wrap_maybe_const (op0, !op0_maybe_const); + if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST) + op1 = c_wrap_maybe_const (op1, !op1_maybe_const); + } + } + } } /* At this point, RESULT_TYPE must be nonzero to avoid an error message. @@ -10216,17 +10245,17 @@ op1 = ep_convert_and_check (result_type, op1, semantic_result_type); /* This can happen if one operand has a vector type, and the other - has a different type. */ + has a different type. */ if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK) - return error_mark_node; + return error_mark_node; } /* Treat expressions in initializers specially as they can't trap. */ if (int_const_or_overflow) ret = (require_constant_value - ? fold_build2_initializer_loc (location, resultcode, build_type, - op0, op1) - : fold_build2_loc (location, resultcode, build_type, op0, op1)); + ? fold_build2_initializer_loc (location, resultcode, build_type, + op0, op1) + : fold_build2_loc (location, resultcode, build_type, op0, op1)); else ret = build2 (resultcode, build_type, op0, op1); if (final_type != 0) @@ -10236,10 +10265,10 @@ gcc_assert (ret != error_mark_node); if (TREE_CODE (ret) == INTEGER_CST && !TREE_OVERFLOW (ret) && !int_const) ret = (int_operands - ? note_integer_operands (ret) - : build1 (NOP_EXPR, TREE_TYPE (ret), ret)); + ? note_integer_operands (ret) + : build1 (NOP_EXPR, TREE_TYPE (ret), ret)); else if (TREE_CODE (ret) != INTEGER_CST && int_operands - && !in_late_binary_op) + && !in_late_binary_op) ret = note_integer_operands (ret); if (semantic_result_type) ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret); @@ -10293,9 +10322,9 @@ if (TREE_CODE (expr) == INTEGER_CST && int_operands && !int_const) { if (TREE_OVERFLOW (expr)) - return expr; + return expr; else - return note_integer_operands (expr); + return note_integer_operands (expr); } if (TREE_CODE (expr) == INTEGER_CST && !int_const) return build1 (NOP_EXPR, TREE_TYPE (expr), expr); @@ -10313,9 +10342,9 @@ { tree decl = COMPOUND_LITERAL_EXPR_DECL (expr); /* Executing a compound literal inside a function reinitializes - it. */ + it. */ if (!TREE_STATIC (decl)) - *se = true; + *se = true; return decl; } else @@ -10408,206 +10437,206 @@ bool need_implicitly_determined = false; switch (OMP_CLAUSE_CODE (c)) - { - case OMP_CLAUSE_SHARED: - name = "shared"; - need_implicitly_determined = true; - goto check_dup_generic; - - case OMP_CLAUSE_PRIVATE: - name = "private"; - need_complete = true; - need_implicitly_determined = true; - goto check_dup_generic; - - case OMP_CLAUSE_REDUCTION: - name = "reduction"; - need_implicitly_determined = true; - t = OMP_CLAUSE_DECL (c); - if (AGGREGATE_TYPE_P (TREE_TYPE (t)) - || POINTER_TYPE_P (TREE_TYPE (t))) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE has invalid type for %", t); - remove = true; - } - else if (FLOAT_TYPE_P (TREE_TYPE (t))) - { - enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c); - const char *r_name = NULL; - - switch (r_code) - { - case PLUS_EXPR: - case MULT_EXPR: - case MINUS_EXPR: - break; - case BIT_AND_EXPR: - r_name = "&"; - break; - case BIT_XOR_EXPR: - r_name = "^"; - break; - case BIT_IOR_EXPR: - r_name = "|"; - break; - case TRUTH_ANDIF_EXPR: - r_name = "&&"; - break; - case TRUTH_ORIF_EXPR: - r_name = "||"; - break; - default: - gcc_unreachable (); - } - if (r_name) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE has invalid type for %", - t, r_name); - remove = true; - } - } - goto check_dup_generic; - - case OMP_CLAUSE_COPYPRIVATE: - name = "copyprivate"; - goto check_dup_generic; - - case OMP_CLAUSE_COPYIN: - name = "copyin"; - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t)) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE must be % for %", t); - remove = true; - } - goto check_dup_generic; - - check_dup_generic: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is not a variable in clause %qs", t, name); - remove = true; - } - else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&firstprivate_head, DECL_UID (t)) - || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE appears more than once in data clauses", t); - remove = true; - } - else - bitmap_set_bit (&generic_head, DECL_UID (t)); - break; - - case OMP_CLAUSE_FIRSTPRIVATE: - name = "firstprivate"; - t = OMP_CLAUSE_DECL (c); - need_complete = true; - need_implicitly_determined = true; - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is not a variable in clause %", t); - remove = true; - } - else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE appears more than once in data clauses", t); - remove = true; - } - else - bitmap_set_bit (&firstprivate_head, DECL_UID (t)); - break; - - case OMP_CLAUSE_LASTPRIVATE: - name = "lastprivate"; - t = OMP_CLAUSE_DECL (c); - need_complete = true; - need_implicitly_determined = true; - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is not a variable in clause %", t); - remove = true; - } - else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE appears more than once in data clauses", t); - remove = true; - } - else - bitmap_set_bit (&lastprivate_head, DECL_UID (t)); - break; - - case OMP_CLAUSE_IF: - case OMP_CLAUSE_NUM_THREADS: - case OMP_CLAUSE_SCHEDULE: - case OMP_CLAUSE_NOWAIT: - case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_DEFAULT: - case OMP_CLAUSE_UNTIED: - case OMP_CLAUSE_COLLAPSE: - pc = &OMP_CLAUSE_CHAIN (c); - continue; - - default: - gcc_unreachable (); - } + { + case OMP_CLAUSE_SHARED: + name = "shared"; + need_implicitly_determined = true; + goto check_dup_generic; + + case OMP_CLAUSE_PRIVATE: + name = "private"; + need_complete = true; + need_implicitly_determined = true; + goto check_dup_generic; + + case OMP_CLAUSE_REDUCTION: + name = "reduction"; + need_implicitly_determined = true; + t = OMP_CLAUSE_DECL (c); + if (AGGREGATE_TYPE_P (TREE_TYPE (t)) + || POINTER_TYPE_P (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE has invalid type for %", t); + remove = true; + } + else if (FLOAT_TYPE_P (TREE_TYPE (t))) + { + enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c); + const char *r_name = NULL; + + switch (r_code) + { + case PLUS_EXPR: + case MULT_EXPR: + case MINUS_EXPR: + break; + case BIT_AND_EXPR: + r_name = "&"; + break; + case BIT_XOR_EXPR: + r_name = "^"; + break; + case BIT_IOR_EXPR: + r_name = "|"; + break; + case TRUTH_ANDIF_EXPR: + r_name = "&&"; + break; + case TRUTH_ORIF_EXPR: + r_name = "||"; + break; + default: + gcc_unreachable (); + } + if (r_name) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE has invalid type for %", + t, r_name); + remove = true; + } + } + goto check_dup_generic; + + case OMP_CLAUSE_COPYPRIVATE: + name = "copyprivate"; + goto check_dup_generic; + + case OMP_CLAUSE_COPYIN: + name = "copyin"; + t = OMP_CLAUSE_DECL (c); + if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t)) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE must be % for %", t); + remove = true; + } + goto check_dup_generic; + + check_dup_generic: + t = OMP_CLAUSE_DECL (c); + if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in clause %qs", t, name); + remove = true; + } + else if (bitmap_bit_p (&generic_head, DECL_UID (t)) + || bitmap_bit_p (&firstprivate_head, DECL_UID (t)) + || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE appears more than once in data clauses", t); + remove = true; + } + else + bitmap_set_bit (&generic_head, DECL_UID (t)); + break; + + case OMP_CLAUSE_FIRSTPRIVATE: + name = "firstprivate"; + t = OMP_CLAUSE_DECL (c); + need_complete = true; + need_implicitly_determined = true; + if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in clause %", t); + remove = true; + } + else if (bitmap_bit_p (&generic_head, DECL_UID (t)) + || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE appears more than once in data clauses", t); + remove = true; + } + else + bitmap_set_bit (&firstprivate_head, DECL_UID (t)); + break; + + case OMP_CLAUSE_LASTPRIVATE: + name = "lastprivate"; + t = OMP_CLAUSE_DECL (c); + need_complete = true; + need_implicitly_determined = true; + if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is not a variable in clause %", t); + remove = true; + } + else if (bitmap_bit_p (&generic_head, DECL_UID (t)) + || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE appears more than once in data clauses", t); + remove = true; + } + else + bitmap_set_bit (&lastprivate_head, DECL_UID (t)); + break; + + case OMP_CLAUSE_IF: + case OMP_CLAUSE_NUM_THREADS: + case OMP_CLAUSE_SCHEDULE: + case OMP_CLAUSE_NOWAIT: + case OMP_CLAUSE_ORDERED: + case OMP_CLAUSE_DEFAULT: + case OMP_CLAUSE_UNTIED: + case OMP_CLAUSE_COLLAPSE: + pc = &OMP_CLAUSE_CHAIN (c); + continue; + + default: + gcc_unreachable (); + } if (!remove) - { - t = OMP_CLAUSE_DECL (c); - - if (need_complete) - { - t = require_complete_type (t); - if (t == error_mark_node) - remove = true; - } - - if (need_implicitly_determined) - { - const char *share_name = NULL; - - if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t)) - share_name = "threadprivate"; - else switch (c_omp_predetermined_sharing (t)) - { - case OMP_CLAUSE_DEFAULT_UNSPECIFIED: - break; - case OMP_CLAUSE_DEFAULT_SHARED: - share_name = "shared"; - break; - case OMP_CLAUSE_DEFAULT_PRIVATE: - share_name = "private"; - break; - default: - gcc_unreachable (); - } - if (share_name) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%qE is predetermined %qs for %qs", - t, share_name, name); - remove = true; - } - } - } + { + t = OMP_CLAUSE_DECL (c); + + if (need_complete) + { + t = require_complete_type (t); + if (t == error_mark_node) + remove = true; + } + + if (need_implicitly_determined) + { + const char *share_name = NULL; + + if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t)) + share_name = "threadprivate"; + else switch (c_omp_predetermined_sharing (t)) + { + case OMP_CLAUSE_DEFAULT_UNSPECIFIED: + break; + case OMP_CLAUSE_DEFAULT_SHARED: + share_name = "shared"; + break; + case OMP_CLAUSE_DEFAULT_PRIVATE: + share_name = "private"; + break; + default: + gcc_unreachable (); + } + if (share_name) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qE is predetermined %qs for %qs", + t, share_name, name); + remove = true; + } + } + } if (remove) - *pc = OMP_CLAUSE_CHAIN (c); + *pc = OMP_CLAUSE_CHAIN (c); else - pc = &OMP_CLAUSE_CHAIN (c); + pc = &OMP_CLAUSE_CHAIN (c); } bitmap_obstack_release (NULL); @@ -10627,24 +10656,24 @@ { tree t; tree element_type = c_build_qualified_type (TREE_TYPE (type), - type_quals); + type_quals); /* See if we already have an identically qualified type. */ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - { - if (TYPE_QUALS (strip_array_types (t)) == type_quals - && TYPE_NAME (t) == TYPE_NAME (type) - && TYPE_CONTEXT (t) == TYPE_CONTEXT (type) - && attribute_list_equal (TYPE_ATTRIBUTES (t), - TYPE_ATTRIBUTES (type))) - break; - } + { + if (TYPE_QUALS (strip_array_types (t)) == type_quals + && TYPE_NAME (t) == TYPE_NAME (type) + && TYPE_CONTEXT (t) == TYPE_CONTEXT (type) + && attribute_list_equal (TYPE_ATTRIBUTES (t), + TYPE_ATTRIBUTES (type))) + break; + } if (!t) - { + { tree domain = TYPE_DOMAIN (type); - t = build_variant_type_copy (type); - TREE_TYPE (t) = element_type; + t = build_variant_type_copy (type); + TREE_TYPE (t) = element_type; if (TYPE_STRUCTURAL_EQUALITY_P (element_type) || (domain && TYPE_STRUCTURAL_EQUALITY_P (domain))) @@ -10661,7 +10690,7 @@ } else TYPE_CANONICAL (t) = t; - } + } return t; } @@ -10670,7 +10699,7 @@ REFERENCE_TYPEs, which is appropriate for C++. */ if ((type_quals & TYPE_QUAL_RESTRICT) && (!POINTER_TYPE_P (type) - || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))) + || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))) { error ("invalid use of %"); type_quals &= ~TYPE_QUAL_RESTRICT; @@ -10686,6 +10715,6 @@ { if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE) warning_at (loc, OPT_Wc___compat, - "C++ requires promoted type, not enum type, in %"); + "C++ requires promoted type, not enum type, in %"); return build_va_arg (loc, expr, type); } diff -r 561a7518be6b -r 1b10fe6932e1 gcc/calls.c --- a/gcc/calls.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/calls.c Sun Aug 21 07:53:12 2011 +0900 @@ -99,6 +99,9 @@ word-sized pseudos we made. */ rtx *aligned_regs; int n_aligned_regs; +#ifndef noCbC +rtx exprs; +#endif }; /* A vector of one char per byte of stack space. A byte if nonzero if @@ -125,33 +128,33 @@ static int stack_arg_under_construction; static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, - HOST_WIDE_INT, rtx, rtx, int, rtx, int, - CUMULATIVE_ARGS *); + HOST_WIDE_INT, rtx, rtx, int, rtx, int, + CUMULATIVE_ARGS *); static void precompute_register_parameters (int, struct arg_data *, int *); static int store_one_arg (struct arg_data *, rtx, int, int, int); static void store_unaligned_arguments_into_pseudos (struct arg_data *, int); static int finalize_must_preallocate (int, int, struct arg_data *, - struct args_size *); + struct args_size *); static void precompute_arguments (int, struct arg_data *); static int compute_argument_block_size (int, struct args_size *, tree, tree, int); static void initialize_argument_information (int, struct arg_data *, - struct args_size *, int, - tree, tree, - tree, tree, CUMULATIVE_ARGS *, int, - rtx *, int *, int *, int *, - bool *, bool); + struct args_size *, int, + tree, tree, + tree, tree, CUMULATIVE_ARGS *, int, + rtx *, int *, int *, int *, + bool *, bool); static void compute_argument_addresses (struct arg_data *, rtx, int); static rtx rtx_for_function_call (tree, tree); static void load_register_parameters (struct arg_data *, int, rtx *, int, - int, int *); + int, int *); static rtx emit_library_call_value_1 (int, rtx, rtx, enum libcall_type, - enum machine_mode, int, va_list); + enum machine_mode, int, va_list); static int special_function_p (const_tree, int); static int check_sibcall_argument_overlap_1 (rtx); static int check_sibcall_argument_overlap (rtx, struct arg_data *, int); static int combine_pending_stack_adjustment_and_call (int, struct args_size *, - unsigned int); + unsigned int); static tree split_complex_types (tree); #ifdef REG_PARM_STACK_SPACE @@ -168,7 +171,7 @@ rtx prepare_call_address (tree fndecl, rtx funexp, rtx static_chain_value, - rtx *call_fusage, int reg_parm_seen, int sibcallp) + rtx *call_fusage, int reg_parm_seen, int sibcallp) { /* Make a valid memory address and copy constants through pseudo-regs, but not for a constant address if -fno-function-cse. */ @@ -183,7 +186,7 @@ { #ifndef NO_FUNCTION_CSE if (optimize && ! flag_no_function_cse) - funexp = force_reg (Pmode, funexp); + funexp = force_reg (Pmode, funexp); #endif } @@ -197,7 +200,7 @@ emit_move_insn (chain, static_chain_value); if (REG_P (chain)) - use_reg (call_fusage, chain); + use_reg (call_fusage, chain); } return funexp; @@ -247,13 +250,13 @@ static void emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNUSED, - tree funtype ATTRIBUTE_UNUSED, - HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED, - HOST_WIDE_INT rounded_stack_size, - HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED, - rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg, - int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags, - CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED) + tree funtype ATTRIBUTE_UNUSED, + HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED, + HOST_WIDE_INT rounded_stack_size, + HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED, + rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg, + int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags, + CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED) { rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size); rtx call_insn; @@ -280,16 +283,16 @@ rtx pat; /* If this subroutine pops its own args, record that in the call insn - if possible, for the sake of frame pointer elimination. */ + if possible, for the sake of frame pointer elimination. */ if (valreg) - pat = GEN_SIBCALL_VALUE_POP (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, - n_pop); + pat = GEN_SIBCALL_VALUE_POP (valreg, + gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, + n_pop); else - pat = GEN_SIBCALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, n_pop); + pat = GEN_SIBCALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, n_pop); emit_call_insn (pat); already_popped = 1; @@ -313,15 +316,15 @@ rtx pat; /* If this subroutine pops its own args, record that in the call insn - if possible, for the sake of frame pointer elimination. */ + if possible, for the sake of frame pointer elimination. */ if (valreg) - pat = GEN_CALL_VALUE_POP (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, n_pop); + pat = GEN_CALL_VALUE_POP (valreg, + gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, n_pop); else - pat = GEN_CALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, n_pop); + pat = GEN_CALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, n_pop); emit_call_insn (pat); already_popped = 1; @@ -334,14 +337,14 @@ && HAVE_sibcall && HAVE_sibcall_value) { if (valreg) - emit_call_insn (GEN_SIBCALL_VALUE (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, - next_arg_reg, NULL_RTX)); + emit_call_insn (GEN_SIBCALL_VALUE (valreg, + gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, + next_arg_reg, NULL_RTX)); else - emit_call_insn (GEN_SIBCALL (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, - GEN_INT (struct_value_size))); + emit_call_insn (GEN_SIBCALL (gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, + GEN_INT (struct_value_size))); } else #endif @@ -350,14 +353,14 @@ if (HAVE_call && HAVE_call_value) { if (valreg) - emit_call_insn (GEN_CALL_VALUE (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, - NULL_RTX)); + emit_call_insn (GEN_CALL_VALUE (valreg, + gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, + NULL_RTX)); else - emit_call_insn (GEN_CALL (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, - GEN_INT (struct_value_size))); + emit_call_insn (GEN_CALL (gen_rtx_MEM (FUNCTION_MODE, funexp), + rounded_stack_size_rtx, next_arg_reg, + GEN_INT (struct_value_size))); } else #endif @@ -407,10 +410,10 @@ if (n_popped > 0) { if (!already_popped) - CALL_INSN_FUNCTION_USAGE (call_insn) - = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx), - CALL_INSN_FUNCTION_USAGE (call_insn)); + CALL_INSN_FUNCTION_USAGE (call_insn) + = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx), + CALL_INSN_FUNCTION_USAGE (call_insn)); rounded_stack_size -= n_popped; rounded_stack_size_rtx = GEN_INT (rounded_stack_size); stack_pointer_delta -= n_popped; @@ -423,23 +426,23 @@ if (!ACCUMULATE_OUTGOING_ARGS) { /* If returning from the subroutine does not automatically pop the args, - we need an instruction to pop them sooner or later. - Perhaps do it now; perhaps just record how much space to pop later. - - If returning from the subroutine does pop the args, indicate that the - stack pointer will be changed. */ + we need an instruction to pop them sooner or later. + Perhaps do it now; perhaps just record how much space to pop later. + + If returning from the subroutine does pop the args, indicate that the + stack pointer will be changed. */ if (rounded_stack_size != 0) - { - if (ecf_flags & ECF_NORETURN) - /* Just pretend we did the pop. */ - stack_pointer_delta -= rounded_stack_size; - else if (flag_defer_pop && inhibit_defer_pop == 0 - && ! (ecf_flags & (ECF_CONST | ECF_PURE))) - pending_stack_adjust += rounded_stack_size; - else - adjust_stack (rounded_stack_size_rtx); - } + { + if (ecf_flags & ECF_NORETURN) + /* Just pretend we did the pop. */ + stack_pointer_delta -= rounded_stack_size; + else if (flag_defer_pop && inhibit_defer_pop == 0 + && ! (ecf_flags & (ECF_CONST | ECF_PURE))) + pending_stack_adjust += rounded_stack_size; + else + adjust_stack (rounded_stack_size_rtx); + } } /* When we accumulate outgoing args, we must avoid any stack manipulations. Restore the stack pointer to its original value now. Usually @@ -473,71 +476,71 @@ if (fndecl && DECL_NAME (fndecl) && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17 /* Exclude functions not at the file scope, or not `extern', - since they are not the magic functions we would otherwise - think they are. - FIXME: this should be handled with attributes, not with this - hacky imitation of DECL_ASSEMBLER_NAME. It's (also) wrong - because you can declare fork() inside a function if you - wish. */ + since they are not the magic functions we would otherwise + think they are. + FIXME: this should be handled with attributes, not with this + hacky imitation of DECL_ASSEMBLER_NAME. It's (also) wrong + because you can declare fork() inside a function if you + wish. */ && (DECL_CONTEXT (fndecl) == NULL_TREE - || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL) + || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL) && TREE_PUBLIC (fndecl)) { const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); const char *tname = name; /* We assume that alloca will always be called by name. It - makes no sense to pass it as a pointer-to-function to - anything that does not understand its behavior. */ + makes no sense to pass it as a pointer-to-function to + anything that does not understand its behavior. */ if (((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6 - && name[0] == 'a' - && ! strcmp (name, "alloca")) - || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16 - && name[0] == '_' - && ! strcmp (name, "__builtin_alloca")))) - flags |= ECF_MAY_BE_ALLOCA; + && name[0] == 'a' + && ! strcmp (name, "alloca")) + || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16 + && name[0] == '_' + && ! strcmp (name, "__builtin_alloca")))) + flags |= ECF_MAY_BE_ALLOCA; /* Disregard prefix _, __, __x or __builtin_. */ if (name[0] == '_') - { - if (name[1] == '_' - && name[2] == 'b' - && !strncmp (name + 3, "uiltin_", 7)) - tname += 10; - else if (name[1] == '_' && name[2] == 'x') - tname += 3; - else if (name[1] == '_') - tname += 2; - else - tname += 1; - } + { + if (name[1] == '_' + && name[2] == 'b' + && !strncmp (name + 3, "uiltin_", 7)) + tname += 10; + else if (name[1] == '_' && name[2] == 'x') + tname += 3; + else if (name[1] == '_') + tname += 2; + else + tname += 1; + } if (tname[0] == 's') - { - if ((tname[1] == 'e' - && (! strcmp (tname, "setjmp") - || ! strcmp (tname, "setjmp_syscall"))) - || (tname[1] == 'i' - && ! strcmp (tname, "sigsetjmp")) - || (tname[1] == 'a' - && ! strcmp (tname, "savectx"))) - flags |= ECF_RETURNS_TWICE; - - if (tname[1] == 'i' - && ! strcmp (tname, "siglongjmp")) - flags |= ECF_NORETURN; - } + { + if ((tname[1] == 'e' + && (! strcmp (tname, "setjmp") + || ! strcmp (tname, "setjmp_syscall"))) + || (tname[1] == 'i' + && ! strcmp (tname, "sigsetjmp")) + || (tname[1] == 'a' + && ! strcmp (tname, "savectx"))) + flags |= ECF_RETURNS_TWICE; + + if (tname[1] == 'i' + && ! strcmp (tname, "siglongjmp")) + flags |= ECF_NORETURN; + } else if ((tname[0] == 'q' && tname[1] == 's' - && ! strcmp (tname, "qsetjmp")) - || (tname[0] == 'v' && tname[1] == 'f' - && ! strcmp (tname, "vfork")) - || (tname[0] == 'g' && tname[1] == 'e' - && !strcmp (tname, "getcontext"))) - flags |= ECF_RETURNS_TWICE; + && ! strcmp (tname, "qsetjmp")) + || (tname[0] == 'v' && tname[1] == 'f' + && ! strcmp (tname, "vfork")) + || (tname[0] == 'g' && tname[1] == 'e' + && !strcmp (tname, "getcontext"))) + flags |= ECF_RETURNS_TWICE; else if (tname[0] == 'l' && tname[1] == 'o' - && ! strcmp (tname, "longjmp")) - flags |= ECF_NORETURN; + && ! strcmp (tname, "longjmp")) + flags |= ECF_NORETURN; } return flags; @@ -578,7 +581,7 @@ && TREE_CODE (CALL_EXPR_FN (exp)) == ADDR_EXPR && (TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (exp), 0)) == FUNCTION_DECL) && (special_function_p (TREE_OPERAND (CALL_EXPR_FN (exp), 0), 0) - & ECF_MAY_BE_ALLOCA)) + & ECF_MAY_BE_ALLOCA)) return true; return false; } @@ -594,19 +597,19 @@ { /* The function exp may have the `malloc' attribute. */ if (DECL_IS_MALLOC (exp)) - flags |= ECF_MALLOC; + flags |= ECF_MALLOC; /* The function exp may have the `returns_twice' attribute. */ if (DECL_IS_RETURNS_TWICE (exp)) - flags |= ECF_RETURNS_TWICE; + flags |= ECF_RETURNS_TWICE; /* Process the pure and const attributes. */ if (TREE_READONLY (exp)) flags |= ECF_CONST; if (DECL_PURE_P (exp)) - flags |= ECF_PURE; + flags |= ECF_PURE; if (DECL_LOOPING_CONST_OR_PURE_P (exp)) - flags |= ECF_LOOPING_CONST_OR_PURE; + flags |= ECF_LOOPING_CONST_OR_PURE; if (DECL_IS_NOVOPS (exp)) flags |= ECF_NOVOPS; @@ -614,7 +617,7 @@ flags |= ECF_LEAF; if (TREE_NOTHROW (exp)) - flags |= ECF_NOTHROW; + flags |= ECF_NOTHROW; flags = special_function_p (exp, flags); } @@ -645,9 +648,9 @@ { t = TREE_TYPE (CALL_EXPR_FN (t)); if (t && TREE_CODE (t) == POINTER_TYPE) - flags = flags_from_decl_or_type (TREE_TYPE (t)); + flags = flags_from_decl_or_type (TREE_TYPE (t)); else - flags = 0; + flags = 0; } return flags; @@ -662,7 +665,7 @@ static void precompute_register_parameters (int num_actuals, struct arg_data *args, - int *reg_parm_seen) + int *reg_parm_seen) { int i; @@ -751,51 +754,51 @@ for (low = 0; low < high; low++) if (stack_usage_map[low] != 0) { - int num_to_save; - enum machine_mode save_mode; - int delta; - rtx stack_area; - rtx save_area; - - while (stack_usage_map[--high] == 0) - ; - - *low_to_save = low; - *high_to_save = high; - - num_to_save = high - low + 1; - save_mode = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1); - - /* If we don't have the required alignment, must do this - in BLKmode. */ - if ((low & (MIN (GET_MODE_SIZE (save_mode), - BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1))) - save_mode = BLKmode; + int num_to_save; + enum machine_mode save_mode; + int delta; + rtx stack_area; + rtx save_area; + + while (stack_usage_map[--high] == 0) + ; + + *low_to_save = low; + *high_to_save = high; + + num_to_save = high - low + 1; + save_mode = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1); + + /* If we don't have the required alignment, must do this + in BLKmode. */ + if ((low & (MIN (GET_MODE_SIZE (save_mode), + BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1))) + save_mode = BLKmode; #ifdef ARGS_GROW_DOWNWARD - delta = -high; + delta = -high; #else - delta = low; + delta = low; #endif - stack_area = gen_rtx_MEM (save_mode, - memory_address (save_mode, - plus_constant (argblock, - delta))); - - set_mem_align (stack_area, PARM_BOUNDARY); - if (save_mode == BLKmode) - { - save_area = assign_stack_temp (BLKmode, num_to_save, 0); - emit_block_move (validize_mem (save_area), stack_area, - GEN_INT (num_to_save), BLOCK_OP_CALL_PARM); - } - else - { - save_area = gen_reg_rtx (save_mode); - emit_move_insn (save_area, stack_area); - } - - return save_area; + stack_area = gen_rtx_MEM (save_mode, + memory_address (save_mode, + plus_constant (argblock, + delta))); + + set_mem_align (stack_area, PARM_BOUNDARY); + if (save_mode == BLKmode) + { + save_area = assign_stack_temp (BLKmode, num_to_save, 0); + emit_block_move (validize_mem (save_area), stack_area, + GEN_INT (num_to_save), BLOCK_OP_CALL_PARM); + } + else + { + save_area = gen_reg_rtx (save_mode); + emit_move_insn (save_area, stack_area); + } + + return save_area; } return NULL_RTX; @@ -814,16 +817,16 @@ delta = low_to_save; #endif stack_area = gen_rtx_MEM (save_mode, - memory_address (save_mode, - plus_constant (argblock, delta))); + memory_address (save_mode, + plus_constant (argblock, delta))); set_mem_align (stack_area, PARM_BOUNDARY); if (save_mode != BLKmode) emit_move_insn (stack_area, save_area); else emit_block_move (stack_area, validize_mem (save_area), - GEN_INT (high_to_save - low_to_save + 1), - BLOCK_OP_CALL_PARM); + GEN_INT (high_to_save - low_to_save + 1), + BLOCK_OP_CALL_PARM); } #endif /* REG_PARM_STACK_SPACE */ @@ -843,38 +846,38 @@ for (i = 0; i < num_actuals; i++) if (args[i].reg != 0 && ! args[i].pass_on_stack - && args[i].mode == BLKmode - && MEM_P (args[i].value) - && (MEM_ALIGN (args[i].value) - < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD))) + && args[i].mode == BLKmode + && MEM_P (args[i].value) + && (MEM_ALIGN (args[i].value) + < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD))) { - int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); - int endian_correction = 0; - - if (args[i].partial) - { - gcc_assert (args[i].partial % UNITS_PER_WORD == 0); - args[i].n_aligned_regs = args[i].partial / UNITS_PER_WORD; - } - else - { - args[i].n_aligned_regs - = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - } - - args[i].aligned_regs = XNEWVEC (rtx, args[i].n_aligned_regs); - - /* Structures smaller than a word are normally aligned to the - least significant byte. On a BYTES_BIG_ENDIAN machine, - this means we must skip the empty high order bytes when - calculating the bit offset. */ - if (bytes < UNITS_PER_WORD + int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); + int endian_correction = 0; + + if (args[i].partial) + { + gcc_assert (args[i].partial % UNITS_PER_WORD == 0); + args[i].n_aligned_regs = args[i].partial / UNITS_PER_WORD; + } + else + { + args[i].n_aligned_regs + = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + } + + args[i].aligned_regs = XNEWVEC (rtx, args[i].n_aligned_regs); + + /* Structures smaller than a word are normally aligned to the + least significant byte. On a BYTES_BIG_ENDIAN machine, + this means we must skip the empty high order bytes when + calculating the bit offset. */ + if (bytes < UNITS_PER_WORD #ifdef BLOCK_REG_PADDING - && (BLOCK_REG_PADDING (args[i].mode, - TREE_TYPE (args[i].tree_value), 1) - == downward) + && (BLOCK_REG_PADDING (args[i].mode, + TREE_TYPE (args[i].tree_value), 1) + == downward) #else - && BYTES_BIG_ENDIAN + && BYTES_BIG_ENDIAN #endif ) endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT; @@ -941,16 +944,16 @@ static void initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, - struct arg_data *args, - struct args_size *args_size, - int n_named_args ATTRIBUTE_UNUSED, - tree exp, tree struct_value_addr_value, - tree fndecl, tree fntype, - CUMULATIVE_ARGS *args_so_far, - int reg_parm_stack_space, - rtx *old_stack_level, int *old_pending_adj, - int *must_preallocate, int *ecf_flags, - bool *may_tailcall, bool call_from_thunk_p) + struct arg_data *args, + struct args_size *args_size, + int n_named_args ATTRIBUTE_UNUSED, + tree exp, tree struct_value_addr_value, + tree fndecl, tree fntype, + CUMULATIVE_ARGS *args_so_far, + int reg_parm_stack_space, + rtx *old_stack_level, int *old_pending_adj, + int *must_preallocate, int *ecf_flags, + bool *may_tailcall, bool call_from_thunk_p) { location_t loc = EXPR_LOCATION (exp); /* 1 if scanning parms front to back, -1 if scanning back to front. */ @@ -972,7 +975,7 @@ { i = num_actuals - 1, inc = -1; /* In this case, must reverse order of args - so that we compute and push the last arg first. */ + so that we compute and push the last arg first. */ } else { @@ -988,25 +991,25 @@ if (struct_value_addr_value) { - args[j].tree_value = struct_value_addr_value; - j += inc; + args[j].tree_value = struct_value_addr_value; + j += inc; } FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) { - tree argtype = TREE_TYPE (arg); - if (targetm.calls.split_complex_arg - && argtype - && TREE_CODE (argtype) == COMPLEX_TYPE - && targetm.calls.split_complex_arg (argtype)) - { - tree subtype = TREE_TYPE (argtype); - args[j].tree_value = build1 (REALPART_EXPR, subtype, arg); - j += inc; - args[j].tree_value = build1 (IMAGPART_EXPR, subtype, arg); - } - else - args[j].tree_value = arg; - j += inc; + tree argtype = TREE_TYPE (arg); + if (targetm.calls.split_complex_arg + && argtype + && TREE_CODE (argtype) == COMPLEX_TYPE + && targetm.calls.split_complex_arg (argtype)) + { + tree subtype = TREE_TYPE (argtype); + args[j].tree_value = build1 (REALPART_EXPR, subtype, arg); + j += inc; + args[j].tree_value = build1 (IMAGPART_EXPR, subtype, arg); + } + else + args[j].tree_value = arg; + j += inc; } } @@ -1019,7 +1022,7 @@ /* Replace erroneous argument with constant zero. */ if (type == error_mark_node || !COMPLETE_TYPE_P (type)) - args[i].tree_value = integer_zero_node, type = integer_type_node; + args[i].tree_value = integer_zero_node, type = integer_type_node; /* If TYPE is a transparent union or record, pass things the way we would pass the first field of the union or record. We have @@ -1030,17 +1033,17 @@ /* Decide where to pass this arg. - args[i].reg is nonzero if all or part is passed in registers. - - args[i].partial is nonzero if part but not all is passed in registers, - and the exact value says how many bytes are passed in registers. - - args[i].pass_on_stack is nonzero if the argument must at least be - computed on the stack. It may then be loaded back into registers - if args[i].reg is nonzero. - - These decisions are driven by the FUNCTION_... macros and must agree - with those made by function.c. */ + args[i].reg is nonzero if all or part is passed in registers. + + args[i].partial is nonzero if part but not all is passed in registers, + and the exact value says how many bytes are passed in registers. + + args[i].pass_on_stack is nonzero if the argument must at least be + computed on the stack. It may then be loaded back into registers + if args[i].reg is nonzero. + + These decisions are driven by the FUNCTION_... macros and must agree + with those made by function.c. */ /* See if this argument should be passed by invisible reference. */ if (pass_by_reference (args_so_far, TYPE_MODE (type), @@ -1133,7 +1136,7 @@ unsignedp = TYPE_UNSIGNED (type); mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, - fndecl ? TREE_TYPE (fndecl) : fntype, 0); + fndecl ? TREE_TYPE (fndecl) : fntype, 0); args[i].unsignedp = unsignedp; args[i].mode = mode; @@ -1152,57 +1155,57 @@ args[i].tail_call_reg = args[i].reg; if (args[i].reg) - args[i].partial - = targetm.calls.arg_partial_bytes (args_so_far, mode, type, - argpos < n_named_args); + args[i].partial + = targetm.calls.arg_partial_bytes (args_so_far, mode, type, + argpos < n_named_args); args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type); /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]), - it means that we are to pass this arg in the register(s) designated - by the PARALLEL, but also to pass it in the stack. */ + it means that we are to pass this arg in the register(s) designated + by the PARALLEL, but also to pass it in the stack. */ if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL - && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0) - args[i].pass_on_stack = 1; + && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0) + args[i].pass_on_stack = 1; /* If this is an addressable type, we must preallocate the stack - since we must evaluate the object into its final location. - - If this is to be passed in both registers and the stack, it is simpler - to preallocate. */ + since we must evaluate the object into its final location. + + If this is to be passed in both registers and the stack, it is simpler + to preallocate. */ if (TREE_ADDRESSABLE (type) - || (args[i].pass_on_stack && args[i].reg != 0)) - *must_preallocate = 1; + || (args[i].pass_on_stack && args[i].reg != 0)) + *must_preallocate = 1; /* Compute the stack-size of this argument. */ if (args[i].reg == 0 || args[i].partial != 0 - || reg_parm_stack_space > 0 - || args[i].pass_on_stack) - locate_and_pad_parm (mode, type, + || reg_parm_stack_space > 0 + || args[i].pass_on_stack) + locate_and_pad_parm (mode, type, #ifdef STACK_PARMS_IN_REG_PARM_AREA - 1, + 1, #else - args[i].reg != 0, + args[i].reg != 0, #endif - args[i].pass_on_stack ? 0 : args[i].partial, - fndecl, args_size, &args[i].locate); + args[i].pass_on_stack ? 0 : args[i].partial, + fndecl, args_size, &args[i].locate); #ifdef BLOCK_REG_PADDING else - /* The argument is passed entirely in registers. See at which - end it should be padded. */ - args[i].locate.where_pad = - BLOCK_REG_PADDING (mode, type, - int_size_in_bytes (type) <= UNITS_PER_WORD); + /* The argument is passed entirely in registers. See at which + end it should be padded. */ + args[i].locate.where_pad = + BLOCK_REG_PADDING (mode, type, + int_size_in_bytes (type) <= UNITS_PER_WORD); #endif /* Update ARGS_SIZE, the total stack space for args so far. */ args_size->constant += args[i].locate.size.constant; if (args[i].locate.size.var) - ADD_PARM_SIZE (*args_size, args[i].locate.size.var); + ADD_PARM_SIZE (*args_size, args[i].locate.size.var); /* Increment ARGS_SO_FAR, which has info about which arg-registers - have been used, etc. */ + have been used, etc. */ targetm.calls.function_arg_advance (args_so_far, TYPE_MODE (type), type, argpos < n_named_args); @@ -1217,10 +1220,10 @@ static int compute_argument_block_size (int reg_parm_stack_space, - struct args_size *args_size, - tree fndecl ATTRIBUTE_UNUSED, - tree fntype ATTRIBUTE_UNUSED, - int preferred_stack_boundary ATTRIBUTE_UNUSED) + struct args_size *args_size, + tree fndecl ATTRIBUTE_UNUSED, + tree fntype ATTRIBUTE_UNUSED, + int preferred_stack_boundary ATTRIBUTE_UNUSED) { int unadjusted_args_size = args_size->constant; @@ -1241,45 +1244,45 @@ preferred_stack_boundary /= BITS_PER_UNIT; if (preferred_stack_boundary > 1) - { - /* We don't handle this case yet. To handle it correctly we have - to add the delta, round and subtract the delta. - Currently no machine description requires this support. */ - gcc_assert (!(stack_pointer_delta & (preferred_stack_boundary - 1))); - args_size->var = round_up (args_size->var, preferred_stack_boundary); - } + { + /* We don't handle this case yet. To handle it correctly we have + to add the delta, round and subtract the delta. + Currently no machine description requires this support. */ + gcc_assert (!(stack_pointer_delta & (preferred_stack_boundary - 1))); + args_size->var = round_up (args_size->var, preferred_stack_boundary); + } if (reg_parm_stack_space > 0) - { - args_size->var - = size_binop (MAX_EXPR, args_size->var, - ssize_int (reg_parm_stack_space)); - - /* The area corresponding to register parameters is not to count in - the size of the block we need. So make the adjustment. */ - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) - args_size->var - = size_binop (MINUS_EXPR, args_size->var, - ssize_int (reg_parm_stack_space)); - } + { + args_size->var + = size_binop (MAX_EXPR, args_size->var, + ssize_int (reg_parm_stack_space)); + + /* The area corresponding to register parameters is not to count in + the size of the block we need. So make the adjustment. */ + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) + args_size->var + = size_binop (MINUS_EXPR, args_size->var, + ssize_int (reg_parm_stack_space)); + } } else { preferred_stack_boundary /= BITS_PER_UNIT; if (preferred_stack_boundary < 1) - preferred_stack_boundary = 1; + preferred_stack_boundary = 1; args_size->constant = (((args_size->constant - + stack_pointer_delta - + preferred_stack_boundary - 1) - / preferred_stack_boundary - * preferred_stack_boundary) - - stack_pointer_delta); + + stack_pointer_delta + + preferred_stack_boundary - 1) + / preferred_stack_boundary + * preferred_stack_boundary) + - stack_pointer_delta); args_size->constant = MAX (args_size->constant, - reg_parm_stack_space); + reg_parm_stack_space); if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) - args_size->constant -= reg_parm_stack_space; + args_size->constant -= reg_parm_stack_space; } return unadjusted_args_size; } @@ -1318,37 +1321,37 @@ enum machine_mode mode; if (TREE_CODE (args[i].tree_value) != CALL_EXPR) - continue; + continue; /* If this is an addressable type, we cannot pre-evaluate it. */ type = TREE_TYPE (args[i].tree_value); gcc_assert (!TREE_ADDRESSABLE (type)); args[i].initial_value = args[i].value - = expand_normal (args[i].tree_value); + = expand_normal (args[i].tree_value); mode = TYPE_MODE (type); if (mode != args[i].mode) - { - int unsignedp = args[i].unsignedp; - args[i].value - = convert_modes (args[i].mode, mode, - args[i].value, args[i].unsignedp); - - /* CSE will replace this only if it contains args[i].value - pseudo, so convert it down to the declared mode using - a SUBREG. */ - if (REG_P (args[i].value) - && GET_MODE_CLASS (args[i].mode) == MODE_INT - && promote_mode (type, mode, &unsignedp) != args[i].mode) - { - args[i].initial_value - = gen_lowpart_SUBREG (mode, args[i].value); - SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1; - SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value, - args[i].unsignedp); - } - } + { + int unsignedp = args[i].unsignedp; + args[i].value + = convert_modes (args[i].mode, mode, + args[i].value, args[i].unsignedp); + + /* CSE will replace this only if it contains args[i].value + pseudo, so convert it down to the declared mode using + a SUBREG. */ + if (REG_P (args[i].value) + && GET_MODE_CLASS (args[i].mode) == MODE_INT + && promote_mode (type, mode, &unsignedp) != args[i].mode) + { + args[i].initial_value + = gen_lowpart_SUBREG (mode, args[i].value); + SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1; + SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value, + args[i].unsignedp); + } + } } } @@ -1358,7 +1361,7 @@ static int finalize_must_preallocate (int must_preallocate, int num_actuals, - struct arg_data *args, struct args_size *args_size) + struct arg_data *args, struct args_size *args_size) { /* See if we have or want to preallocate stack space. @@ -1386,24 +1389,24 @@ int i; for (i = 0; i < num_actuals && ! must_preallocate; i++) - { - if (args[i].partial > 0 && ! args[i].pass_on_stack) - partial_seen = 1; - else if (partial_seen && args[i].reg == 0) - must_preallocate = 1; - - if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode - && (TREE_CODE (args[i].tree_value) == CALL_EXPR - || TREE_CODE (args[i].tree_value) == TARGET_EXPR - || TREE_CODE (args[i].tree_value) == COND_EXPR - || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))) - copy_to_evaluate_size - += int_size_in_bytes (TREE_TYPE (args[i].tree_value)); - } + { + if (args[i].partial > 0 && ! args[i].pass_on_stack) + partial_seen = 1; + else if (partial_seen && args[i].reg == 0) + must_preallocate = 1; + + if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode + && (TREE_CODE (args[i].tree_value) == CALL_EXPR + || TREE_CODE (args[i].tree_value) == TARGET_EXPR + || TREE_CODE (args[i].tree_value) == COND_EXPR + || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))) + copy_to_evaluate_size + += int_size_in_bytes (TREE_TYPE (args[i].tree_value)); + } if (copy_to_evaluate_size * 2 >= args_size->constant - && args_size->constant > 0) - must_preallocate = 1; + && args_size->constant > 0) + must_preallocate = 1; } return must_preallocate; } @@ -1425,87 +1428,87 @@ int i, arg_offset = 0; if (GET_CODE (argblock) == PLUS) - arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1)); + arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1)); for (i = 0; i < num_actuals; i++) - { - rtx offset = ARGS_SIZE_RTX (args[i].locate.offset); - rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset); - rtx addr; - unsigned int align, boundary; - unsigned int units_on_stack = 0; - enum machine_mode partial_mode = VOIDmode; - - /* Skip this parm if it will not be passed on the stack. */ - if (! args[i].pass_on_stack - && args[i].reg != 0 - && args[i].partial == 0) - continue; - - if (CONST_INT_P (offset)) - addr = plus_constant (arg_reg, INTVAL (offset)); - else - addr = gen_rtx_PLUS (Pmode, arg_reg, offset); - - addr = plus_constant (addr, arg_offset); - - if (args[i].partial != 0) - { - /* Only part of the parameter is being passed on the stack. - Generate a simple memory reference of the correct size. */ - units_on_stack = args[i].locate.size.constant; - partial_mode = mode_for_size (units_on_stack * BITS_PER_UNIT, - MODE_INT, 1); - args[i].stack = gen_rtx_MEM (partial_mode, addr); - set_mem_size (args[i].stack, GEN_INT (units_on_stack)); - } - else - { - args[i].stack = gen_rtx_MEM (args[i].mode, addr); - set_mem_attributes (args[i].stack, - TREE_TYPE (args[i].tree_value), 1); - } - align = BITS_PER_UNIT; - boundary = args[i].locate.boundary; - if (args[i].locate.where_pad != downward) - align = boundary; - else if (CONST_INT_P (offset)) - { - align = INTVAL (offset) * BITS_PER_UNIT | boundary; - align = align & -align; - } - set_mem_align (args[i].stack, align); - - if (CONST_INT_P (slot_offset)) - addr = plus_constant (arg_reg, INTVAL (slot_offset)); - else - addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset); - - addr = plus_constant (addr, arg_offset); - - if (args[i].partial != 0) - { - /* Only part of the parameter is being passed on the stack. - Generate a simple memory reference of the correct size. - */ - args[i].stack_slot = gen_rtx_MEM (partial_mode, addr); - set_mem_size (args[i].stack_slot, GEN_INT (units_on_stack)); - } - else - { - args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr); - set_mem_attributes (args[i].stack_slot, - TREE_TYPE (args[i].tree_value), 1); - } - set_mem_align (args[i].stack_slot, args[i].locate.boundary); - - /* Function incoming arguments may overlap with sibling call - outgoing arguments and we cannot allow reordering of reads - from function arguments with stores to outgoing arguments - of sibling calls. */ - set_mem_alias_set (args[i].stack, 0); - set_mem_alias_set (args[i].stack_slot, 0); - } + { + rtx offset = ARGS_SIZE_RTX (args[i].locate.offset); + rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset); + rtx addr; + unsigned int align, boundary; + unsigned int units_on_stack = 0; + enum machine_mode partial_mode = VOIDmode; + + /* Skip this parm if it will not be passed on the stack. */ + if (! args[i].pass_on_stack + && args[i].reg != 0 + && args[i].partial == 0) + continue; + + if (CONST_INT_P (offset)) + addr = plus_constant (arg_reg, INTVAL (offset)); + else + addr = gen_rtx_PLUS (Pmode, arg_reg, offset); + + addr = plus_constant (addr, arg_offset); + + if (args[i].partial != 0) + { + /* Only part of the parameter is being passed on the stack. + Generate a simple memory reference of the correct size. */ + units_on_stack = args[i].locate.size.constant; + partial_mode = mode_for_size (units_on_stack * BITS_PER_UNIT, + MODE_INT, 1); + args[i].stack = gen_rtx_MEM (partial_mode, addr); + set_mem_size (args[i].stack, GEN_INT (units_on_stack)); + } + else + { + args[i].stack = gen_rtx_MEM (args[i].mode, addr); + set_mem_attributes (args[i].stack, + TREE_TYPE (args[i].tree_value), 1); + } + align = BITS_PER_UNIT; + boundary = args[i].locate.boundary; + if (args[i].locate.where_pad != downward) + align = boundary; + else if (CONST_INT_P (offset)) + { + align = INTVAL (offset) * BITS_PER_UNIT | boundary; + align = align & -align; + } + set_mem_align (args[i].stack, align); + + if (CONST_INT_P (slot_offset)) + addr = plus_constant (arg_reg, INTVAL (slot_offset)); + else + addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset); + + addr = plus_constant (addr, arg_offset); + + if (args[i].partial != 0) + { + /* Only part of the parameter is being passed on the stack. + Generate a simple memory reference of the correct size. + */ + args[i].stack_slot = gen_rtx_MEM (partial_mode, addr); + set_mem_size (args[i].stack_slot, GEN_INT (units_on_stack)); + } + else + { + args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr); + set_mem_attributes (args[i].stack_slot, + TREE_TYPE (args[i].tree_value), 1); + } + set_mem_align (args[i].stack_slot, args[i].locate.boundary); + + /* Function incoming arguments may overlap with sibling call + outgoing arguments and we cannot allow reordering of reads + from function arguments with stores to outgoing arguments + of sibling calls. */ + set_mem_alias_set (args[i].stack, 0); + set_mem_alias_set (args[i].stack_slot, 0); + } } } @@ -1526,12 +1529,12 @@ if (fndecl) { /* If this is the first use of the function, see if we need to - make an external definition for it. */ + make an external definition for it. */ if (!TREE_USED (fndecl) && fndecl != current_function_decl) - { - assemble_external (fndecl); - TREE_USED (fndecl) = 1; - } + { + assemble_external (fndecl); + TREE_USED (fndecl) = 1; + } /* Get a SYMBOL_REF rtx for the function address. */ funexp = XEXP (DECL_RTL (fndecl), 0); @@ -1541,7 +1544,7 @@ { push_temp_slots (); funexp = expand_normal (addr); - pop_temp_slots (); /* FUNEXP can't be BLKmode. */ + pop_temp_slots (); /* FUNEXP can't be BLKmode. */ } return funexp; } @@ -1559,13 +1562,13 @@ if (addr == crtl->args.internal_arg_pointer) i = 0; else if (GET_CODE (addr) == PLUS - && XEXP (addr, 0) == crtl->args.internal_arg_pointer - && CONST_INT_P (XEXP (addr, 1))) + && XEXP (addr, 0) == crtl->args.internal_arg_pointer + && CONST_INT_P (XEXP (addr, 1))) i = INTVAL (XEXP (addr, 1)); /* Return true for arg pointer based indexed addressing. */ else if (GET_CODE (addr) == PLUS - && (XEXP (addr, 0) == crtl->args.internal_arg_pointer - || XEXP (addr, 1) == crtl->args.internal_arg_pointer)) + && (XEXP (addr, 0) == crtl->args.internal_arg_pointer + || XEXP (addr, 1) == crtl->args.internal_arg_pointer)) return true; else return false; @@ -1578,9 +1581,9 @@ unsigned HOST_WIDE_INT k; for (k = 0; k < size; k++) - if (i + k < stored_args_map->n_bits - && TEST_BIT (stored_args_map, i + k)) - return true; + if (i + k < stored_args_map->n_bits + && TEST_BIT (stored_args_map, i + k)) + return true; } return false; @@ -1598,76 +1601,76 @@ static void load_register_parameters (struct arg_data *args, int num_actuals, - rtx *call_fusage, int flags, int is_sibcall, - int *sibcall_failure) + rtx *call_fusage, int flags, int is_sibcall, + int *sibcall_failure) { int i, j; for (i = 0; i < num_actuals; i++) { rtx reg = ((flags & ECF_SIBCALL) - ? args[i].tail_call_reg : args[i].reg); + ? args[i].tail_call_reg : args[i].reg); if (reg) - { - int partial = args[i].partial; - int nregs; - int size = 0; - rtx before_arg = get_last_insn (); - /* Set non-negative if we must move a word at a time, even if - just one word (e.g, partial == 4 && mode == DFmode). Set - to -1 if we just use a normal move insn. This value can be - zero if the argument is a zero size structure. */ - nregs = -1; - if (GET_CODE (reg) == PARALLEL) - ; - else if (partial) - { - gcc_assert (partial % UNITS_PER_WORD == 0); - nregs = partial / UNITS_PER_WORD; - } - else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode) - { - size = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); - nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; - } - else - size = GET_MODE_SIZE (args[i].mode); - - /* Handle calls that pass values in multiple non-contiguous - locations. The Irix 6 ABI has examples of this. */ - - if (GET_CODE (reg) == PARALLEL) - emit_group_move (reg, args[i].parallel_value); - - /* If simple case, just do move. If normal partial, store_one_arg - has already loaded the register for us. In all other cases, - load the register(s) from memory. */ - - else if (nregs == -1) - { - emit_move_insn (reg, args[i].value); + { + int partial = args[i].partial; + int nregs; + int size = 0; + rtx before_arg = get_last_insn (); + /* Set non-negative if we must move a word at a time, even if + just one word (e.g, partial == 4 && mode == DFmode). Set + to -1 if we just use a normal move insn. This value can be + zero if the argument is a zero size structure. */ + nregs = -1; + if (GET_CODE (reg) == PARALLEL) + ; + else if (partial) + { + gcc_assert (partial % UNITS_PER_WORD == 0); + nregs = partial / UNITS_PER_WORD; + } + else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode) + { + size = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); + nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; + } + else + size = GET_MODE_SIZE (args[i].mode); + + /* Handle calls that pass values in multiple non-contiguous + locations. The Irix 6 ABI has examples of this. */ + + if (GET_CODE (reg) == PARALLEL) + emit_group_move (reg, args[i].parallel_value); + + /* If simple case, just do move. If normal partial, store_one_arg + has already loaded the register for us. In all other cases, + load the register(s) from memory. */ + + else if (nregs == -1) + { + emit_move_insn (reg, args[i].value); #ifdef BLOCK_REG_PADDING - /* Handle case where we have a value that needs shifting - up to the msb. eg. a QImode value and we're padding - upward on a BYTES_BIG_ENDIAN machine. */ - if (size < UNITS_PER_WORD - && (args[i].locate.where_pad - == (BYTES_BIG_ENDIAN ? upward : downward))) - { - rtx x; - int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT; - - /* Assigning REG here rather than a temp makes CALL_FUSAGE - report the whole reg as used. Strictly speaking, the - call only uses SIZE bytes at the msb end, but it doesn't - seem worth generating rtl to say that. */ - reg = gen_rtx_REG (word_mode, REGNO (reg)); - x = expand_shift (LSHIFT_EXPR, word_mode, reg, - build_int_cst (NULL_TREE, shift), - reg, 1); - if (x != reg) - emit_move_insn (reg, x); - } + /* Handle case where we have a value that needs shifting + up to the msb. eg. a QImode value and we're padding + upward on a BYTES_BIG_ENDIAN machine. */ + if (size < UNITS_PER_WORD + && (args[i].locate.where_pad + == (BYTES_BIG_ENDIAN ? upward : downward))) + { + rtx x; + int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT; + + /* Assigning REG here rather than a temp makes CALL_FUSAGE + report the whole reg as used. Strictly speaking, the + call only uses SIZE bytes at the msb end, but it doesn't + seem worth generating rtl to say that. */ + reg = gen_rtx_REG (word_mode, REGNO (reg)); + x = expand_shift (LSHIFT_EXPR, word_mode, reg, + build_int_cst (NULL_TREE, shift), + reg, 1); + if (x != reg) + emit_move_insn (reg, x); + } #endif } @@ -1694,46 +1697,46 @@ /* Handle a BLKmode that needs shifting. */ if (nregs == 1 && size < UNITS_PER_WORD #ifdef BLOCK_REG_PADDING - && args[i].locate.where_pad == downward + && args[i].locate.where_pad == downward #else - && BYTES_BIG_ENDIAN + && BYTES_BIG_ENDIAN #endif - ) - { - rtx tem = operand_subword_force (mem, 0, args[i].mode); - rtx ri = gen_rtx_REG (word_mode, REGNO (reg)); - rtx x = gen_reg_rtx (word_mode); - int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT; - enum tree_code dir = BYTES_BIG_ENDIAN ? RSHIFT_EXPR - : LSHIFT_EXPR; - - emit_move_insn (x, tem); - x = expand_shift (dir, word_mode, x, - build_int_cst (NULL_TREE, shift), - ri, 1); - if (x != ri) - emit_move_insn (ri, x); - } - else - move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode); - } - - /* When a parameter is a block, and perhaps in other cases, it is - possible that it did a load from an argument slot that was - already clobbered. */ - if (is_sibcall - && check_sibcall_argument_overlap (before_arg, &args[i], 0)) - *sibcall_failure = 1; - - /* Handle calls that pass values in multiple non-contiguous - locations. The Irix 6 ABI has examples of this. */ - if (GET_CODE (reg) == PARALLEL) - use_group_regs (call_fusage, reg); - else if (nregs == -1) - use_reg (call_fusage, reg); - else if (nregs > 0) - use_regs (call_fusage, REGNO (reg), nregs); - } + ) + { + rtx tem = operand_subword_force (mem, 0, args[i].mode); + rtx ri = gen_rtx_REG (word_mode, REGNO (reg)); + rtx x = gen_reg_rtx (word_mode); + int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT; + enum tree_code dir = BYTES_BIG_ENDIAN ? RSHIFT_EXPR + : LSHIFT_EXPR; + + emit_move_insn (x, tem); + x = expand_shift (dir, word_mode, x, + build_int_cst (NULL_TREE, shift), + ri, 1); + if (x != ri) + emit_move_insn (ri, x); + } + else + move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode); + } + + /* When a parameter is a block, and perhaps in other cases, it is + possible that it did a load from an argument slot that was + already clobbered. */ + if (is_sibcall + && check_sibcall_argument_overlap (before_arg, &args[i], 0)) + *sibcall_failure = 1; + + /* Handle calls that pass values in multiple non-contiguous + locations. The Irix 6 ABI has examples of this. */ + if (GET_CODE (reg) == PARALLEL) + use_group_regs (call_fusage, reg); + else if (nregs == -1) + use_reg (call_fusage, reg); + else if (nregs > 0) + use_regs (call_fusage, REGNO (reg), nregs); + } } } @@ -1748,8 +1751,8 @@ static int combine_pending_stack_adjustment_and_call (int unadjusted_args_size, - struct args_size *args_size, - unsigned int preferred_unit_stack_boundary) + struct args_size *args_size, + unsigned int preferred_unit_stack_boundary) { /* The number of bytes to pop so that the stack will be under-aligned by UNADJUSTED_ARGS_SIZE bytes. */ @@ -1778,9 +1781,9 @@ if (preferred_unit_stack_boundary > 1) { if (unadjusted_alignment > 0) - adjustment -= preferred_unit_stack_boundary - unadjusted_alignment; + adjustment -= preferred_unit_stack_boundary - unadjusted_alignment; else - adjustment += unadjusted_alignment; + adjustment += unadjusted_alignment; } /* Now, sets ARGS_SIZE->CONSTANT so that we pop the right number of @@ -1813,23 +1816,23 @@ if (code == MEM) return mem_overlaps_already_clobbered_arg_p (XEXP (x, 0), - GET_MODE_SIZE (GET_MODE (x))); + GET_MODE_SIZE (GET_MODE (x))); /* Scan all subexpressions. */ fmt = GET_RTX_FORMAT (code); for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) { if (*fmt == 'e') - { - if (check_sibcall_argument_overlap_1 (XEXP (x, i))) - return 1; - } + { + if (check_sibcall_argument_overlap_1 (XEXP (x, i))) + return 1; + } else if (*fmt == 'E') - { - for (j = 0; j < XVECLEN (x, i); j++) - if (check_sibcall_argument_overlap_1 (XVECEXP (x, i, j))) - return 1; - } + { + for (j = 0; j < XVECLEN (x, i); j++) + if (check_sibcall_argument_overlap_1 (XVECEXP (x, i, j))) + return 1; + } } return 0; } @@ -1853,7 +1856,7 @@ for (; insn; insn = NEXT_INSN (insn)) if (INSN_P (insn) - && check_sibcall_argument_overlap_1 (PATTERN (insn))) + && check_sibcall_argument_overlap_1 (PATTERN (insn))) break; if (mark_stored_args_map) @@ -1865,7 +1868,7 @@ #endif for (high = low + arg->locate.size.constant; low < high; low++) - SET_BIT (stored_args_map, low); + SET_BIT (stored_args_map, low); } return insn != NULL_RTX; } @@ -1888,11 +1891,15 @@ of the MIPS port, which requires SImode values to be sign-extended when stored in 64-bit registers. */ if (!force_expand_binop (GET_MODE (value), left_p ? ashl_optab : ashr_optab, - value, GEN_INT (shift), value, 1, OPTAB_WIDEN)) + value, GEN_INT (shift), value, 1, OPTAB_WIDEN)) gcc_unreachable (); return true; } +#ifndef noCbC +#include "cbc-tree.h" +#endif + /* If X is a likely-spilled register value, copy it to a pseudo register and return that register. Return X otherwise. */ @@ -1906,9 +1913,9 @@ && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (x)))) { /* Make sure that we generate a REG rather than a CONCAT. - Moves into CONCATs can need nontrivial instructions, - and the whole point of this function is to avoid - using the hard register directly in such a situation. */ + Moves into CONCATs can need nontrivial instructions, + and the whole point of this function is to avoid + using the hard register directly in such a situation. */ generating_concat_p = 0; new_rtx = gen_reg_rtx (GET_MODE (x)); generating_concat_p = 1; @@ -1918,7 +1925,7 @@ return x; } -/* Generate all the code for a CALL_EXPR exp +/* Generate all the code for a function call and return an rtx for its value. Store the value in TARGET (specified as an rtx) if convenient. If the value is stored in TARGET then TARGET is returned. @@ -2014,7 +2021,7 @@ /* Define the boundary of the register parm stack space that needs to be saved, if any. */ int low_to_save, high_to_save; - rtx save_area = 0; /* Place that it is saved */ + rtx save_area = 0; /* Place that it is saved */ #endif int initial_highest_arg_in_use = highest_outgoing_arg_in_use; @@ -2076,25 +2083,25 @@ if ((flags & (ECF_CONST | ECF_PURE)) && (!(flags & ECF_LOOPING_CONST_OR_PURE)) && (ignore || target == const0_rtx - || TYPE_MODE (rettype) == VOIDmode)) + || TYPE_MODE (rettype) == VOIDmode)) { bool volatilep = false; tree arg; call_expr_arg_iterator iter; FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) - if (TREE_THIS_VOLATILE (arg)) - { - volatilep = true; - break; - } + if (TREE_THIS_VOLATILE (arg)) + { + volatilep = true; + break; + } if (! volatilep) - { - FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) - expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL); - return const0_rtx; - } + { + FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) + expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL); + return const0_rtx; + } } #ifdef REG_PARM_STACK_SPACE @@ -2115,25 +2122,25 @@ #ifdef PCC_STATIC_STRUCT_RETURN { - pcc_struct_value = 1; + pcc_struct_value = 1; } #else /* not PCC_STATIC_STRUCT_RETURN */ { - struct_value_size = int_size_in_bytes (rettype); - - if (target && MEM_P (target) && CALL_EXPR_RETURN_SLOT_OPT (exp)) - structure_value_addr = XEXP (target, 0); - else - { - /* For variable-sized objects, we must be called with a target - specified. If we were to allocate space on the stack here, - we would have no way of knowing when to free it. */ - rtx d = assign_temp (rettype, 0, 1, 1); - - mark_temp_addr_taken (d); - structure_value_addr = XEXP (d, 0); - target = 0; - } + struct_value_size = int_size_in_bytes (rettype); + + if (target && MEM_P (target) && CALL_EXPR_RETURN_SLOT_OPT (exp)) + structure_value_addr = XEXP (target, 0); + else + { + /* For variable-sized objects, we must be called with a target + specified. If we were to allocate space on the stack here, + we would have no way of knowing when to free it. */ + rtx d = assign_temp (rettype, 0, 1, 1); + + mark_temp_addr_taken (d); + structure_value_addr = XEXP (d, 0); + target = 0; + } } #endif /* not PCC_STATIC_STRUCT_RETURN */ } @@ -2144,14 +2151,14 @@ { struct cgraph_rtl_info *i = cgraph_rtl_info (fndecl); /* Without automatic stack alignment, we can't increase preferred - stack boundary. With automatic stack alignment, it is - unnecessary since unless we can guarantee that all callers will - align the outgoing stack properly, callee has to align its - stack anyway. */ + stack boundary. With automatic stack alignment, it is + unnecessary since unless we can guarantee that all callers will + align the outgoing stack properly, callee has to align its + stack anyway. */ if (i - && i->preferred_incoming_stack_boundary - && i->preferred_incoming_stack_boundary < preferred_stack_boundary) - preferred_stack_boundary = i->preferred_incoming_stack_boundary; + && i->preferred_incoming_stack_boundary + && i->preferred_incoming_stack_boundary < preferred_stack_boundary) + preferred_stack_boundary = i->preferred_incoming_stack_boundary; } /* Operand 0 is a pointer-to-function; get the type of the function. */ @@ -2167,12 +2174,12 @@ call_expr_arg_iterator iter; tree arg; FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) - { - tree type = TREE_TYPE (arg); - if (type && TREE_CODE (type) == COMPLEX_TYPE - && targetm.calls.split_complex_arg (type)) - num_complex_actuals++; - } + { + tree type = TREE_TYPE (arg); + if (type && TREE_CODE (type) == COMPLEX_TYPE + && targetm.calls.split_complex_arg (type)) + num_complex_actuals++; + } type_arg_types = split_complex_types (TYPE_ARG_TYPES (funtype)); } else @@ -2187,20 +2194,20 @@ if (structure_value_addr && struct_value == 0) { /* If structure_value_addr is a REG other than - virtual_outgoing_args_rtx, we can use always use it. If it - is not a REG, we must always copy it into a register. - If it is virtual_outgoing_args_rtx, we must copy it to another - register in some cases. */ + virtual_outgoing_args_rtx, we can use always use it. If it + is not a REG, we must always copy it into a register. + If it is virtual_outgoing_args_rtx, we must copy it to another + register in some cases. */ rtx temp = (!REG_P (structure_value_addr) - || (ACCUMULATE_OUTGOING_ARGS - && stack_arg_under_construction - && structure_value_addr == virtual_outgoing_args_rtx) - ? copy_addr_to_reg (convert_memory_address - (Pmode, structure_value_addr)) - : structure_value_addr); + || (ACCUMULATE_OUTGOING_ARGS + && stack_arg_under_construction + && structure_value_addr == virtual_outgoing_args_rtx) + ? copy_addr_to_reg (convert_memory_address + (Pmode, structure_value_addr)) + : structure_value_addr); structure_value_addr_value = - make_tree (build_pointer_type (TREE_TYPE (funtype)), temp); + make_tree (build_pointer_type (TREE_TYPE (funtype)), temp); structure_value_addr_parm = 1; } @@ -2214,8 +2221,8 @@ if (type_arg_types != 0) n_named_args = (list_length (type_arg_types) - /* Count the struct value address, if it is passed as a parm. */ - + structure_value_addr_parm); + /* Count the struct value address, if it is passed as a parm. */ + + structure_value_addr_parm); else /* If we know nothing, treat all args as named. */ n_named_args = num_actuals; @@ -2250,7 +2257,7 @@ && targetm.calls.strict_argument_naming (&args_so_far)) ; else if (type_arg_types != 0 - && ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far)) + && ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far)) /* Don't include the last named arg. */ --n_named_args; else @@ -2264,20 +2271,20 @@ /* Build up entries in the ARGS array, compute the size of the arguments into ARGS_SIZE, etc. */ initialize_argument_information (num_actuals, args, &args_size, - n_named_args, exp, - structure_value_addr_value, fndecl, fntype, - &args_so_far, reg_parm_stack_space, - &old_stack_level, &old_pending_adj, - &must_preallocate, &flags, - &try_tail_call, CALL_FROM_THUNK_P (exp)); + n_named_args, exp, + structure_value_addr_value, fndecl, fntype, + &args_so_far, reg_parm_stack_space, + &old_stack_level, &old_pending_adj, + &must_preallocate, &flags, + &try_tail_call, CALL_FROM_THUNK_P (exp)); if (args_size.var) must_preallocate = 1; /* Now make final decision about preallocating stack space. */ must_preallocate = finalize_must_preallocate (must_preallocate, - num_actuals, args, - &args_size); + num_actuals, args, + &args_size); /* If the structure value address will reference the stack pointer, we must stabilize it. We don't need to do this if we know that we are @@ -2285,10 +2292,10 @@ if (structure_value_addr && (reg_mentioned_p (virtual_stack_dynamic_rtx, structure_value_addr) - || reg_mentioned_p (virtual_outgoing_args_rtx, - structure_value_addr)) + || reg_mentioned_p (virtual_outgoing_args_rtx, + structure_value_addr)) && (args_size.var - || (!ACCUMULATE_OUTGOING_ARGS && args_size.constant))) + || (!ACCUMULATE_OUTGOING_ARGS && args_size.constant))) structure_value_addr = copy_to_reg (structure_value_addr); /* Tail calls can make things harder to debug, and we've traditionally @@ -2296,8 +2303,13 @@ expanding a call, as that means we're an argument. Don't try if there's cleanups, as we know there's code to follow the call. */ + // -O2オプションがないときも末尾最適化が行われるように(Code Segmentのみ) if (currently_expanding_call++ != 0 +#ifndef noCbC + || ((!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))) && !flag_optimize_sibling_calls) +#else || !flag_optimize_sibling_calls +#endif || args_size.var || dbg_cnt (tail_call) == false) try_tail_call = 0; @@ -2311,33 +2323,33 @@ #endif || !try_tail_call /* Doing sibling call optimization needs some work, since - structure_value_addr can be allocated on the stack. - It does not seem worth the effort since few optimizable - sibling calls will return a structure. */ + structure_value_addr can be allocated on the stack. + It does not seem worth the effort since few optimizable + sibling calls will return a structure. */ || structure_value_addr != NULL_RTX #ifdef REG_PARM_STACK_SPACE /* If outgoing reg parm stack space changes, we can not do sibcall. */ || (OUTGOING_REG_PARM_STACK_SPACE (funtype) - != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))) + != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))) || (reg_parm_stack_space != REG_PARM_STACK_SPACE (fndecl)) #endif /* Check whether the target is able to optimize the call - into a sibcall. */ + into a sibcall. */ || !targetm.function_ok_for_sibcall (fndecl, exp) /* Functions that do not return exactly once may not be sibcall - optimized. */ + optimized. */ || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN)) || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) /* If the called function is nested in the current one, it might access - some of the caller's arguments, but could clobber them beforehand if - the argument areas are shared. */ + some of the caller's arguments, but could clobber them beforehand if + the argument areas are shared. */ || (fndecl && decl_function_context (fndecl) == current_function_decl) /* If this function requires more stack slots than the current - function, we cannot change it into a sibling call. - crtl->args.pretend_args_size is not part of the - stack allocated by our caller. */ + function, we cannot change it into a sibling call. + crtl->args.pretend_args_size is not part of the + stack allocated by our caller. */ || args_size.constant > (crtl->args.size - - crtl->args.pretend_args_size) + - crtl->args.pretend_args_size) /* If the callee pops its own arguments, then it must pop exactly the same number of arguments as the current function. */ || (targetm.calls.return_pops_args (fndecl, funtype, args_size.constant) @@ -2361,21 +2373,21 @@ callee_unsignedp = TYPE_UNSIGNED (TREE_TYPE (funtype)); callee_mode = TYPE_MODE (TREE_TYPE (funtype)); caller_promoted_mode - = promote_function_mode (TREE_TYPE (caller_res), caller_mode, - &caller_unsignedp, - TREE_TYPE (current_function_decl), 1); + = promote_function_mode (TREE_TYPE (caller_res), caller_mode, + &caller_unsignedp, + TREE_TYPE (current_function_decl), 1); callee_promoted_mode - = promote_function_mode (TREE_TYPE (funtype), callee_mode, - &callee_unsignedp, - funtype, 1); + = promote_function_mode (TREE_TYPE (funtype), callee_mode, + &callee_unsignedp, + funtype, 1); if (caller_mode != VOIDmode - && (caller_promoted_mode != callee_promoted_mode - || ((caller_mode != caller_promoted_mode - || callee_mode != callee_promoted_mode) - && (caller_unsignedp != callee_unsignedp - || GET_MODE_BITSIZE (caller_mode) - < GET_MODE_BITSIZE (callee_mode))))) - try_tail_call = 0; + && (caller_promoted_mode != callee_promoted_mode + || ((caller_mode != caller_promoted_mode + || callee_mode != callee_promoted_mode) + && (caller_unsignedp != callee_unsignedp + || GET_MODE_BITSIZE (caller_mode) + < GET_MODE_BITSIZE (callee_mode))))) + try_tail_call = 0; } /* Ensure current function's preferred stack boundary is at least @@ -2388,6 +2400,67 @@ preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; +#ifndef noCbC + if ( fntype + && CbC_IS_CbC_GOTO (exp) // it's better? than CALL_EXPR_TAILCALL() + && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl)) + ) + { + + args_size.constant = CbC_PRETENDED_STACK_SIZE; + // try_tail_callを矯正的に立たせて末尾最適化を必ずうように変更 + // -> expand_cbc_gotは不要に。 + /* return expand_cbc_goto(exp, target, fndecl, funtype, fntype, + * addr, ignore, flags, num_actuals, args, &args_size, + * args_so_far, + * old_stack_level, reg_parm_stack_space, old_pending_adj, + * preferred_stack_boundary, preferred_unit_stack_boundary, + * structure_value_addr, old_inhibit_defer_pop); */ + } + else if ( CbC_IS_CbC_GOTO (exp) ) + { + // TODO: 関数からコードセグメントへの遷移 + /* + if (fndecl) + { + char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning(0, "no warning: code segment `%s' has been called from a function.", name_callee); + } + else + { + warning(0, "no warning: unnamed code segment has been called from a function."); + } + */ + args_size.constant = CbC_PRETENDED_STACK_SIZE; + } + else if ( fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) ) + { + // 警告コードセグメントを関数呼び出し + //char *name= IDENTIFIER_POINTER(DECL_NAME(fndecl)); + //warning (0, "code segment `%s' has been \"called\" instead \"goto\".", name); + } + else if (CbC_IS_CODE_SEGMENT(TREE_TYPE (current_function_decl)) ) + { + // code segment内部からの関数呼び出し。なんも問題ない。 + //warning (0, "no warning: normal call from a code segment."); + } +#endif + + // when tail call optimization flag was down, warn about them. + // and flag it to force a tail call optimize. +#ifndef noCbC + if (fndecl && CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)) + && CbC_IS_CODE_SEGMENT (TREE_TYPE (current_function_decl)) + && try_tail_call == 0) + { + location_t loc = EXPR_LOCATION (exp); + char *name_callee = IDENTIFIER_POINTER(DECL_NAME(fndecl)); + warning_at (loc, 0, "transition to code segment \"%s\" with CbC goto, but tail call optimization was cut.", + name_callee); + try_tail_call = 1; + } +#endif + /* We want to make two insn chains; one for a sibling call, the other for a normal call. We will select one of the two chains after initial RTL generation is complete. */ @@ -2395,95 +2468,110 @@ { int sibcall_failure = 0; /* We want to emit any pending stack adjustments before the tail - recursion "call". That way we know any adjustment after the tail - recursion call can be ignored if we indeed use the tail - call expansion. */ + recursion "call". That way we know any adjustment after the tail + recursion call can be ignored if we indeed use the tail + call expansion. */ int save_pending_stack_adjust = 0; int save_stack_pointer_delta = 0; rtx insns; rtx before_call, next_arg_reg, after_args; if (pass == 0) - { - /* State variables we need to save and restore between - iterations. */ - save_pending_stack_adjust = pending_stack_adjust; - save_stack_pointer_delta = stack_pointer_delta; - } + { + /* State variables we need to save and restore between + iterations. */ + save_pending_stack_adjust = pending_stack_adjust; + save_stack_pointer_delta = stack_pointer_delta; + } if (pass) - flags &= ~ECF_SIBCALL; + flags &= ~ECF_SIBCALL; else - flags |= ECF_SIBCALL; + flags |= ECF_SIBCALL; /* Other state variables that we must reinitialize each time - through the loop (that are not initialized by the loop itself). */ + through the loop (that are not initialized by the loop itself). */ argblock = 0; call_fusage = 0; /* Start a new sequence for the normal call case. - From this point on, if the sibling call fails, we want to set - sibcall_failure instead of continuing the loop. */ + From this point on, if the sibling call fails, we want to set + sibcall_failure instead of continuing the loop. */ start_sequence (); /* Don't let pending stack adjusts add up to too much. - Also, do all pending adjustments now if there is any chance - this might be a call to alloca or if we are expanding a sibling - call sequence. - Also do the adjustments before a throwing call, otherwise - exception handling can fail; PR 19225. */ + Also, do all pending adjustments now if there is any chance + this might be a call to alloca or if we are expanding a sibling + call sequence. + Also do the adjustments before a throwing call, otherwise + exception handling can fail; PR 19225. */ if (pending_stack_adjust >= 32 - || (pending_stack_adjust > 0 - && (flags & ECF_MAY_BE_ALLOCA)) - || (pending_stack_adjust > 0 - && flag_exceptions && !(flags & ECF_NOTHROW)) - || pass == 0) - do_pending_stack_adjust (); + || (pending_stack_adjust > 0 + && (flags & ECF_MAY_BE_ALLOCA)) + || (pending_stack_adjust > 0 + && flag_exceptions && !(flags & ECF_NOTHROW)) + || pass == 0) + do_pending_stack_adjust (); /* Precompute any arguments as needed. */ if (pass) - precompute_arguments (num_actuals, args); + precompute_arguments (num_actuals, args); /* Now we are about to start emitting insns that can be deleted - if a libcall is deleted. */ + if a libcall is deleted. */ if (pass && (flags & ECF_MALLOC)) - start_sequence (); + start_sequence (); if (pass == 0 && crtl->stack_protect_guard) - stack_protect_epilogue (); + stack_protect_epilogue (); adjusted_args_size = args_size; /* Compute the actual size of the argument block required. The variable - and constant sizes must be combined, the size may have to be rounded, - and there may be a minimum required size. When generating a sibcall - pattern, do not round up, since we'll be re-using whatever space our - caller provided. */ + and constant sizes must be combined, the size may have to be rounded, + and there may be a minimum required size. When generating a sibcall + pattern, do not round up, since we'll be re-using whatever space our + caller provided. */ +#ifndef noCbC + if ( fntype && CbC_IS_CODE_SEGMENT(fntype) ) + { + unadjusted_args_size = args_size.constant; + adjusted_args_size.constant = CbC_PRETENDED_STACK_SIZE; + compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + fndecl, fntype, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } + else +#endif + { unadjusted_args_size - = compute_argument_block_size (reg_parm_stack_space, - &adjusted_args_size, - fndecl, fntype, - (pass == 0 ? 0 - : preferred_stack_boundary)); + = compute_argument_block_size (reg_parm_stack_space, + &adjusted_args_size, + fndecl, fntype, + (pass == 0 ? 0 + : preferred_stack_boundary)); + } old_stack_allocated = stack_pointer_delta - pending_stack_adjust; /* The argument block when performing a sibling call is the - incoming argument block. */ + incoming argument block. */ if (pass == 0) - { - argblock = crtl->args.internal_arg_pointer; - argblock + { + argblock = crtl->args.internal_arg_pointer; + argblock #ifdef STACK_GROWS_DOWNWARD - = plus_constant (argblock, crtl->args.pretend_args_size); + = plus_constant (argblock, crtl->args.pretend_args_size); #else - = plus_constant (argblock, -crtl->args.pretend_args_size); + = plus_constant (argblock, -crtl->args.pretend_args_size); #endif - stored_args_map = sbitmap_alloc (args_size.constant); - sbitmap_zero (stored_args_map); - } + stored_args_map = sbitmap_alloc (args_size.constant); + sbitmap_zero (stored_args_map); + } /* If we have no actual push instructions, or shouldn't use them, - make space for all args right now. */ + make space for all args right now. */ else if (adjusted_args_size.var != 0) { if (old_stack_level == 0) @@ -2503,130 +2591,130 @@ current_function_has_unbounded_dynamic_stack_size = 1; } else - { - /* Note that we must go through the motions of allocating an argument - block even if the size is zero because we may be storing args - in the area reserved for register arguments, which may be part of - the stack frame. */ - - int needed = adjusted_args_size.constant; - - /* Store the maximum argument space used. It will be pushed by - the prologue (if ACCUMULATE_OUTGOING_ARGS, or stack overflow - checking). */ - - if (needed > crtl->outgoing_args_size) - crtl->outgoing_args_size = needed; - - if (must_preallocate) - { - if (ACCUMULATE_OUTGOING_ARGS) - { - /* Since the stack pointer will never be pushed, it is - possible for the evaluation of a parm to clobber - something we have already written to the stack. - Since most function calls on RISC machines do not use - the stack, this is uncommon, but must work correctly. - - Therefore, we save any area of the stack that was already - written and that we are using. Here we set up to do this - by making a new stack usage map from the old one. The - actual save will be done by store_one_arg. - - Another approach might be to try to reorder the argument - evaluations to avoid this conflicting stack usage. */ - - /* Since we will be writing into the entire argument area, - the map must be allocated for its entire size, not just - the part that is the responsibility of the caller. */ - if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) - needed += reg_parm_stack_space; + { + /* Note that we must go through the motions of allocating an argument + block even if the size is zero because we may be storing args + in the area reserved for register arguments, which may be part of + the stack frame. */ + + int needed = adjusted_args_size.constant; + + /* Store the maximum argument space used. It will be pushed by + the prologue (if ACCUMULATE_OUTGOING_ARGS, or stack overflow + checking). */ + + if (needed > crtl->outgoing_args_size) + crtl->outgoing_args_size = needed; + + if (must_preallocate) + { + if (ACCUMULATE_OUTGOING_ARGS) + { + /* Since the stack pointer will never be pushed, it is + possible for the evaluation of a parm to clobber + something we have already written to the stack. + Since most function calls on RISC machines do not use + the stack, this is uncommon, but must work correctly. + + Therefore, we save any area of the stack that was already + written and that we are using. Here we set up to do this + by making a new stack usage map from the old one. The + actual save will be done by store_one_arg. + + Another approach might be to try to reorder the argument + evaluations to avoid this conflicting stack usage. */ + + /* Since we will be writing into the entire argument area, + the map must be allocated for its entire size, not just + the part that is the responsibility of the caller. */ + if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) + needed += reg_parm_stack_space; #ifdef ARGS_GROW_DOWNWARD - highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use, - needed + 1); + highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use, + needed + 1); #else - highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use, - needed); + highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use, + needed); #endif - if (stack_usage_map_buf) - free (stack_usage_map_buf); - stack_usage_map_buf = XNEWVEC (char, highest_outgoing_arg_in_use); - stack_usage_map = stack_usage_map_buf; - - if (initial_highest_arg_in_use) - memcpy (stack_usage_map, initial_stack_usage_map, - initial_highest_arg_in_use); - - if (initial_highest_arg_in_use != highest_outgoing_arg_in_use) - memset (&stack_usage_map[initial_highest_arg_in_use], 0, - (highest_outgoing_arg_in_use - - initial_highest_arg_in_use)); - needed = 0; - - /* The address of the outgoing argument list must not be - copied to a register here, because argblock would be left - pointing to the wrong place after the call to - allocate_dynamic_stack_space below. */ - - argblock = virtual_outgoing_args_rtx; - } - else - { - if (inhibit_defer_pop == 0) - { - /* Try to reuse some or all of the pending_stack_adjust - to get this space. */ - needed - = (combine_pending_stack_adjustment_and_call - (unadjusted_args_size, - &adjusted_args_size, - preferred_unit_stack_boundary)); - - /* combine_pending_stack_adjustment_and_call computes - an adjustment before the arguments are allocated. - Account for them and see whether or not the stack - needs to go up or down. */ - needed = unadjusted_args_size - needed; - - if (needed < 0) - { - /* We're releasing stack space. */ - /* ??? We can avoid any adjustment at all if we're - already aligned. FIXME. */ - pending_stack_adjust = -needed; - do_pending_stack_adjust (); - needed = 0; - } - else - /* We need to allocate space. We'll do that in - push_block below. */ - pending_stack_adjust = 0; - } - - /* Special case this because overhead of `push_block' in - this case is non-trivial. */ - if (needed == 0) - argblock = virtual_outgoing_args_rtx; - else - { - argblock = push_block (GEN_INT (needed), 0, 0); + if (stack_usage_map_buf) + free (stack_usage_map_buf); + stack_usage_map_buf = XNEWVEC (char, highest_outgoing_arg_in_use); + stack_usage_map = stack_usage_map_buf; + + if (initial_highest_arg_in_use) + memcpy (stack_usage_map, initial_stack_usage_map, + initial_highest_arg_in_use); + + if (initial_highest_arg_in_use != highest_outgoing_arg_in_use) + memset (&stack_usage_map[initial_highest_arg_in_use], 0, + (highest_outgoing_arg_in_use + - initial_highest_arg_in_use)); + needed = 0; + + /* The address of the outgoing argument list must not be + copied to a register here, because argblock would be left + pointing to the wrong place after the call to + allocate_dynamic_stack_space below. */ + + argblock = virtual_outgoing_args_rtx; + } + else + { + if (inhibit_defer_pop == 0) + { + /* Try to reuse some or all of the pending_stack_adjust + to get this space. */ + needed + = (combine_pending_stack_adjustment_and_call + (unadjusted_args_size, + &adjusted_args_size, + preferred_unit_stack_boundary)); + + /* combine_pending_stack_adjustment_and_call computes + an adjustment before the arguments are allocated. + Account for them and see whether or not the stack + needs to go up or down. */ + needed = unadjusted_args_size - needed; + + if (needed < 0) + { + /* We're releasing stack space. */ + /* ??? We can avoid any adjustment at all if we're + already aligned. FIXME. */ + pending_stack_adjust = -needed; + do_pending_stack_adjust (); + needed = 0; + } + else + /* We need to allocate space. We'll do that in + push_block below. */ + pending_stack_adjust = 0; + } + + /* Special case this because overhead of `push_block' in + this case is non-trivial. */ + if (needed == 0) + argblock = virtual_outgoing_args_rtx; + else + { + argblock = push_block (GEN_INT (needed), 0, 0); #ifdef ARGS_GROW_DOWNWARD - argblock = plus_constant (argblock, needed); + argblock = plus_constant (argblock, needed); #endif - } - - /* We only really need to call `copy_to_reg' in the case - where push insns are going to be used to pass ARGBLOCK - to a function call in ARGS. In that case, the stack - pointer changes value from the allocation point to the - call point, and hence the value of - VIRTUAL_OUTGOING_ARGS_RTX changes as well. But might - as well always do it. */ - argblock = copy_to_reg (argblock); - } - } - } + } + + /* We only really need to call `copy_to_reg' in the case + where push insns are going to be used to pass ARGBLOCK + to a function call in ARGS. In that case, the stack + pointer changes value from the allocation point to the + call point, and hence the value of + VIRTUAL_OUTGOING_ARGS_RTX changes as well. But might + as well always do it. */ + argblock = copy_to_reg (argblock); + } + } + } if (ACCUMULATE_OUTGOING_ARGS) { @@ -2681,28 +2769,28 @@ compute_argument_addresses (args, argblock, num_actuals); /* If we push args individually in reverse order, perform stack alignment - before the first push (the last arg). */ + before the first push (the last arg). */ if (PUSH_ARGS_REVERSED && argblock == 0 - && adjusted_args_size.constant != unadjusted_args_size) - { - /* When the stack adjustment is pending, we get better code - by combining the adjustments. */ - if (pending_stack_adjust - && ! inhibit_defer_pop) - { - pending_stack_adjust - = (combine_pending_stack_adjustment_and_call - (unadjusted_args_size, - &adjusted_args_size, - preferred_unit_stack_boundary)); - do_pending_stack_adjust (); - } - else if (argblock == 0) - anti_adjust_stack (GEN_INT (adjusted_args_size.constant - - unadjusted_args_size)); - } + && adjusted_args_size.constant != unadjusted_args_size) + { + /* When the stack adjustment is pending, we get better code + by combining the adjustments. */ + if (pending_stack_adjust + && ! inhibit_defer_pop) + { + pending_stack_adjust + = (combine_pending_stack_adjustment_and_call + (unadjusted_args_size, + &adjusted_args_size, + preferred_unit_stack_boundary)); + do_pending_stack_adjust (); + } + else if (argblock == 0) + anti_adjust_stack (GEN_INT (adjusted_args_size.constant + - unadjusted_args_size)); + } /* Now that the stack is properly aligned, pops can't safely - be deferred during the evaluation of the arguments. */ + be deferred during the evaluation of the arguments. */ NO_DEFER_POP; /* Record the maximum pushed stack space size. We need to delay @@ -2723,138 +2811,138 @@ /* Figure out the register where the value, if any, will come back. */ valreg = 0; if (TYPE_MODE (rettype) != VOIDmode - && ! structure_value_addr) - { - if (pcc_struct_value) - valreg = hard_function_value (build_pointer_type (rettype), - fndecl, NULL, (pass == 0)); - else - valreg = hard_function_value (rettype, fndecl, fntype, - (pass == 0)); - - /* If VALREG is a PARALLEL whose first member has a zero - offset, use that. This is for targets such as m68k that - return the same value in multiple places. */ - if (GET_CODE (valreg) == PARALLEL) - { - rtx elem = XVECEXP (valreg, 0, 0); - rtx where = XEXP (elem, 0); - rtx offset = XEXP (elem, 1); - if (offset == const0_rtx - && GET_MODE (where) == GET_MODE (valreg)) - valreg = where; - } - } + && ! structure_value_addr) + { + if (pcc_struct_value) + valreg = hard_function_value (build_pointer_type (rettype), + fndecl, NULL, (pass == 0)); + else + valreg = hard_function_value (rettype, fndecl, fntype, + (pass == 0)); + + /* If VALREG is a PARALLEL whose first member has a zero + offset, use that. This is for targets such as m68k that + return the same value in multiple places. */ + if (GET_CODE (valreg) == PARALLEL) + { + rtx elem = XVECEXP (valreg, 0, 0); + rtx where = XEXP (elem, 0); + rtx offset = XEXP (elem, 1); + if (offset == const0_rtx + && GET_MODE (where) == GET_MODE (valreg)) + valreg = where; + } + } /* Precompute all register parameters. It isn't safe to compute anything - once we have started filling any specific hard regs. */ + once we have started filling any specific hard regs. */ precompute_register_parameters (num_actuals, args, ®_parm_seen); if (CALL_EXPR_STATIC_CHAIN (exp)) - static_chain_value = expand_normal (CALL_EXPR_STATIC_CHAIN (exp)); + static_chain_value = expand_normal (CALL_EXPR_STATIC_CHAIN (exp)); else - static_chain_value = 0; + static_chain_value = 0; #ifdef REG_PARM_STACK_SPACE /* Save the fixed argument area if it's part of the caller's frame and - is clobbered by argument setup for this call. */ + is clobbered by argument setup for this call. */ if (ACCUMULATE_OUTGOING_ARGS && pass) - save_area = save_fixed_argument_area (reg_parm_stack_space, argblock, - &low_to_save, &high_to_save); + save_area = save_fixed_argument_area (reg_parm_stack_space, argblock, + &low_to_save, &high_to_save); #endif /* Now store (and compute if necessary) all non-register parms. - These come before register parms, since they can require block-moves, - which could clobber the registers used for register parms. - Parms which have partial registers are not stored here, - but we do preallocate space here if they want that. */ + These come before register parms, since they can require block-moves, + which could clobber the registers used for register parms. + Parms which have partial registers are not stored here, + but we do preallocate space here if they want that. */ for (i = 0; i < num_actuals; i++) - { - if (args[i].reg == 0 || args[i].pass_on_stack) - { - rtx before_arg = get_last_insn (); - - if (store_one_arg (&args[i], argblock, flags, - adjusted_args_size.var != 0, - reg_parm_stack_space) - || (pass == 0 - && check_sibcall_argument_overlap (before_arg, - &args[i], 1))) - sibcall_failure = 1; - } - - if (((flags & ECF_CONST) - || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS)) - && args[i].stack) - call_fusage = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_USE (VOIDmode, - args[i].stack), - call_fusage); - } + { + if (args[i].reg == 0 || args[i].pass_on_stack) + { + rtx before_arg = get_last_insn (); + + if (store_one_arg (&args[i], argblock, flags, + adjusted_args_size.var != 0, + reg_parm_stack_space) + || (pass == 0 + && check_sibcall_argument_overlap (before_arg, + &args[i], 1))) + sibcall_failure = 1; + } + + if (((flags & ECF_CONST) + || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS)) + && args[i].stack) + call_fusage = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_USE (VOIDmode, + args[i].stack), + call_fusage); + } /* If we have a parm that is passed in registers but not in memory - and whose alignment does not permit a direct copy into registers, - make a group of pseudos that correspond to each register that we - will later fill. */ + and whose alignment does not permit a direct copy into registers, + make a group of pseudos that correspond to each register that we + will later fill. */ if (STRICT_ALIGNMENT) - store_unaligned_arguments_into_pseudos (args, num_actuals); + store_unaligned_arguments_into_pseudos (args, num_actuals); /* Now store any partially-in-registers parm. - This is the last place a block-move can happen. */ + This is the last place a block-move can happen. */ if (reg_parm_seen) - for (i = 0; i < num_actuals; i++) - if (args[i].partial != 0 && ! args[i].pass_on_stack) - { - rtx before_arg = get_last_insn (); - - if (store_one_arg (&args[i], argblock, flags, - adjusted_args_size.var != 0, - reg_parm_stack_space) - || (pass == 0 - && check_sibcall_argument_overlap (before_arg, - &args[i], 1))) - sibcall_failure = 1; - } + for (i = 0; i < num_actuals; i++) + if (args[i].partial != 0 && ! args[i].pass_on_stack) + { + rtx before_arg = get_last_insn (); + + if (store_one_arg (&args[i], argblock, flags, + adjusted_args_size.var != 0, + reg_parm_stack_space) + || (pass == 0 + && check_sibcall_argument_overlap (before_arg, + &args[i], 1))) + sibcall_failure = 1; + } /* If we pushed args in forward order, perform stack alignment - after pushing the last arg. */ + after pushing the last arg. */ if (!PUSH_ARGS_REVERSED && argblock == 0) - anti_adjust_stack (GEN_INT (adjusted_args_size.constant - - unadjusted_args_size)); + anti_adjust_stack (GEN_INT (adjusted_args_size.constant + - unadjusted_args_size)); /* If register arguments require space on the stack and stack space - was not preallocated, allocate stack space here for arguments - passed in registers. */ + was not preallocated, allocate stack space here for arguments + passed in registers. */ if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))) && !ACCUMULATE_OUTGOING_ARGS - && must_preallocate == 0 && reg_parm_stack_space > 0) - anti_adjust_stack (GEN_INT (reg_parm_stack_space)); + && must_preallocate == 0 && reg_parm_stack_space > 0) + anti_adjust_stack (GEN_INT (reg_parm_stack_space)); /* Pass the function the address in which to return a - structure value. */ + structure value. */ if (pass != 0 && structure_value_addr && ! structure_value_addr_parm) - { - structure_value_addr - = convert_memory_address (Pmode, structure_value_addr); - emit_move_insn (struct_value, - force_reg (Pmode, - force_operand (structure_value_addr, - NULL_RTX))); - - if (REG_P (struct_value)) - use_reg (&call_fusage, struct_value); - } + { + structure_value_addr + = convert_memory_address (Pmode, structure_value_addr); + emit_move_insn (struct_value, + force_reg (Pmode, + force_operand (structure_value_addr, + NULL_RTX))); + + if (REG_P (struct_value)) + use_reg (&call_fusage, struct_value); + } after_args = get_last_insn (); funexp = prepare_call_address (fndecl, funexp, static_chain_value, - &call_fusage, reg_parm_seen, pass == 0); + &call_fusage, reg_parm_seen, pass == 0); load_register_parameters (args, num_actuals, &call_fusage, flags, - pass == 0, &sibcall_failure); + pass == 0, &sibcall_failure); /* Save a pointer to the last insn before the call, so that we can - later safely search backwards to find the CALL_INSN. */ + later safely search backwards to find the CALL_INSN. */ before_call = get_last_insn (); /* Set up next argument register. For sibling calls on machines @@ -2870,233 +2958,233 @@ true); /* All arguments and registers used for the call must be set up by - now! */ + now! */ /* Stack must be properly aligned now. */ gcc_assert (!pass - || !(stack_pointer_delta % preferred_unit_stack_boundary)); + || !(stack_pointer_delta % preferred_unit_stack_boundary)); /* Generate the actual call instruction. */ emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size, - adjusted_args_size.constant, struct_value_size, - next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, - flags, & args_so_far); + adjusted_args_size.constant, struct_value_size, + next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, + flags, & args_so_far); /* If the call setup or the call itself overlaps with anything - of the argument setup we probably clobbered our call address. - In that case we can't do sibcalls. */ + of the argument setup we probably clobbered our call address. + In that case we can't do sibcalls. */ if (pass == 0 - && check_sibcall_argument_overlap (after_args, 0, 0)) - sibcall_failure = 1; + && check_sibcall_argument_overlap (after_args, 0, 0)) + sibcall_failure = 1; /* If a non-BLKmode value is returned at the most significant end - of a register, shift the register right by the appropriate amount - and update VALREG accordingly. BLKmode values are handled by the - group load/store machinery below. */ + of a register, shift the register right by the appropriate amount + and update VALREG accordingly. BLKmode values are handled by the + group load/store machinery below. */ if (!structure_value_addr - && !pcc_struct_value - && TYPE_MODE (rettype) != BLKmode - && targetm.calls.return_in_msb (rettype)) - { - if (shift_return_value (TYPE_MODE (rettype), false, valreg)) - sibcall_failure = 1; - valreg = gen_rtx_REG (TYPE_MODE (rettype), REGNO (valreg)); - } + && !pcc_struct_value + && TYPE_MODE (rettype) != BLKmode + && targetm.calls.return_in_msb (rettype)) + { + if (shift_return_value (TYPE_MODE (rettype), false, valreg)) + sibcall_failure = 1; + valreg = gen_rtx_REG (TYPE_MODE (rettype), REGNO (valreg)); + } if (pass && (flags & ECF_MALLOC)) - { - rtx temp = gen_reg_rtx (GET_MODE (valreg)); - rtx last, insns; - - /* The return value from a malloc-like function is a pointer. */ - if (TREE_CODE (rettype) == POINTER_TYPE) - mark_reg_pointer (temp, BIGGEST_ALIGNMENT); - - emit_move_insn (temp, valreg); - - /* The return value from a malloc-like function can not alias - anything else. */ - last = get_last_insn (); - add_reg_note (last, REG_NOALIAS, temp); - - /* Write out the sequence. */ - insns = get_insns (); - end_sequence (); - emit_insn (insns); - valreg = temp; - } + { + rtx temp = gen_reg_rtx (GET_MODE (valreg)); + rtx last, insns; + + /* The return value from a malloc-like function is a pointer. */ + if (TREE_CODE (rettype) == POINTER_TYPE) + mark_reg_pointer (temp, BIGGEST_ALIGNMENT); + + emit_move_insn (temp, valreg); + + /* The return value from a malloc-like function can not alias + anything else. */ + last = get_last_insn (); + add_reg_note (last, REG_NOALIAS, temp); + + /* Write out the sequence. */ + insns = get_insns (); + end_sequence (); + emit_insn (insns); + valreg = temp; + } /* For calls to `setjmp', etc., inform - function.c:setjmp_warnings that it should complain if - nonvolatile values are live. For functions that cannot - return, inform flow that control does not fall through. */ + function.c:setjmp_warnings that it should complain if + nonvolatile values are live. For functions that cannot + return, inform flow that control does not fall through. */ if ((flags & ECF_NORETURN) || pass == 0) - { - /* The barrier must be emitted - immediately after the CALL_INSN. Some ports emit more - than just a CALL_INSN above, so we must search for it here. */ - - rtx last = get_last_insn (); - while (!CALL_P (last)) - { - last = PREV_INSN (last); - /* There was no CALL_INSN? */ - gcc_assert (last != before_call); - } - - emit_barrier_after (last); - - /* Stack adjustments after a noreturn call are dead code. - However when NO_DEFER_POP is in effect, we must preserve - stack_pointer_delta. */ - if (inhibit_defer_pop == 0) - { - stack_pointer_delta = old_stack_allocated; - pending_stack_adjust = 0; - } - } + { + /* The barrier must be emitted + immediately after the CALL_INSN. Some ports emit more + than just a CALL_INSN above, so we must search for it here. */ + + rtx last = get_last_insn (); + while (!CALL_P (last)) + { + last = PREV_INSN (last); + /* There was no CALL_INSN? */ + gcc_assert (last != before_call); + } + + emit_barrier_after (last); + + /* Stack adjustments after a noreturn call are dead code. + However when NO_DEFER_POP is in effect, we must preserve + stack_pointer_delta. */ + if (inhibit_defer_pop == 0) + { + stack_pointer_delta = old_stack_allocated; + pending_stack_adjust = 0; + } + } /* If value type not void, return an rtx for the value. */ if (TYPE_MODE (rettype) == VOIDmode - || ignore) - target = const0_rtx; + || ignore) + target = const0_rtx; else if (structure_value_addr) - { - if (target == 0 || !MEM_P (target)) - { - target - = gen_rtx_MEM (TYPE_MODE (rettype), - memory_address (TYPE_MODE (rettype), - structure_value_addr)); - set_mem_attributes (target, rettype, 1); - } - } + { + if (target == 0 || !MEM_P (target)) + { + target + = gen_rtx_MEM (TYPE_MODE (rettype), + memory_address (TYPE_MODE (rettype), + structure_value_addr)); + set_mem_attributes (target, rettype, 1); + } + } else if (pcc_struct_value) - { - /* This is the special C++ case where we need to - know what the true target was. We take care to - never use this value more than once in one expression. */ - target = gen_rtx_MEM (TYPE_MODE (rettype), - copy_to_reg (valreg)); - set_mem_attributes (target, rettype, 1); - } + { + /* This is the special C++ case where we need to + know what the true target was. We take care to + never use this value more than once in one expression. */ + target = gen_rtx_MEM (TYPE_MODE (rettype), + copy_to_reg (valreg)); + set_mem_attributes (target, rettype, 1); + } /* Handle calls that return values in multiple non-contiguous locations. - The Irix 6 ABI has examples of this. */ + The Irix 6 ABI has examples of this. */ else if (GET_CODE (valreg) == PARALLEL) - { - if (target == 0) - { - /* This will only be assigned once, so it can be readonly. */ - tree nt = build_qualified_type (rettype, - (TYPE_QUALS (rettype) - | TYPE_QUAL_CONST)); - - target = assign_temp (nt, 0, 1, 1); - } - - if (! rtx_equal_p (target, valreg)) - emit_group_store (target, valreg, rettype, - int_size_in_bytes (rettype)); - - /* We can not support sibling calls for this case. */ - sibcall_failure = 1; - } + { + if (target == 0) + { + /* This will only be assigned once, so it can be readonly. */ + tree nt = build_qualified_type (rettype, + (TYPE_QUALS (rettype) + | TYPE_QUAL_CONST)); + + target = assign_temp (nt, 0, 1, 1); + } + + if (! rtx_equal_p (target, valreg)) + emit_group_store (target, valreg, rettype, + int_size_in_bytes (rettype)); + + /* We can not support sibling calls for this case. */ + sibcall_failure = 1; + } else if (target - && GET_MODE (target) == TYPE_MODE (rettype) - && GET_MODE (target) == GET_MODE (valreg)) - { - bool may_overlap = false; - - /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard - reg to a plain register. */ - if (!REG_P (target) || HARD_REGISTER_P (target)) - valreg = avoid_likely_spilled_reg (valreg); - - /* If TARGET is a MEM in the argument area, and we have - saved part of the argument area, then we can't store - directly into TARGET as it may get overwritten when we - restore the argument save area below. Don't work too - hard though and simply force TARGET to a register if it - is a MEM; the optimizer is quite likely to sort it out. */ - if (ACCUMULATE_OUTGOING_ARGS && pass && MEM_P (target)) - for (i = 0; i < num_actuals; i++) - if (args[i].save_area) - { - may_overlap = true; - break; - } - - if (may_overlap) - target = copy_to_reg (valreg); - else - { - /* TARGET and VALREG cannot be equal at this point - because the latter would not have - REG_FUNCTION_VALUE_P true, while the former would if - it were referring to the same register. - - If they refer to the same register, this move will be - a no-op, except when function inlining is being - done. */ - emit_move_insn (target, valreg); - - /* If we are setting a MEM, this code must be executed. - Since it is emitted after the call insn, sibcall - optimization cannot be performed in that case. */ - if (MEM_P (target)) - sibcall_failure = 1; - } - } + && GET_MODE (target) == TYPE_MODE (rettype) + && GET_MODE (target) == GET_MODE (valreg)) + { + bool may_overlap = false; + + /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard + reg to a plain register. */ + if (!REG_P (target) || HARD_REGISTER_P (target)) + valreg = avoid_likely_spilled_reg (valreg); + + /* If TARGET is a MEM in the argument area, and we have + saved part of the argument area, then we can't store + directly into TARGET as it may get overwritten when we + restore the argument save area below. Don't work too + hard though and simply force TARGET to a register if it + is a MEM; the optimizer is quite likely to sort it out. */ + if (ACCUMULATE_OUTGOING_ARGS && pass && MEM_P (target)) + for (i = 0; i < num_actuals; i++) + if (args[i].save_area) + { + may_overlap = true; + break; + } + + if (may_overlap) + target = copy_to_reg (valreg); + else + { + /* TARGET and VALREG cannot be equal at this point + because the latter would not have + REG_FUNCTION_VALUE_P true, while the former would if + it were referring to the same register. + + If they refer to the same register, this move will be + a no-op, except when function inlining is being + done. */ + emit_move_insn (target, valreg); + + /* If we are setting a MEM, this code must be executed. + Since it is emitted after the call insn, sibcall + optimization cannot be performed in that case. */ + if (MEM_P (target)) + sibcall_failure = 1; + } + } else if (TYPE_MODE (rettype) == BLKmode) - { - rtx val = valreg; - if (GET_MODE (val) != BLKmode) - val = avoid_likely_spilled_reg (val); - target = copy_blkmode_from_reg (target, val, rettype); - - /* We can not support sibling calls for this case. */ - sibcall_failure = 1; - } + { + rtx val = valreg; + if (GET_MODE (val) != BLKmode) + val = avoid_likely_spilled_reg (val); + target = copy_blkmode_from_reg (target, val, rettype); + + /* We can not support sibling calls for this case. */ + sibcall_failure = 1; + } else - target = copy_to_reg (avoid_likely_spilled_reg (valreg)); + target = copy_to_reg (avoid_likely_spilled_reg (valreg)); /* If we promoted this return value, make the proper SUBREG. TARGET might be const0_rtx here, so be careful. */ if (REG_P (target) - && TYPE_MODE (rettype) != BLKmode - && GET_MODE (target) != TYPE_MODE (rettype)) - { - tree type = rettype; - int unsignedp = TYPE_UNSIGNED (type); - int offset = 0; - enum machine_mode pmode; - - /* Ensure we promote as expected, and get the new unsignedness. */ - pmode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, - funtype, 1); - gcc_assert (GET_MODE (target) == pmode); - - if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) - && (GET_MODE_SIZE (GET_MODE (target)) - > GET_MODE_SIZE (TYPE_MODE (type)))) - { - offset = GET_MODE_SIZE (GET_MODE (target)) - - GET_MODE_SIZE (TYPE_MODE (type)); - if (! BYTES_BIG_ENDIAN) - offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD; - else if (! WORDS_BIG_ENDIAN) - offset %= UNITS_PER_WORD; - } - - target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset); - SUBREG_PROMOTED_VAR_P (target) = 1; - SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp); - } + && TYPE_MODE (rettype) != BLKmode + && GET_MODE (target) != TYPE_MODE (rettype)) + { + tree type = rettype; + int unsignedp = TYPE_UNSIGNED (type); + int offset = 0; + enum machine_mode pmode; + + /* Ensure we promote as expected, and get the new unsignedness. */ + pmode = promote_function_mode (type, TYPE_MODE (type), &unsignedp, + funtype, 1); + gcc_assert (GET_MODE (target) == pmode); + + if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) + && (GET_MODE_SIZE (GET_MODE (target)) + > GET_MODE_SIZE (TYPE_MODE (type)))) + { + offset = GET_MODE_SIZE (GET_MODE (target)) + - GET_MODE_SIZE (TYPE_MODE (type)); + if (! BYTES_BIG_ENDIAN) + offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD; + else if (! WORDS_BIG_ENDIAN) + offset %= UNITS_PER_WORD; + } + + target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset); + SUBREG_PROMOTED_VAR_P (target) = 1; + SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp); + } /* If size of args is variable or this was a constructor call for a stack - argument, restore saved stack-pointer value. */ + argument, restore saved stack-pointer value. */ if (old_stack_level) { @@ -3110,86 +3198,86 @@ sibcall_failure = 1; } else if (ACCUMULATE_OUTGOING_ARGS && pass) - { + { #ifdef REG_PARM_STACK_SPACE - if (save_area) - restore_fixed_argument_area (save_area, argblock, - high_to_save, low_to_save); + if (save_area) + restore_fixed_argument_area (save_area, argblock, + high_to_save, low_to_save); #endif - /* If we saved any argument areas, restore them. */ - for (i = 0; i < num_actuals; i++) - if (args[i].save_area) - { - enum machine_mode save_mode = GET_MODE (args[i].save_area); - rtx stack_area - = gen_rtx_MEM (save_mode, - memory_address (save_mode, - XEXP (args[i].stack_slot, 0))); - - if (save_mode != BLKmode) - emit_move_insn (stack_area, args[i].save_area); - else - emit_block_move (stack_area, args[i].save_area, - GEN_INT (args[i].locate.size.constant), - BLOCK_OP_CALL_PARM); - } - - highest_outgoing_arg_in_use = initial_highest_arg_in_use; - stack_usage_map = initial_stack_usage_map; - } + /* If we saved any argument areas, restore them. */ + for (i = 0; i < num_actuals; i++) + if (args[i].save_area) + { + enum machine_mode save_mode = GET_MODE (args[i].save_area); + rtx stack_area + = gen_rtx_MEM (save_mode, + memory_address (save_mode, + XEXP (args[i].stack_slot, 0))); + + if (save_mode != BLKmode) + emit_move_insn (stack_area, args[i].save_area); + else + emit_block_move (stack_area, args[i].save_area, + GEN_INT (args[i].locate.size.constant), + BLOCK_OP_CALL_PARM); + } + + highest_outgoing_arg_in_use = initial_highest_arg_in_use; + stack_usage_map = initial_stack_usage_map; + } /* If this was alloca, record the new stack level for nonlocal gotos. - Check for the handler slots since we might not have a save area - for non-local gotos. */ + Check for the handler slots since we might not have a save area + for non-local gotos. */ if ((flags & ECF_MAY_BE_ALLOCA) && cfun->nonlocal_goto_save_area != 0) - update_nonlocal_goto_save_area (); + update_nonlocal_goto_save_area (); /* Free up storage we no longer need. */ for (i = 0; i < num_actuals; ++i) - if (args[i].aligned_regs) - free (args[i].aligned_regs); + if (args[i].aligned_regs) + free (args[i].aligned_regs); insns = get_insns (); end_sequence (); if (pass == 0) - { - tail_call_insns = insns; - - /* Restore the pending stack adjustment now that we have - finished generating the sibling call sequence. */ - - pending_stack_adjust = save_pending_stack_adjust; - stack_pointer_delta = save_stack_pointer_delta; - - /* Prepare arg structure for next iteration. */ - for (i = 0; i < num_actuals; i++) - { - args[i].value = 0; - args[i].aligned_regs = 0; - args[i].stack = 0; - } - - sbitmap_free (stored_args_map); - } + { + tail_call_insns = insns; + + /* Restore the pending stack adjustment now that we have + finished generating the sibling call sequence. */ + + pending_stack_adjust = save_pending_stack_adjust; + stack_pointer_delta = save_stack_pointer_delta; + + /* Prepare arg structure for next iteration. */ + for (i = 0; i < num_actuals; i++) + { + args[i].value = 0; + args[i].aligned_regs = 0; + args[i].stack = 0; + } + + sbitmap_free (stored_args_map); + } else - { - normal_call_insns = insns; - - /* Verify that we've deallocated all the stack we used. */ - gcc_assert ((flags & ECF_NORETURN) - || (old_stack_allocated - == stack_pointer_delta - pending_stack_adjust)); - } + { + normal_call_insns = insns; + + /* Verify that we've deallocated all the stack we used. */ + gcc_assert ((flags & ECF_NORETURN) + || (old_stack_allocated + == stack_pointer_delta - pending_stack_adjust)); + } /* If something prevents making this a sibling call, - zero out the sequence. */ + zero out the sequence. */ if (sibcall_failure) - tail_call_insns = NULL_RTX; + tail_call_insns = NULL_RTX; else - break; + break; } /* If tail call production succeeded, we need to remove REG_EQUIV notes on @@ -3232,14 +3320,14 @@ rtx note; /* There are never REG_EQUIV notes for the incoming arguments - after the NOTE_INSN_FUNCTION_BEG note, so stop if we see it. */ + after the NOTE_INSN_FUNCTION_BEG note, so stop if we see it. */ if (NOTE_P (insn) - && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) - break; + && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) + break; note = find_reg_note (insn, REG_EQUIV, 0); if (note) - remove_note (insn, note); + remove_note (insn, note); note = find_reg_note (insn, REG_EQUIV, 0); gcc_assert (!note); } @@ -3257,8 +3345,8 @@ { tree type = TREE_VALUE (p); if (TREE_CODE (type) == COMPLEX_TYPE - && targetm.calls.split_complex_arg (type)) - goto found; + && targetm.calls.split_complex_arg (type)) + goto found; } return types; @@ -3270,22 +3358,22 @@ tree complex_type = TREE_VALUE (p); if (TREE_CODE (complex_type) == COMPLEX_TYPE - && targetm.calls.split_complex_arg (complex_type)) - { - tree next, imag; - - /* Rewrite complex type with component type. */ - TREE_VALUE (p) = TREE_TYPE (complex_type); - next = TREE_CHAIN (p); - - /* Add another component type for the imaginary part. */ - imag = build_tree_list (NULL_TREE, TREE_VALUE (p)); - TREE_CHAIN (p) = imag; - TREE_CHAIN (imag) = next; - - /* Skip the newly created node. */ - p = TREE_CHAIN (p); - } + && targetm.calls.split_complex_arg (complex_type)) + { + tree next, imag; + + /* Rewrite complex type with component type. */ + TREE_VALUE (p) = TREE_TYPE (complex_type); + next = TREE_CHAIN (p); + + /* Add another component type for the imaginary part. */ + imag = build_tree_list (NULL_TREE, TREE_VALUE (p)); + TREE_CHAIN (p) = imag; + TREE_CHAIN (imag) = next; + + /* Skip the newly created node. */ + p = TREE_CHAIN (p); + } } return types; @@ -3297,8 +3385,8 @@ static rtx emit_library_call_value_1 (int retval, rtx orgfun, rtx value, - enum libcall_type fn_type, - enum machine_mode outmode, int nargs, va_list p) + enum libcall_type fn_type, + enum machine_mode outmode, int nargs, va_list p) { /* Total size in bytes of all the stack-parms scanned so far. */ struct args_size args_size; @@ -3334,7 +3422,7 @@ int reg_parm_stack_space = 0; int needed; rtx before_call; - tree tfom; /* type_for_mode (outmode, 0) */ + tree tfom; /* type_for_mode (outmode, 0) */ #ifdef REG_PARM_STACK_SPACE /* Define the boundary of the register parm stack space that needs to be @@ -3390,24 +3478,24 @@ { tfom = lang_hooks.types.type_for_mode (outmode, 0); if (aggregate_value_p (tfom, 0)) - { + { #ifdef PCC_STATIC_STRUCT_RETURN - rtx pointer_reg - = hard_function_value (build_pointer_type (tfom), 0, 0, 0); - mem_value = gen_rtx_MEM (outmode, pointer_reg); - pcc_struct_value = 1; - if (value == 0) - value = gen_reg_rtx (outmode); + rtx pointer_reg + = hard_function_value (build_pointer_type (tfom), 0, 0, 0); + mem_value = gen_rtx_MEM (outmode, pointer_reg); + pcc_struct_value = 1; + if (value == 0) + value = gen_reg_rtx (outmode); #else /* not PCC_STATIC_STRUCT_RETURN */ - struct_value_size = GET_MODE_SIZE (outmode); - if (value != 0 && MEM_P (value)) - mem_value = value; - else - mem_value = assign_temp (tfom, 0, 1, 1); + struct_value_size = GET_MODE_SIZE (outmode); + if (value != 0 && MEM_P (value)) + mem_value = value; + else + mem_value = assign_temp (tfom, 0, 1, 1); #endif - /* This call returns a big structure. */ - flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE); - } + /* This call returns a big structure. */ + flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE); + } } else tfom = void_type_node; @@ -3447,8 +3535,8 @@ /* Make sure it is a reasonable operand for a move or push insn. */ if (!REG_P (addr) && !MEM_P (addr) - && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr))) - addr = force_operand (addr, NULL_RTX); + && ! (CONSTANT_P (addr) && LEGITIMATE_CONSTANT_P (addr))) + addr = force_operand (addr, NULL_RTX); argvec[count].value = addr; argvec[count].mode = Pmode; @@ -3457,19 +3545,19 @@ argvec[count].reg = targetm.calls.function_arg (&args_so_far, Pmode, NULL_TREE, true); gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode, - NULL_TREE, 1) == 0); + NULL_TREE, 1) == 0); locate_and_pad_parm (Pmode, NULL_TREE, #ifdef STACK_PARMS_IN_REG_PARM_AREA - 1, + 1, #else - argvec[count].reg != 0, + argvec[count].reg != 0, #endif - 0, NULL_TREE, &args_size, &argvec[count].locate); + 0, NULL_TREE, &args_size, &argvec[count].locate); if (argvec[count].reg == 0 || argvec[count].partial != 0 - || reg_parm_stack_space > 0) - args_size.constant += argvec[count].locate.size.constant; + || reg_parm_stack_space > 0) + args_size.constant += argvec[count].locate.size.constant; targetm.calls.function_arg_advance (&args_so_far, Pmode, (tree) 0, true); @@ -3482,50 +3570,50 @@ enum machine_mode mode = (enum machine_mode) va_arg (p, int); /* We cannot convert the arg value to the mode the library wants here; - must do it earlier where we know the signedness of the arg. */ + must do it earlier where we know the signedness of the arg. */ gcc_assert (mode != BLKmode - && (GET_MODE (val) == mode || GET_MODE (val) == VOIDmode)); + && (GET_MODE (val) == mode || GET_MODE (val) == VOIDmode)); /* Make sure it is a reasonable operand for a move or push insn. */ if (!REG_P (val) && !MEM_P (val) - && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val))) - val = force_operand (val, NULL_RTX); + && ! (CONSTANT_P (val) && LEGITIMATE_CONSTANT_P (val))) + val = force_operand (val, NULL_RTX); if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1)) - { - rtx slot; - int must_copy - = !reference_callee_copied (&args_so_far, mode, NULL_TREE, 1); - - /* If this was a CONST function, it is now PURE since it now - reads memory. */ - if (flags & ECF_CONST) - { - flags &= ~ECF_CONST; - flags |= ECF_PURE; - } - - if (MEM_P (val) && !must_copy) - slot = val; - else - { - slot = assign_temp (lang_hooks.types.type_for_mode (mode, 0), - 0, 1, 1); - emit_move_insn (slot, val); - } - - call_fusage = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_USE (VOIDmode, slot), - call_fusage); - if (must_copy) - call_fusage = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_CLOBBER (VOIDmode, - slot), - call_fusage); - - mode = Pmode; - val = force_operand (XEXP (slot, 0), NULL_RTX); - } + { + rtx slot; + int must_copy + = !reference_callee_copied (&args_so_far, mode, NULL_TREE, 1); + + /* If this was a CONST function, it is now PURE since it now + reads memory. */ + if (flags & ECF_CONST) + { + flags &= ~ECF_CONST; + flags |= ECF_PURE; + } + + if (MEM_P (val) && !must_copy) + slot = val; + else + { + slot = assign_temp (lang_hooks.types.type_for_mode (mode, 0), + 0, 1, 1); + emit_move_insn (slot, val); + } + + call_fusage = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_USE (VOIDmode, slot), + call_fusage); + if (must_copy) + call_fusage = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_CLOBBER (VOIDmode, + slot), + call_fusage); + + mode = Pmode; + val = force_operand (XEXP (slot, 0), NULL_RTX); + } argvec[count].value = val; argvec[count].mode = mode; @@ -3534,22 +3622,22 @@ NULL_TREE, true); argvec[count].partial - = targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1); + = targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1); locate_and_pad_parm (mode, NULL_TREE, #ifdef STACK_PARMS_IN_REG_PARM_AREA - 1, + 1, #else - argvec[count].reg != 0, + argvec[count].reg != 0, #endif - argvec[count].partial, - NULL_TREE, &args_size, &argvec[count].locate); + argvec[count].partial, + NULL_TREE, &args_size, &argvec[count].locate); gcc_assert (!argvec[count].locate.size.var); if (argvec[count].reg == 0 || argvec[count].partial != 0 - || reg_parm_stack_space > 0) - args_size.constant += argvec[count].locate.size.constant; + || reg_parm_stack_space > 0) + args_size.constant += argvec[count].locate.size.constant; targetm.calls.function_arg_advance (&args_so_far, mode, (tree) 0, true); } @@ -3560,14 +3648,14 @@ original_args_size = args_size; args_size.constant = (((args_size.constant - + stack_pointer_delta - + STACK_BYTES - 1) - / STACK_BYTES - * STACK_BYTES) - - stack_pointer_delta); + + stack_pointer_delta + + STACK_BYTES - 1) + / STACK_BYTES + * STACK_BYTES) + - stack_pointer_delta); args_size.constant = MAX (args_size.constant, - reg_parm_stack_space); + reg_parm_stack_space); if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) args_size.constant -= reg_parm_stack_space; @@ -3585,65 +3673,65 @@ if (ACCUMULATE_OUTGOING_ARGS) { /* Since the stack pointer will never be pushed, it is possible for - the evaluation of a parm to clobber something we have already - written to the stack. Since most function calls on RISC machines - do not use the stack, this is uncommon, but must work correctly. - - Therefore, we save any area of the stack that was already written - and that we are using. Here we set up to do this by making a new - stack usage map from the old one. - - Another approach might be to try to reorder the argument - evaluations to avoid this conflicting stack usage. */ + the evaluation of a parm to clobber something we have already + written to the stack. Since most function calls on RISC machines + do not use the stack, this is uncommon, but must work correctly. + + Therefore, we save any area of the stack that was already written + and that we are using. Here we set up to do this by making a new + stack usage map from the old one. + + Another approach might be to try to reorder the argument + evaluations to avoid this conflicting stack usage. */ needed = args_size.constant; /* Since we will be writing into the entire argument area, the - map must be allocated for its entire size, not just the part that - is the responsibility of the caller. */ + map must be allocated for its entire size, not just the part that + is the responsibility of the caller. */ if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))) - needed += reg_parm_stack_space; + needed += reg_parm_stack_space; #ifdef ARGS_GROW_DOWNWARD highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use, - needed + 1); + needed + 1); #else highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use, - needed); + needed); #endif stack_usage_map_buf = XNEWVEC (char, highest_outgoing_arg_in_use); stack_usage_map = stack_usage_map_buf; if (initial_highest_arg_in_use) - memcpy (stack_usage_map, initial_stack_usage_map, - initial_highest_arg_in_use); + memcpy (stack_usage_map, initial_stack_usage_map, + initial_highest_arg_in_use); if (initial_highest_arg_in_use != highest_outgoing_arg_in_use) - memset (&stack_usage_map[initial_highest_arg_in_use], 0, - highest_outgoing_arg_in_use - initial_highest_arg_in_use); + memset (&stack_usage_map[initial_highest_arg_in_use], 0, + highest_outgoing_arg_in_use - initial_highest_arg_in_use); needed = 0; /* We must be careful to use virtual regs before they're instantiated, - and real regs afterwards. Loop optimization, for example, can create - new libcalls after we've instantiated the virtual regs, and if we - use virtuals anyway, they won't match the rtl patterns. */ + and real regs afterwards. Loop optimization, for example, can create + new libcalls after we've instantiated the virtual regs, and if we + use virtuals anyway, they won't match the rtl patterns. */ if (virtuals_instantiated) - argblock = plus_constant (stack_pointer_rtx, STACK_POINTER_OFFSET); + argblock = plus_constant (stack_pointer_rtx, STACK_POINTER_OFFSET); else - argblock = virtual_outgoing_args_rtx; + argblock = virtual_outgoing_args_rtx; } else { if (!PUSH_ARGS) - argblock = push_block (GEN_INT (args_size.constant), 0, 0); + argblock = push_block (GEN_INT (args_size.constant), 0, 0); } /* If we push args individually in reverse order, perform stack alignment before the first push (the last arg). */ if (argblock == 0 && PUSH_ARGS_REVERSED) anti_adjust_stack (GEN_INT (args_size.constant - - original_args_size.constant)); + - original_args_size.constant)); if (PUSH_ARGS_REVERSED) { @@ -3660,10 +3748,10 @@ if (ACCUMULATE_OUTGOING_ARGS) { /* The argument list is the property of the called routine and it - may clobber it. If the fixed area has been used for previous - parameters, we must save and restore it. */ + may clobber it. If the fixed area has been used for previous + parameters, we must save and restore it. */ save_area = save_fixed_argument_area (reg_parm_stack_space, argblock, - &low_to_save, &high_to_save); + &low_to_save, &high_to_save); } #endif @@ -3681,107 +3769,107 @@ int lower_bound = 0, upper_bound = 0, i; if (! (reg != 0 && partial == 0)) - { - if (ACCUMULATE_OUTGOING_ARGS) - { - /* If this is being stored into a pre-allocated, fixed-size, - stack area, save any previous data at that location. */ + { + if (ACCUMULATE_OUTGOING_ARGS) + { + /* If this is being stored into a pre-allocated, fixed-size, + stack area, save any previous data at that location. */ #ifdef ARGS_GROW_DOWNWARD - /* stack_slot is negative, but we want to index stack_usage_map - with positive values. */ - upper_bound = -argvec[argnum].locate.slot_offset.constant + 1; - lower_bound = upper_bound - argvec[argnum].locate.size.constant; + /* stack_slot is negative, but we want to index stack_usage_map + with positive values. */ + upper_bound = -argvec[argnum].locate.slot_offset.constant + 1; + lower_bound = upper_bound - argvec[argnum].locate.size.constant; #else - lower_bound = argvec[argnum].locate.slot_offset.constant; - upper_bound = lower_bound + argvec[argnum].locate.size.constant; + lower_bound = argvec[argnum].locate.slot_offset.constant; + upper_bound = lower_bound + argvec[argnum].locate.size.constant; #endif - i = lower_bound; - /* Don't worry about things in the fixed argument area; - it has already been saved. */ - if (i < reg_parm_stack_space) - i = reg_parm_stack_space; - while (i < upper_bound && stack_usage_map[i] == 0) - i++; - - if (i < upper_bound) - { - /* We need to make a save area. */ - unsigned int size - = argvec[argnum].locate.size.constant * BITS_PER_UNIT; - enum machine_mode save_mode - = mode_for_size (size, MODE_INT, 1); - rtx adr - = plus_constant (argblock, - argvec[argnum].locate.offset.constant); - rtx stack_area - = gen_rtx_MEM (save_mode, memory_address (save_mode, adr)); - - if (save_mode == BLKmode) - { - argvec[argnum].save_area - = assign_stack_temp (BLKmode, - argvec[argnum].locate.size.constant, - 0); - - emit_block_move (validize_mem (argvec[argnum].save_area), - stack_area, - GEN_INT (argvec[argnum].locate.size.constant), - BLOCK_OP_CALL_PARM); - } - else - { - argvec[argnum].save_area = gen_reg_rtx (save_mode); - - emit_move_insn (argvec[argnum].save_area, stack_area); - } - } - } - - emit_push_insn (val, mode, NULL_TREE, NULL_RTX, parm_align, - partial, reg, 0, argblock, - GEN_INT (argvec[argnum].locate.offset.constant), - reg_parm_stack_space, - ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad)); - - /* Now mark the segment we just used. */ - if (ACCUMULATE_OUTGOING_ARGS) - for (i = lower_bound; i < upper_bound; i++) - stack_usage_map[i] = 1; - - NO_DEFER_POP; - - if ((flags & ECF_CONST) - || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS)) - { - rtx use; - - /* Indicate argument access so that alias.c knows that these - values are live. */ - if (argblock) - use = plus_constant (argblock, - argvec[argnum].locate.offset.constant); - else - /* When arguments are pushed, trying to tell alias.c where - exactly this argument is won't work, because the - auto-increment causes confusion. So we merely indicate - that we access something with a known mode somewhere on - the stack. */ - use = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx, - gen_rtx_SCRATCH (Pmode)); - use = gen_rtx_MEM (argvec[argnum].mode, use); - use = gen_rtx_USE (VOIDmode, use); - call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage); - } - } + i = lower_bound; + /* Don't worry about things in the fixed argument area; + it has already been saved. */ + if (i < reg_parm_stack_space) + i = reg_parm_stack_space; + while (i < upper_bound && stack_usage_map[i] == 0) + i++; + + if (i < upper_bound) + { + /* We need to make a save area. */ + unsigned int size + = argvec[argnum].locate.size.constant * BITS_PER_UNIT; + enum machine_mode save_mode + = mode_for_size (size, MODE_INT, 1); + rtx adr + = plus_constant (argblock, + argvec[argnum].locate.offset.constant); + rtx stack_area + = gen_rtx_MEM (save_mode, memory_address (save_mode, adr)); + + if (save_mode == BLKmode) + { + argvec[argnum].save_area + = assign_stack_temp (BLKmode, + argvec[argnum].locate.size.constant, + 0); + + emit_block_move (validize_mem (argvec[argnum].save_area), + stack_area, + GEN_INT (argvec[argnum].locate.size.constant), + BLOCK_OP_CALL_PARM); + } + else + { + argvec[argnum].save_area = gen_reg_rtx (save_mode); + + emit_move_insn (argvec[argnum].save_area, stack_area); + } + } + } + + emit_push_insn (val, mode, NULL_TREE, NULL_RTX, parm_align, + partial, reg, 0, argblock, + GEN_INT (argvec[argnum].locate.offset.constant), + reg_parm_stack_space, + ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad)); + + /* Now mark the segment we just used. */ + if (ACCUMULATE_OUTGOING_ARGS) + for (i = lower_bound; i < upper_bound; i++) + stack_usage_map[i] = 1; + + NO_DEFER_POP; + + if ((flags & ECF_CONST) + || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS)) + { + rtx use; + + /* Indicate argument access so that alias.c knows that these + values are live. */ + if (argblock) + use = plus_constant (argblock, + argvec[argnum].locate.offset.constant); + else + /* When arguments are pushed, trying to tell alias.c where + exactly this argument is won't work, because the + auto-increment causes confusion. So we merely indicate + that we access something with a known mode somewhere on + the stack. */ + use = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx, + gen_rtx_SCRATCH (Pmode)); + use = gen_rtx_MEM (argvec[argnum].mode, use); + use = gen_rtx_USE (VOIDmode, use); + call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage); + } + } } /* If we pushed args in forward order, perform stack alignment after pushing the last arg. */ if (argblock == 0 && !PUSH_ARGS_REVERSED) anti_adjust_stack (GEN_INT (args_size.constant - - original_args_size.constant)); + - original_args_size.constant)); if (PUSH_ARGS_REVERSED) argnum = nargs - 1; @@ -3802,11 +3890,11 @@ int partial = argvec[argnum].partial; /* Handle calls that pass values in multiple non-contiguous - locations. The PA64 has examples of this for library calls. */ + locations. The PA64 has examples of this for library calls. */ if (reg != 0 && GET_CODE (reg) == PARALLEL) - emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (mode)); + emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (mode)); else if (reg != 0 && partial == 0) - emit_move_insn (reg, val); + emit_move_insn (reg, val); NO_DEFER_POP; } @@ -3816,42 +3904,42 @@ { rtx reg = argvec[count].reg; if (reg != 0 && GET_CODE (reg) == PARALLEL) - use_group_regs (&call_fusage, reg); + use_group_regs (&call_fusage, reg); else if (reg != 0) { - int partial = argvec[count].partial; - if (partial) - { - int nregs; + int partial = argvec[count].partial; + if (partial) + { + int nregs; gcc_assert (partial % UNITS_PER_WORD == 0); - nregs = partial / UNITS_PER_WORD; - use_regs (&call_fusage, REGNO (reg), nregs); - } - else - use_reg (&call_fusage, reg); - } + nregs = partial / UNITS_PER_WORD; + use_regs (&call_fusage, REGNO (reg), nregs); + } + else + use_reg (&call_fusage, reg); + } } /* Pass the function the address in which to return a structure value. */ if (mem_value != 0 && struct_value != 0 && ! pcc_struct_value) { emit_move_insn (struct_value, - force_reg (Pmode, - force_operand (XEXP (mem_value, 0), - NULL_RTX))); + force_reg (Pmode, + force_operand (XEXP (mem_value, 0), + NULL_RTX))); if (REG_P (struct_value)) - use_reg (&call_fusage, struct_value); + use_reg (&call_fusage, struct_value); } /* Don't allow popping to be deferred, since then cse'ing of library calls could delete a call and leave the pop. */ NO_DEFER_POP; valreg = (mem_value == 0 && outmode != VOIDmode - ? hard_libcall_value (outmode, orgfun) : NULL_RTX); + ? hard_libcall_value (outmode, orgfun) : NULL_RTX); /* Stack must be properly aligned now. */ gcc_assert (!(stack_pointer_delta - & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))); + & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))); before_call = get_last_insn (); @@ -3880,16 +3968,16 @@ if (flags & ECF_NORETURN) { /* The barrier note must be emitted - immediately after the CALL_INSN. Some ports emit more than - just a CALL_INSN above, so we must search for it here. */ + immediately after the CALL_INSN. Some ports emit more than + just a CALL_INSN above, so we must search for it here. */ rtx last = get_last_insn (); while (!CALL_P (last)) - { - last = PREV_INSN (last); - /* There was no CALL_INSN? */ - gcc_assert (last != before_call); - } + { + last = PREV_INSN (last); + /* There was no CALL_INSN? */ + gcc_assert (last != before_call); + } emit_barrier_after (last); } @@ -3903,64 +3991,64 @@ if (outmode != VOIDmode && retval) { if (mem_value) - { - if (value == 0) - value = mem_value; - if (value != mem_value) - emit_move_insn (value, mem_value); - } + { + if (value == 0) + value = mem_value; + if (value != mem_value) + emit_move_insn (value, mem_value); + } else if (GET_CODE (valreg) == PARALLEL) - { - if (value == 0) - value = gen_reg_rtx (outmode); - emit_group_store (value, valreg, NULL_TREE, GET_MODE_SIZE (outmode)); - } + { + if (value == 0) + value = gen_reg_rtx (outmode); + emit_group_store (value, valreg, NULL_TREE, GET_MODE_SIZE (outmode)); + } else - { - /* Convert to the proper mode if a promotion has been active. */ - if (GET_MODE (valreg) != outmode) - { - int unsignedp = TYPE_UNSIGNED (tfom); - - gcc_assert (promote_function_mode (tfom, outmode, &unsignedp, - fndecl ? TREE_TYPE (fndecl) : fntype, 1) - == GET_MODE (valreg)); - valreg = convert_modes (outmode, GET_MODE (valreg), valreg, 0); - } - - if (value != 0) - emit_move_insn (value, valreg); - else - value = valreg; - } + { + /* Convert to the proper mode if a promotion has been active. */ + if (GET_MODE (valreg) != outmode) + { + int unsignedp = TYPE_UNSIGNED (tfom); + + gcc_assert (promote_function_mode (tfom, outmode, &unsignedp, + fndecl ? TREE_TYPE (fndecl) : fntype, 1) + == GET_MODE (valreg)); + valreg = convert_modes (outmode, GET_MODE (valreg), valreg, 0); + } + + if (value != 0) + emit_move_insn (value, valreg); + else + value = valreg; + } } if (ACCUMULATE_OUTGOING_ARGS) { #ifdef REG_PARM_STACK_SPACE if (save_area) - restore_fixed_argument_area (save_area, argblock, - high_to_save, low_to_save); + restore_fixed_argument_area (save_area, argblock, + high_to_save, low_to_save); #endif /* If we saved any argument areas, restore them. */ for (count = 0; count < nargs; count++) - if (argvec[count].save_area) - { - enum machine_mode save_mode = GET_MODE (argvec[count].save_area); - rtx adr = plus_constant (argblock, - argvec[count].locate.offset.constant); - rtx stack_area = gen_rtx_MEM (save_mode, - memory_address (save_mode, adr)); - - if (save_mode == BLKmode) - emit_block_move (stack_area, - validize_mem (argvec[count].save_area), - GEN_INT (argvec[count].locate.size.constant), - BLOCK_OP_CALL_PARM); - else - emit_move_insn (stack_area, argvec[count].save_area); - } + if (argvec[count].save_area) + { + enum machine_mode save_mode = GET_MODE (argvec[count].save_area); + rtx adr = plus_constant (argblock, + argvec[count].locate.offset.constant); + rtx stack_area = gen_rtx_MEM (save_mode, + memory_address (save_mode, adr)); + + if (save_mode == BLKmode) + emit_block_move (stack_area, + validize_mem (argvec[count].save_area), + GEN_INT (argvec[count].locate.size.constant), + BLOCK_OP_CALL_PARM); + else + emit_move_insn (stack_area, argvec[count].save_area); + } highest_outgoing_arg_in_use = initial_highest_arg_in_use; stack_usage_map = initial_stack_usage_map; @@ -3985,7 +4073,7 @@ void emit_library_call (rtx orgfun, enum libcall_type fn_type, - enum machine_mode outmode, int nargs, ...) + enum machine_mode outmode, int nargs, ...) { va_list p; @@ -4004,15 +4092,15 @@ rtx emit_library_call_value (rtx orgfun, rtx value, - enum libcall_type fn_type, - enum machine_mode outmode, int nargs, ...) + enum libcall_type fn_type, + enum machine_mode outmode, int nargs, ...) { rtx result; va_list p; va_start (p, nargs); result = emit_library_call_value_1 (1, orgfun, value, fn_type, outmode, - nargs, p); + nargs, p); va_end (p); return result; @@ -4039,7 +4127,7 @@ static int store_one_arg (struct arg_data *arg, rtx argblock, int flags, - int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space) + int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space) { tree pval = arg->tree_value; rtx reg = 0; @@ -4058,62 +4146,62 @@ if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL)) { /* If this is being stored into a pre-allocated, fixed-size, stack area, - save any previous data at that location. */ + save any previous data at that location. */ if (argblock && ! variable_size && arg->stack) - { + { #ifdef ARGS_GROW_DOWNWARD - /* stack_slot is negative, but we want to index stack_usage_map - with positive values. */ - if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS) - upper_bound = -INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)) + 1; - else - upper_bound = 0; - - lower_bound = upper_bound - arg->locate.size.constant; + /* stack_slot is negative, but we want to index stack_usage_map + with positive values. */ + if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS) + upper_bound = -INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)) + 1; + else + upper_bound = 0; + + lower_bound = upper_bound - arg->locate.size.constant; #else - if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS) - lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)); - else - lower_bound = 0; - - upper_bound = lower_bound + arg->locate.size.constant; + if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS) + lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)); + else + lower_bound = 0; + + upper_bound = lower_bound + arg->locate.size.constant; #endif - i = lower_bound; - /* Don't worry about things in the fixed argument area; - it has already been saved. */ - if (i < reg_parm_stack_space) - i = reg_parm_stack_space; - while (i < upper_bound && stack_usage_map[i] == 0) - i++; - - if (i < upper_bound) - { - /* We need to make a save area. */ - unsigned int size = arg->locate.size.constant * BITS_PER_UNIT; - enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1); - rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0)); - rtx stack_area = gen_rtx_MEM (save_mode, adr); - - if (save_mode == BLKmode) - { - tree ot = TREE_TYPE (arg->tree_value); - tree nt = build_qualified_type (ot, (TYPE_QUALS (ot) - | TYPE_QUAL_CONST)); - - arg->save_area = assign_temp (nt, 0, 1, 1); - preserve_temp_slots (arg->save_area); - emit_block_move (validize_mem (arg->save_area), stack_area, - GEN_INT (arg->locate.size.constant), - BLOCK_OP_CALL_PARM); - } - else - { - arg->save_area = gen_reg_rtx (save_mode); - emit_move_insn (arg->save_area, stack_area); - } - } - } + i = lower_bound; + /* Don't worry about things in the fixed argument area; + it has already been saved. */ + if (i < reg_parm_stack_space) + i = reg_parm_stack_space; + while (i < upper_bound && stack_usage_map[i] == 0) + i++; + + if (i < upper_bound) + { + /* We need to make a save area. */ + unsigned int size = arg->locate.size.constant * BITS_PER_UNIT; + enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1); + rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0)); + rtx stack_area = gen_rtx_MEM (save_mode, adr); + + if (save_mode == BLKmode) + { + tree ot = TREE_TYPE (arg->tree_value); + tree nt = build_qualified_type (ot, (TYPE_QUALS (ot) + | TYPE_QUAL_CONST)); + + arg->save_area = assign_temp (nt, 0, 1, 1); + preserve_temp_slots (arg->save_area); + emit_block_move (validize_mem (arg->save_area), stack_area, + GEN_INT (arg->locate.size.constant), + BLOCK_OP_CALL_PARM); + } + else + { + arg->save_area = gen_reg_rtx (save_mode); + emit_move_insn (arg->save_area, stack_area); + } + } + } } /* If this isn't going to be placed on both the stack and in registers, @@ -4121,9 +4209,9 @@ if (! arg->pass_on_stack) { if (flags & ECF_SIBCALL) - reg = arg->tail_call_reg; + reg = arg->tail_call_reg; else - reg = arg->reg; + reg = arg->reg; partial = arg->partial; } @@ -4141,48 +4229,48 @@ if (arg->value == 0) { /* stack_arg_under_construction is nonzero if a function argument is - being evaluated directly into the outgoing argument list and - expand_call must take special action to preserve the argument list - if it is called recursively. - - For scalar function arguments stack_usage_map is sufficient to - determine which stack slots must be saved and restored. Scalar - arguments in general have pass_on_stack == 0. - - If this argument is initialized by a function which takes the - address of the argument (a C++ constructor or a C function - returning a BLKmode structure), then stack_usage_map is - insufficient and expand_call must push the stack around the - function call. Such arguments have pass_on_stack == 1. - - Note that it is always safe to set stack_arg_under_construction, - but this generates suboptimal code if set when not needed. */ + being evaluated directly into the outgoing argument list and + expand_call must take special action to preserve the argument list + if it is called recursively. + + For scalar function arguments stack_usage_map is sufficient to + determine which stack slots must be saved and restored. Scalar + arguments in general have pass_on_stack == 0. + + If this argument is initialized by a function which takes the + address of the argument (a C++ constructor or a C function + returning a BLKmode structure), then stack_usage_map is + insufficient and expand_call must push the stack around the + function call. Such arguments have pass_on_stack == 1. + + Note that it is always safe to set stack_arg_under_construction, + but this generates suboptimal code if set when not needed. */ if (arg->pass_on_stack) - stack_arg_under_construction++; + stack_arg_under_construction++; arg->value = expand_expr (pval, - (partial - || TYPE_MODE (TREE_TYPE (pval)) != arg->mode) - ? NULL_RTX : arg->stack, - VOIDmode, EXPAND_STACK_PARM); + (partial + || TYPE_MODE (TREE_TYPE (pval)) != arg->mode) + ? NULL_RTX : arg->stack, + VOIDmode, EXPAND_STACK_PARM); /* If we are promoting object (or for any other reason) the mode - doesn't agree, convert the mode. */ + doesn't agree, convert the mode. */ if (arg->mode != TYPE_MODE (TREE_TYPE (pval))) - arg->value = convert_modes (arg->mode, TYPE_MODE (TREE_TYPE (pval)), - arg->value, arg->unsignedp); + arg->value = convert_modes (arg->mode, TYPE_MODE (TREE_TYPE (pval)), + arg->value, arg->unsignedp); if (arg->pass_on_stack) - stack_arg_under_construction--; + stack_arg_under_construction--; } /* Check for overlap with already clobbered argument area. */ if ((flags & ECF_SIBCALL) && MEM_P (arg->value) && mem_overlaps_already_clobbered_arg_p (XEXP (arg->value, 0), - arg->locate.size.constant)) + arg->locate.size.constant)) sibcall_failure = 1; /* Don't allow anything left on stack from computation @@ -4199,54 +4287,54 @@ unsigned int parm_align; /* Argument is a scalar, not entirely passed in registers. - (If part is passed in registers, arg->partial says how much - and emit_push_insn will take care of putting it there.) - - Push it, and if its size is less than the - amount of space allocated to it, - also bump stack pointer by the additional space. - Note that in C the default argument promotions - will prevent such mismatches. */ + (If part is passed in registers, arg->partial says how much + and emit_push_insn will take care of putting it there.) + + Push it, and if its size is less than the + amount of space allocated to it, + also bump stack pointer by the additional space. + Note that in C the default argument promotions + will prevent such mismatches. */ size = GET_MODE_SIZE (arg->mode); /* Compute how much space the push instruction will push. - On many machines, pushing a byte will advance the stack - pointer by a halfword. */ + On many machines, pushing a byte will advance the stack + pointer by a halfword. */ #ifdef PUSH_ROUNDING size = PUSH_ROUNDING (size); #endif used = size; /* Compute how much space the argument should get: - round up to a multiple of the alignment for arguments. */ + round up to a multiple of the alignment for arguments. */ if (none != FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval))) - used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1) - / (PARM_BOUNDARY / BITS_PER_UNIT)) - * (PARM_BOUNDARY / BITS_PER_UNIT)); + used = (((size + PARM_BOUNDARY / BITS_PER_UNIT - 1) + / (PARM_BOUNDARY / BITS_PER_UNIT)) + * (PARM_BOUNDARY / BITS_PER_UNIT)); /* Compute the alignment of the pushed argument. */ parm_align = arg->locate.boundary; if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward) - { - int pad = used - size; - if (pad) - { - unsigned int pad_align = (pad & -pad) * BITS_PER_UNIT; - parm_align = MIN (parm_align, pad_align); - } - } + { + int pad = used - size; + if (pad) + { + unsigned int pad_align = (pad & -pad) * BITS_PER_UNIT; + parm_align = MIN (parm_align, pad_align); + } + } /* This isn't already where we want it on the stack, so put it there. - This can either be done with push or copy insns. */ + This can either be done with push or copy insns. */ emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, - parm_align, partial, reg, used - size, argblock, - ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, - ARGS_SIZE_RTX (arg->locate.alignment_pad)); + parm_align, partial, reg, used - size, argblock, + ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, + ARGS_SIZE_RTX (arg->locate.alignment_pad)); /* Unless this is a partially-in-register argument, the argument is now - in the stack. */ + in the stack. */ if (partial == 0) - arg->value = arg->stack; + arg->value = arg->stack; } else { @@ -4257,115 +4345,115 @@ rtx size_rtx; /* Pushing a nonscalar. - If part is passed in registers, PARTIAL says how much - and emit_push_insn will take care of putting it there. */ + If part is passed in registers, PARTIAL says how much + and emit_push_insn will take care of putting it there. */ /* Round its size up to a multiple - of the allocation unit for arguments. */ + of the allocation unit for arguments. */ if (arg->locate.size.var != 0) - { - excess = 0; - size_rtx = ARGS_SIZE_RTX (arg->locate.size); - } + { + excess = 0; + size_rtx = ARGS_SIZE_RTX (arg->locate.size); + } else - { - /* PUSH_ROUNDING has no effect on us, because emit_push_insn - for BLKmode is careful to avoid it. */ - excess = (arg->locate.size.constant - - int_size_in_bytes (TREE_TYPE (pval)) - + partial); - size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)), - NULL_RTX, TYPE_MODE (sizetype), - EXPAND_NORMAL); - } + { + /* PUSH_ROUNDING has no effect on us, because emit_push_insn + for BLKmode is careful to avoid it. */ + excess = (arg->locate.size.constant + - int_size_in_bytes (TREE_TYPE (pval)) + + partial); + size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)), + NULL_RTX, TYPE_MODE (sizetype), + EXPAND_NORMAL); + } parm_align = arg->locate.boundary; /* When an argument is padded down, the block is aligned to - PARM_BOUNDARY, but the actual argument isn't. */ + PARM_BOUNDARY, but the actual argument isn't. */ if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward) - { - if (arg->locate.size.var) - parm_align = BITS_PER_UNIT; - else if (excess) - { - unsigned int excess_align = (excess & -excess) * BITS_PER_UNIT; - parm_align = MIN (parm_align, excess_align); - } - } + { + if (arg->locate.size.var) + parm_align = BITS_PER_UNIT; + else if (excess) + { + unsigned int excess_align = (excess & -excess) * BITS_PER_UNIT; + parm_align = MIN (parm_align, excess_align); + } + } if ((flags & ECF_SIBCALL) && MEM_P (arg->value)) - { - /* emit_push_insn might not work properly if arg->value and - argblock + arg->locate.offset areas overlap. */ - rtx x = arg->value; - int i = 0; - - if (XEXP (x, 0) == crtl->args.internal_arg_pointer - || (GET_CODE (XEXP (x, 0)) == PLUS - && XEXP (XEXP (x, 0), 0) == - crtl->args.internal_arg_pointer - && CONST_INT_P (XEXP (XEXP (x, 0), 1)))) - { - if (XEXP (x, 0) != crtl->args.internal_arg_pointer) - i = INTVAL (XEXP (XEXP (x, 0), 1)); - - /* expand_call should ensure this. */ - gcc_assert (!arg->locate.offset.var - && arg->locate.size.var == 0 - && CONST_INT_P (size_rtx)); - - if (arg->locate.offset.constant > i) - { - if (arg->locate.offset.constant < i + INTVAL (size_rtx)) - sibcall_failure = 1; - } - else if (arg->locate.offset.constant < i) - { - /* Use arg->locate.size.constant instead of size_rtx - because we only care about the part of the argument - on the stack. */ - if (i < (arg->locate.offset.constant - + arg->locate.size.constant)) - sibcall_failure = 1; - } - else - { - /* Even though they appear to be at the same location, - if part of the outgoing argument is in registers, - they aren't really at the same location. Check for - this by making sure that the incoming size is the - same as the outgoing size. */ - if (arg->locate.size.constant != INTVAL (size_rtx)) - sibcall_failure = 1; - } - } - } + { + /* emit_push_insn might not work properly if arg->value and + argblock + arg->locate.offset areas overlap. */ + rtx x = arg->value; + int i = 0; + + if (XEXP (x, 0) == crtl->args.internal_arg_pointer + || (GET_CODE (XEXP (x, 0)) == PLUS + && XEXP (XEXP (x, 0), 0) == + crtl->args.internal_arg_pointer + && CONST_INT_P (XEXP (XEXP (x, 0), 1)))) + { + if (XEXP (x, 0) != crtl->args.internal_arg_pointer) + i = INTVAL (XEXP (XEXP (x, 0), 1)); + + /* expand_call should ensure this. */ + gcc_assert (!arg->locate.offset.var + && arg->locate.size.var == 0 + && CONST_INT_P (size_rtx)); + + if (arg->locate.offset.constant > i) + { + if (arg->locate.offset.constant < i + INTVAL (size_rtx)) + sibcall_failure = 1; + } + else if (arg->locate.offset.constant < i) + { + /* Use arg->locate.size.constant instead of size_rtx + because we only care about the part of the argument + on the stack. */ + if (i < (arg->locate.offset.constant + + arg->locate.size.constant)) + sibcall_failure = 1; + } + else + { + /* Even though they appear to be at the same location, + if part of the outgoing argument is in registers, + they aren't really at the same location. Check for + this by making sure that the incoming size is the + same as the outgoing size. */ + if (arg->locate.size.constant != INTVAL (size_rtx)) + sibcall_failure = 1; + } + } + } emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx, - parm_align, partial, reg, excess, argblock, - ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, - ARGS_SIZE_RTX (arg->locate.alignment_pad)); + parm_align, partial, reg, excess, argblock, + ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, + ARGS_SIZE_RTX (arg->locate.alignment_pad)); /* Unless this is a partially-in-register argument, the argument is now - in the stack. - - ??? Unlike the case above, in which we want the actual - address of the data, so that we can load it directly into a - register, here we want the address of the stack slot, so that - it's properly aligned for word-by-word copying or something - like that. It's not clear that this is always correct. */ + in the stack. + + ??? Unlike the case above, in which we want the actual + address of the data, so that we can load it directly into a + register, here we want the address of the stack slot, so that + it's properly aligned for word-by-word copying or something + like that. It's not clear that this is always correct. */ if (partial == 0) - arg->value = arg->stack_slot; + arg->value = arg->stack_slot; } if (arg->reg && GET_CODE (arg->reg) == PARALLEL) { tree type = TREE_TYPE (arg->tree_value); arg->parallel_value - = emit_group_load_into_temps (arg->reg, arg->value, type, - int_size_in_bytes (type)); + = emit_group_load_into_temps (arg->reg, arg->value, type, + int_size_in_bytes (type)); } /* Mark all slots this store used. */ @@ -4392,7 +4480,7 @@ bool must_pass_in_stack_var_size (enum machine_mode mode ATTRIBUTE_UNUSED, - const_tree type) + const_tree type) { if (!type) return false; @@ -4433,7 +4521,7 @@ if (mode == BLKmode && int_size_in_bytes (type) % (PARM_BOUNDARY / BITS_PER_UNIT) && (FUNCTION_ARG_PADDING (mode, type) - == (BYTES_BIG_ENDIAN ? upward : downward))) + == (BYTES_BIG_ENDIAN ? upward : downward))) return true; return false; diff -r 561a7518be6b -r 1b10fe6932e1 gcc/cbc-tree-debug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/cbc-tree-debug.c Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,49 @@ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "c-tree.h" + + +tree +_TREE_TYPE (tree t) +{ + return TREE_TYPE (t); +} + +enum tree_code +_TREE_CODE (tree t) +{ + return TREE_CODE (t); +} + +tree +_TREE_CHAIN (tree t) +{ + return TREE_CHAIN (t); +} + +tree +_DECL_NAME (tree t) +{ + return DECL_NAME (t); +} + +tree +_CALL_EXPR_FN (tree t) +{ + return CALL_EXPR_FN (t); +} + +tree +_CALL_EXPR_ARGS (tree t) +{ + return CALL_EXPR_ARGS (t); +} + +tree +_CALL_EXPR_ARG (tree t, int i) +{ + return CALL_EXPR_ARG (t, i); +} diff -r 561a7518be6b -r 1b10fe6932e1 gcc/cbc-tree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/cbc-tree.h Sun Aug 21 07:53:12 2011 +0900 @@ -0,0 +1,14 @@ +//#define CbC_PRETENDED_STACK_SIZE 256 +#define CbC_PRETENDED_STACK_SIZE 1024 + +/* Set if the fntype is code segment on CbC language. */ +// flag3,5,6 has been used by c-tree.h +#define CbC_IS_CODE_SEGMENT(TYPE) TYPE_LANG_FLAG_5 ( FUNCTION_TYPE_CHECK(TYPE)) + +/* Set if the CALL_EXPR NODE is goto statement on CbC language. */ +#define CbC_IS_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) +#define CALL_EXPR_CbC_GOTO(NODE) TREE_LANG_FLAG_5 (CALL_EXPR_CHECK(NODE)) + +extern tree cbc_return_f; +extern tree cbc_env; +extern location_t cbc_return; diff -r 561a7518be6b -r 1b10fe6932e1 gcc/cfgexpand.c --- a/gcc/cfgexpand.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/cfgexpand.c Sun Aug 21 07:53:12 2011 +0900 @@ -44,6 +44,9 @@ #include "tree-inline.h" #include "value-prof.h" #include "target.h" +#ifndef noCbC +#include "cbc-tree.h" +#endif #include "ssaexpand.h" #include "bitmap.h" #include "sbitmap.h" @@ -76,13 +79,13 @@ gimple_assign_rhs3 (stmt)); else if (grhs_class == GIMPLE_BINARY_RHS) t = build2 (gimple_assign_rhs_code (stmt), - TREE_TYPE (gimple_assign_lhs (stmt)), - gimple_assign_rhs1 (stmt), - gimple_assign_rhs2 (stmt)); + TREE_TYPE (gimple_assign_lhs (stmt)), + gimple_assign_rhs1 (stmt), + gimple_assign_rhs2 (stmt)); else if (grhs_class == GIMPLE_UNARY_RHS) t = build1 (gimple_assign_rhs_code (stmt), - TREE_TYPE (gimple_assign_lhs (stmt)), - gimple_assign_rhs1 (stmt)); + TREE_TYPE (gimple_assign_lhs (stmt)), + gimple_assign_rhs1 (stmt)); else if (grhs_class == GIMPLE_SINGLE_RHS) { t = gimple_assign_rhs1 (stmt); @@ -123,29 +126,29 @@ { SA.partition_to_pseudo[var_to_partition (SA.map, t)] = x; if (x && !MEM_P (x)) - set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (t), x); + set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (t), x); /* For the benefit of debug information at -O0 (where vartracking doesn't run) record the place also in the base DECL if it's - a normal variable (not a parameter). */ + a normal variable (not a parameter). */ if (x && x != pc_rtx && TREE_CODE (SSA_NAME_VAR (t)) == VAR_DECL) - { - tree var = SSA_NAME_VAR (t); - /* If we don't yet have something recorded, just record it now. */ - if (!DECL_RTL_SET_P (var)) - SET_DECL_RTL (var, x); - /* If we have it set alrady to "multiple places" don't - change this. */ - else if (DECL_RTL (var) == pc_rtx) - ; - /* If we have something recorded and it's not the same place - as we want to record now, we have multiple partitions for the - same base variable, with different places. We can't just - randomly chose one, hence we have to say that we don't know. - This only happens with optimization, and there var-tracking - will figure out the right thing. */ - else if (DECL_RTL (var) != x) - SET_DECL_RTL (var, pc_rtx); - } + { + tree var = SSA_NAME_VAR (t); + /* If we don't yet have something recorded, just record it now. */ + if (!DECL_RTL_SET_P (var)) + SET_DECL_RTL (var, x); + /* If we have it set alrady to "multiple places" don't + change this. */ + else if (DECL_RTL (var) == pc_rtx) + ; + /* If we have something recorded and it's not the same place + as we want to record now, we have multiple partitions for the + same base variable, with different places. We can't just + randomly chose one, hence we have to say that we don't know. + This only happens with optimization, and there var-tracking + will figure out the right thing. */ + else if (DECL_RTL (var) != x) + SET_DECL_RTL (var, pc_rtx); + } } else SET_DECL_RTL (t, x); @@ -258,11 +261,11 @@ if (stack_vars_num >= stack_vars_alloc) { if (stack_vars_alloc) - stack_vars_alloc = stack_vars_alloc * 3 / 2; + stack_vars_alloc = stack_vars_alloc * 3 / 2; else - stack_vars_alloc = 32; + stack_vars_alloc = 32; stack_vars - = XRESIZEVEC (struct stack_var, stack_vars, stack_vars_alloc); + = XRESIZEVEC (struct stack_var, stack_vars, stack_vars_alloc); } v = &stack_vars[stack_vars_num]; @@ -333,7 +336,7 @@ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) if (aggregate_contains_union_type (TREE_TYPE (field))) - return true; + return true; return false; } @@ -361,21 +364,21 @@ contains_union = aggregate_contains_union_type (type_i); for (j = 0; j < i; ++j) - { - tree type_j = TREE_TYPE (stack_vars[j].decl); - bool aggr_j = AGGREGATE_TYPE_P (type_j); - if (aggr_i != aggr_j - /* Either the objects conflict by means of type based - aliasing rules, or we need to add a conflict. */ - || !objects_must_conflict_p (type_i, type_j) - /* In case the types do not conflict ensure that access - to elements will conflict. In case of unions we have - to be careful as type based aliasing rules may say - access to the same memory does not conflict. So play - safe and add a conflict in this case. */ - || contains_union) - add_stack_var_conflict (i, j); - } + { + tree type_j = TREE_TYPE (stack_vars[j].decl); + bool aggr_j = AGGREGATE_TYPE_P (type_j); + if (aggr_i != aggr_j + /* Either the objects conflict by means of type based + aliasing rules, or we need to add a conflict. */ + || !objects_must_conflict_p (type_i, type_j) + /* In case the types do not conflict ensure that access + to elements will conflict. In case of unions we have + to be careful as type based aliasing rules may say + access to the same memory does not conflict. So play + safe and add a conflict in this case. */ + || contains_union) + add_stack_var_conflict (i, j); + } } } @@ -420,9 +423,9 @@ if (TREE_CODE (decla) == SSA_NAME) { if (TREE_CODE (declb) == SSA_NAME) - uida = SSA_NAME_VERSION (decla), uidb = SSA_NAME_VERSION (declb); + uida = SSA_NAME_VERSION (decla), uidb = SSA_NAME_VERSION (declb); else - return -1; + return -1; } else if (TREE_CODE (declb) == SSA_NAME) return 1; @@ -442,8 +445,8 @@ static void add_partitioned_vars_to_ptset (struct pt_solution *pt, - struct pointer_map_t *decls_to_partitions, - struct pointer_set_t *visited, bitmap temp) + struct pointer_map_t *decls_to_partitions, + struct pointer_set_t *visited, bitmap temp) { bitmap_iterator bi; unsigned i; @@ -452,7 +455,7 @@ if (pt->anything || pt->vars == NULL /* The pointed-to vars bitmap is shared, it is enough to - visit it once. */ + visit it once. */ || pointer_set_insert(visited, pt->vars)) return; @@ -463,9 +466,9 @@ once. */ EXECUTE_IF_SET_IN_BITMAP (pt->vars, 0, i, bi) if ((!temp - || !bitmap_bit_p (temp, i)) - && (part = (bitmap *) pointer_map_contains (decls_to_partitions, - (void *)(size_t) i))) + || !bitmap_bit_p (temp, i)) + && (part = (bitmap *) pointer_map_contains (decls_to_partitions, + (void *)(size_t) i))) bitmap_ior_into (temp, *part); if (!bitmap_empty_p (temp)) bitmap_ior_into (pt->vars, temp); @@ -495,16 +498,16 @@ continue; if (!decls_to_partitions) - { - decls_to_partitions = pointer_map_create (); - cfun->gimple_df->decls_to_pointers = pointer_map_create (); - } + { + decls_to_partitions = pointer_map_create (); + cfun->gimple_df->decls_to_pointers = pointer_map_create (); + } /* Create an SSA_NAME that points to the partition for use as base during alias-oracle queries on RTL for bases that - have been partitioned. */ + have been partitioned. */ if (var == NULL_TREE) - var = create_tmp_var (ptr_type_node, NULL); + var = create_tmp_var (ptr_type_node, NULL); name = make_ssa_name (var, NULL); /* Create bitmaps representing partitions. They will be used for @@ -542,16 +545,16 @@ bitmap temp = BITMAP_ALLOC (NULL); for (i = 1; i < num_ssa_names; i++) - { - tree name = ssa_name (i); - struct ptr_info_def *pi; - - if (name - && POINTER_TYPE_P (TREE_TYPE (name)) - && ((pi = SSA_NAME_PTR_INFO (name)) != NULL)) - add_partitioned_vars_to_ptset (&pi->pt, decls_to_partitions, - visited, temp); - } + { + tree name = ssa_name (i); + struct ptr_info_def *pi; + + if (name + && POINTER_TYPE_P (TREE_TYPE (name)) + && ((pi = SSA_NAME_PTR_INFO (name)) != NULL)) + add_partitioned_vars_to_ptset (&pi->pt, decls_to_partitions, + visited, temp); + } add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped, decls_to_partitions, visited, temp); @@ -596,7 +599,7 @@ if (vb->conflicts) { EXECUTE_IF_SET_IN_BITMAP (vb->conflicts, 0, u, bi) - add_stack_var_conflict (a, stack_vars[u].representative); + add_stack_var_conflict (a, stack_vars[u].representative); BITMAP_FREE (vb->conflicts); } } @@ -605,18 +608,18 @@ partitions constrained by the interference graph. The overall algorithm used is as follows: - Sort the objects by size. - For each object A { - S = size(A) - O = 0 - loop { - Look for the largest non-conflicting object B with size <= S. - UNION (A, B) - offset(B) = O - O += size(B) - S -= size(B) - } - } + Sort the objects by size. + For each object A { + S = size(A) + O = 0 + loop { + Look for the largest non-conflicting object B with size <= S. + UNION (A, B) + offset(B) = O + O += size(B) + S -= size(B) + } + } */ static void @@ -702,19 +705,19 @@ /* Skip variables that aren't partition representatives, for now. */ if (stack_vars[i].representative != i) - continue; + continue; fprintf (dump_file, "Partition %lu: size " HOST_WIDE_INT_PRINT_DEC - " align %u\n", (unsigned long) i, stack_vars[i].size, - stack_vars[i].alignb); + " align %u\n", (unsigned long) i, stack_vars[i].size, + stack_vars[i].alignb); for (j = i; j != EOC; j = stack_vars[j].next) - { - fputc ('\t', dump_file); - print_generic_expr (dump_file, stack_vars[j].decl, dump_flags); - fprintf (dump_file, ", offset " HOST_WIDE_INT_PRINT_DEC "\n", - stack_vars[j].offset); - } + { + fputc ('\t', dump_file); + print_generic_expr (dump_file, stack_vars[j].decl, dump_flags); + fprintf (dump_file, ", offset " HOST_WIDE_INT_PRINT_DEC "\n", + stack_vars[j].offset); + } } } @@ -821,7 +824,7 @@ /* Skip variables that aren't partition representatives, for now. */ if (stack_vars[i].representative != i) - continue; + continue; /* Skip variables that have already had rtl assigned. See also add_stack_var where we perpetrate this pc_rtx hack. */ @@ -860,7 +863,7 @@ } /* Create rtl for each variable based on their location within the - partition. */ + partition. */ for (j = i; j != EOC; j = stack_vars[j].next) { gcc_assert (stack_vars[j].offset <= stack_vars[i].size); @@ -886,11 +889,11 @@ /* Skip variables that aren't partition representatives, for now. */ if (stack_vars[i].representative != i) - continue; + continue; size += stack_vars[i].size; for (j = i; j != EOC; j = stack_vars[j].next) - set_rtl (stack_vars[j].decl, NULL); + set_rtl (stack_vars[j].decl, NULL); } return size; } @@ -1024,10 +1027,10 @@ if (TREE_TYPE (var) != error_mark_node && TREE_CODE (var) == VAR_DECL) { /* Because we don't know if VAR will be in register or on stack, - we conservatively assume it will be on stack even if VAR is - eventually put into register after RA pass. For non-automatic - variables, which won't be on stack, we collect alignment of - type and ignore user specified alignment. */ + we conservatively assume it will be on stack even if VAR is + eventually put into register after RA pass. For non-automatic + variables, which won't be on stack, we collect alignment of + type and ignore user specified alignment. */ if (TREE_STATIC (var) || DECL_EXTERNAL (var)) align = MINIMUM_ALIGNMENT (TREE_TYPE (var), TYPE_MODE (TREE_TYPE (var)), @@ -1040,7 +1043,7 @@ changed from the offset chosen to it. */ align = crtl->stack_alignment_estimated; else - align = MINIMUM_ALIGNMENT (var, DECL_MODE (var), DECL_ALIGN (var)); + align = MINIMUM_ALIGNMENT (var, DECL_MODE (var), DECL_ALIGN (var)); /* If the variable alignment is very large we'll dynamicaly allocate it, which means that in-frame portion is just a pointer. */ @@ -1067,12 +1070,12 @@ if (TREE_CODE (origvar) == SSA_NAME) { gcc_assert (TREE_CODE (var) != VAR_DECL - || (!DECL_EXTERNAL (var) - && !DECL_HAS_VALUE_EXPR_P (var) - && !TREE_STATIC (var) - && TREE_TYPE (var) != error_mark_node - && !DECL_HARD_REGISTER (var) - && really_expand)); + || (!DECL_EXTERNAL (var) + && !DECL_HAS_VALUE_EXPR_P (var) + && !TREE_STATIC (var) + && TREE_TYPE (var) != error_mark_node + && !DECL_HARD_REGISTER (var) + && really_expand)); } if (TREE_CODE (var) != VAR_DECL && TREE_CODE (origvar) != SSA_NAME) ; @@ -1152,8 +1155,8 @@ new_sv_num = stack_vars_num; for (i = old_sv_num; i < new_sv_num; ++i) - for (j = i < this_sv_num ? i : this_sv_num; j-- > old_sv_num ;) - add_stack_var_conflict (i, j); + for (j = i < this_sv_num ? i : this_sv_num; j-- > old_sv_num ;) + add_stack_var_conflict (i, j); } } @@ -1175,10 +1178,10 @@ /* Examine TYPE and determine a bit mask of the following features. */ -#define SPCT_HAS_LARGE_CHAR_ARRAY 1 -#define SPCT_HAS_SMALL_CHAR_ARRAY 2 -#define SPCT_HAS_ARRAY 4 -#define SPCT_HAS_AGGREGATE 8 +#define SPCT_HAS_LARGE_CHAR_ARRAY 1 +#define SPCT_HAS_SMALL_CHAR_ARRAY 2 +#define SPCT_HAS_ARRAY 4 +#define SPCT_HAS_AGGREGATE 8 static unsigned int stack_protect_classify_type (tree type) @@ -1191,25 +1194,25 @@ case ARRAY_TYPE: t = TYPE_MAIN_VARIANT (TREE_TYPE (type)); if (t == char_type_node - || t == signed_char_type_node - || t == unsigned_char_type_node) - { - unsigned HOST_WIDE_INT max = PARAM_VALUE (PARAM_SSP_BUFFER_SIZE); - unsigned HOST_WIDE_INT len; - - if (!TYPE_SIZE_UNIT (type) - || !host_integerp (TYPE_SIZE_UNIT (type), 1)) - len = max; - else - len = tree_low_cst (TYPE_SIZE_UNIT (type), 1); - - if (len < max) - ret = SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_ARRAY; - else - ret = SPCT_HAS_LARGE_CHAR_ARRAY | SPCT_HAS_ARRAY; - } + || t == signed_char_type_node + || t == unsigned_char_type_node) + { + unsigned HOST_WIDE_INT max = PARAM_VALUE (PARAM_SSP_BUFFER_SIZE); + unsigned HOST_WIDE_INT len; + + if (!TYPE_SIZE_UNIT (type) + || !host_integerp (TYPE_SIZE_UNIT (type), 1)) + len = max; else - ret = SPCT_HAS_ARRAY; + len = tree_low_cst (TYPE_SIZE_UNIT (type), 1); + + if (len < max) + ret = SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_ARRAY; + else + ret = SPCT_HAS_LARGE_CHAR_ARRAY | SPCT_HAS_ARRAY; + } + else + ret = SPCT_HAS_ARRAY; break; case UNION_TYPE: @@ -1217,8 +1220,8 @@ case RECORD_TYPE: ret = SPCT_HAS_AGGREGATE; for (t = TYPE_FIELDS (type); t ; t = TREE_CHAIN (t)) - if (TREE_CODE (t) == FIELD_DECL) - ret |= stack_protect_classify_type (TREE_TYPE (t)); + if (TREE_CODE (t) == FIELD_DECL) + ret |= stack_protect_classify_type (TREE_TYPE (t)); break; default: @@ -1245,10 +1248,10 @@ if (flag_stack_protect == 2) { if ((bits & (SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_LARGE_CHAR_ARRAY)) - && !(bits & SPCT_HAS_AGGREGATE)) - ret = 1; + && !(bits & SPCT_HAS_AGGREGATE)) + ret = 1; else if (bits & SPCT_HAS_ARRAY) - ret = 2; + ret = 2; } else ret = (bits & SPCT_HAS_LARGE_CHAR_ARRAY) != 0; @@ -1291,8 +1294,8 @@ { unsigned char ph_i = phase[i]; for (j = 0; j < i; ++j) - if (ph_i != phase[j]) - add_stack_var_conflict (i, j); + if (ph_i != phase[j]) + add_stack_var_conflict (i, j); } XDELETEVEC (phase); @@ -1304,7 +1307,7 @@ create_stack_guard (void) { tree guard = build_decl (DECL_SOURCE_LOCATION (current_function_decl), - VAR_DECL, NULL, ptr_type_node); + VAR_DECL, NULL, ptr_type_node); TREE_THIS_VOLATILE (guard) = 1; TREE_USED (guard) = 1; expand_one_stack_var (guard); @@ -1372,7 +1375,7 @@ /* Fake sorting the stack vars for account_stack_vars (). */ stack_vars_sorted = XNEWVEC (size_t, stack_vars_num); for (i = 0; i < stack_vars_num; ++i) - stack_vars_sorted[i] = i; + stack_vars_sorted[i] = i; size += account_stack_vars (); fini_vars_expansion (); } @@ -1406,20 +1409,20 @@ gcc_assert (is_gimple_reg (var)); if (TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL) - expand_one_var (var, true, true); + expand_one_var (var, true, true); else - { - /* This is a PARM_DECL or RESULT_DECL. For those partitions that - contain the default def (representing the parm or result itself) - we don't do anything here. But those which don't contain the - default def (representing a temporary based on the parm/result) - we need to allocate space just like for normal VAR_DECLs. */ - if (!bitmap_bit_p (SA.partition_has_default_def, i)) - { - expand_one_var (var, true, true); - gcc_assert (SA.partition_to_pseudo[i]); - } - } + { + /* This is a PARM_DECL or RESULT_DECL. For those partitions that + contain the default def (representing the parm or result itself) + we don't do anything here. But those which don't contain the + default def (representing a temporary based on the parm/result) + we need to allocate space just like for normal VAR_DECLs. */ + if (!bitmap_bit_p (SA.partition_has_default_def, i)) + { + expand_one_var (var, true, true); + gcc_assert (SA.partition_to_pseudo[i]); + } + } } /* At this point all variables on the local_decls with TREE_USED @@ -1437,21 +1440,21 @@ goto next; } /* We didn't set a block for static or extern because it's hard - to tell the difference between a global variable (re)declared - in a local scope, and one that's really declared there to - begin with. And it doesn't really matter much, since we're - not giving them stack space. Expand them now. */ + to tell the difference between a global variable (re)declared + in a local scope, and one that's really declared there to + begin with. And it doesn't really matter much, since we're + not giving them stack space. Expand them now. */ else if (TREE_STATIC (var) || DECL_EXTERNAL (var)) - expand_now = true; + expand_now = true; /* If the variable is not associated with any block, then it - was created by the optimizers, and could be live anywhere - in the function. */ + was created by the optimizers, and could be live anywhere + in the function. */ else if (TREE_USED (var)) - expand_now = true; + expand_now = true; /* Finally, mark all variables on the list as used. We'll use - this in a moment when we expand those associated with scopes. */ + this in a moment when we expand those associated with scopes. */ TREE_USED (var) = 1; if (expand_now) @@ -1495,46 +1498,46 @@ if (stack_vars_num > 0) { /* Due to the way alias sets work, no variables with non-conflicting - alias sets may be assigned the same address. Add conflicts to - reflect this. */ + alias sets may be assigned the same address. Add conflicts to + reflect this. */ add_alias_set_conflicts (); /* If stack protection is enabled, we don't share space between - vulnerable data and non-vulnerable data. */ + vulnerable data and non-vulnerable data. */ if (flag_stack_protect) - add_stack_protection_conflicts (); + add_stack_protection_conflicts (); /* Now that we have collected all stack variables, and have computed a - minimal interference graph, attempt to save some stack space. */ + minimal interference graph, attempt to save some stack space. */ partition_stack_vars (); if (dump_file) - dump_stack_var_partition (); + dump_stack_var_partition (); } /* There are several conditions under which we should create a stack guard: protect-all, alloca used, protected decls present. */ if (flag_stack_protect == 2 || (flag_stack_protect - && (cfun->calls_alloca || has_protected_decls))) + && (cfun->calls_alloca || has_protected_decls))) create_stack_guard (); /* Assign rtl to each variable based on these partitions. */ if (stack_vars_num > 0) { /* Reorder decls to be protected by iterating over the variables - array multiple times, and allocating out of each phase in turn. */ + array multiple times, and allocating out of each phase in turn. */ /* ??? We could probably integrate this into the qsort we did - earlier, such that we naturally see these variables first, - and thus naturally allocate things in the right order. */ + earlier, such that we naturally see these variables first, + and thus naturally allocate things in the right order. */ if (has_protected_decls) - { - /* Phase 1 contains only character arrays. */ - expand_stack_vars (stack_protect_decl_phase_1); - - /* Phase 2 contains other kinds of arrays. */ - if (flag_stack_protect == 2) - expand_stack_vars (stack_protect_decl_phase_2); - } + { + /* Phase 1 contains only character arrays. */ + expand_stack_vars (stack_protect_decl_phase_1); + + /* Phase 2 contains other kinds of arrays. */ + if (flag_stack_protect == 2) + expand_stack_vars (stack_protect_decl_phase_2); + } expand_stack_vars (NULL); @@ -1560,7 +1563,7 @@ { HOST_WIDE_INT align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; if (!FRAME_GROWS_DOWNWARD) - frame_offset += align - 1; + frame_offset += align - 1; frame_offset &= -align; } } @@ -1577,7 +1580,7 @@ { fprintf (dump_file, "\n;; "); print_gimple_stmt (dump_file, stmt, 0, - TDF_SLIM | (dump_flags & TDF_LINENO)); + TDF_SLIM | (dump_flags & TDF_LINENO)); fprintf (dump_file, "\n"); print_rtl (dump_file, since ? NEXT_INSN (since) : since); @@ -1611,11 +1614,11 @@ { lab_stmt = gsi_stmt (gsi); if (gimple_code (lab_stmt) != GIMPLE_LABEL) - break; + break; lab = gimple_label_label (lab_stmt); if (DECL_NONLOCAL (lab)) - break; + break; return label_rtx (lab); } @@ -1650,17 +1653,17 @@ rtx insn; remove_edge (e); /* Now, we have a single successor block, if we have insns to - insert on the remaining edge we potentially will insert - it at the end of this block (if the dest block isn't feasible) - in order to avoid splitting the edge. This insertion will take - place in front of the last jump. But we might have emitted - multiple jumps (conditional and one unconditional) to the - same destination. Inserting in front of the last one then - is a problem. See PR 40021. We fix this by deleting all - jumps except the last unconditional one. */ + insert on the remaining edge we potentially will insert + it at the end of this block (if the dest block isn't feasible) + in order to avoid splitting the edge. This insertion will take + place in front of the last jump. But we might have emitted + multiple jumps (conditional and one unconditional) to the + same destination. Inserting in front of the last one then + is a problem. See PR 40021. We fix this by deleting all + jumps except the last unconditional one. */ insn = PREV_INSN (get_last_insn ()); /* Make sure we have an unconditional jump. Otherwise we're - confused. */ + confused. */ gcc_assert (JUMP_P (insn) && !any_condjump_p (insn)); for (insn = PREV_INSN (insn); insn != last;) { @@ -1711,35 +1714,35 @@ { gimple second = SSA_NAME_DEF_STMT (op0); if (gimple_code (second) == GIMPLE_ASSIGN) - { - enum tree_code code2 = gimple_assign_rhs_code (second); - if (TREE_CODE_CLASS (code2) == tcc_comparison) - { - code = code2; - op0 = gimple_assign_rhs1 (second); - op1 = gimple_assign_rhs2 (second); - } - /* If jumps are cheap turn some more codes into - jumpy sequences. */ - else if (BRANCH_COST (optimize_insn_for_speed_p (), false) < 4) - { - if ((code2 == BIT_AND_EXPR - && TYPE_PRECISION (TREE_TYPE (op0)) == 1 - && TREE_CODE (gimple_assign_rhs2 (second)) != INTEGER_CST) - || code2 == TRUTH_AND_EXPR) - { - code = TRUTH_ANDIF_EXPR; - op0 = gimple_assign_rhs1 (second); - op1 = gimple_assign_rhs2 (second); - } - else if (code2 == BIT_IOR_EXPR || code2 == TRUTH_OR_EXPR) - { - code = TRUTH_ORIF_EXPR; - op0 = gimple_assign_rhs1 (second); - op1 = gimple_assign_rhs2 (second); - } - } - } + { + enum tree_code code2 = gimple_assign_rhs_code (second); + if (TREE_CODE_CLASS (code2) == tcc_comparison) + { + code = code2; + op0 = gimple_assign_rhs1 (second); + op1 = gimple_assign_rhs2 (second); + } + /* If jumps are cheap turn some more codes into + jumpy sequences. */ + else if (BRANCH_COST (optimize_insn_for_speed_p (), false) < 4) + { + if ((code2 == BIT_AND_EXPR + && TYPE_PRECISION (TREE_TYPE (op0)) == 1 + && TREE_CODE (gimple_assign_rhs2 (second)) != INTEGER_CST) + || code2 == TRUTH_AND_EXPR) + { + code = TRUTH_ANDIF_EXPR; + op0 = gimple_assign_rhs1 (second); + op1 = gimple_assign_rhs2 (second); + } + else if (code2 == BIT_IOR_EXPR || code2 == TRUTH_OR_EXPR) + { + code = TRUTH_ORIF_EXPR; + op0 = gimple_assign_rhs1 (second); + op1 = gimple_assign_rhs2 (second); + } + } + } } last2 = last = get_last_insn (); @@ -1763,11 +1766,11 @@ true_edge->probability); maybe_dump_rtl_for_gimple_stmt (stmt, last); if (true_edge->goto_locus) - { - set_curr_insn_source_location (true_edge->goto_locus); - set_curr_insn_block (true_edge->goto_block); - true_edge->goto_locus = curr_insn_locator (); - } + { + set_curr_insn_source_location (true_edge->goto_locus); + set_curr_insn_block (true_edge->goto_block); + true_edge->goto_locus = curr_insn_locator (); + } true_edge->goto_block = NULL; false_edge->flags |= EDGE_FALLTHRU; maybe_cleanup_end_of_block (false_edge, last); @@ -1779,11 +1782,11 @@ false_edge->probability); maybe_dump_rtl_for_gimple_stmt (stmt, last); if (false_edge->goto_locus) - { - set_curr_insn_source_location (false_edge->goto_locus); - set_curr_insn_block (false_edge->goto_block); - false_edge->goto_locus = curr_insn_locator (); - } + { + set_curr_insn_source_location (false_edge->goto_locus); + set_curr_insn_block (false_edge->goto_block); + false_edge->goto_locus = curr_insn_locator (); + } false_edge->goto_block = NULL; true_edge->flags |= EDGE_FALLTHRU; maybe_cleanup_end_of_block (true_edge, last); @@ -1901,9 +1904,9 @@ case GIMPLE_GOTO: op0 = gimple_goto_dest (stmt); if (TREE_CODE (op0) == LABEL_DECL) - expand_goto (op0); + expand_goto (op0); else - expand_computed_goto (op0); + expand_computed_goto (op0); break; case GIMPLE_LABEL: expand_label (gimple_label_label (stmt)); @@ -1925,30 +1928,30 @@ op0 = gimple_return_retval (stmt); if (op0 && op0 != error_mark_node) - { - tree result = DECL_RESULT (current_function_decl); - - /* If we are not returning the current function's RESULT_DECL, - build an assignment to it. */ - if (op0 != result) - { - /* I believe that a function's RESULT_DECL is unique. */ - gcc_assert (TREE_CODE (op0) != RESULT_DECL); - - /* ??? We'd like to use simply expand_assignment here, - but this fails if the value is of BLKmode but the return - decl is a register. expand_return has special handling - for this combination, which eventually should move - to common code. See comments there. Until then, let's - build a modify expression :-/ */ - op0 = build2 (MODIFY_EXPR, TREE_TYPE (result), - result, op0); - } - } + { + tree result = DECL_RESULT (current_function_decl); + + /* If we are not returning the current function's RESULT_DECL, + build an assignment to it. */ + if (op0 != result) + { + /* I believe that a function's RESULT_DECL is unique. */ + gcc_assert (TREE_CODE (op0) != RESULT_DECL); + + /* ??? We'd like to use simply expand_assignment here, + but this fails if the value is of BLKmode but the return + decl is a register. expand_return has special handling + for this combination, which eventually should move + to common code. See comments there. Until then, let's + build a modify expression :-/ */ + op0 = build2 (MODIFY_EXPR, TREE_TYPE (result), + result, op0); + } + } if (!op0) - expand_null_return (); + expand_null_return (); else - expand_return (op0); + expand_return (op0); break; case GIMPLE_ASSIGN: @@ -2089,16 +2092,16 @@ { rtx insn; for (insn = next_real_insn (last); insn; - insn = next_real_insn (insn)) - { - if (! find_reg_note (insn, REG_EH_REGION, NULL_RTX) - /* If we want exceptions for non-call insns, any - may_trap_p instruction may throw. */ - && GET_CODE (PATTERN (insn)) != CLOBBER - && GET_CODE (PATTERN (insn)) != USE - && insn_could_throw_p (insn)) - make_reg_eh_region_note (insn, 0, lp_nr); - } + insn = next_real_insn (insn)) + { + if (! find_reg_note (insn, REG_EH_REGION, NULL_RTX) + /* If we want exceptions for non-call insns, any + may_trap_p instruction may throw. */ + && GET_CODE (PATTERN (insn)) != CLOBBER + && GET_CODE (PATTERN (insn)) != USE + && insn_could_throw_p (insn)) + make_reg_eh_region_note (insn, 0, lp_nr); + } } return last; @@ -2152,22 +2155,22 @@ for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH))) - { - if (e->dest != EXIT_BLOCK_PTR) - { - e->dest->count -= e->count; - e->dest->frequency -= EDGE_FREQUENCY (e); - if (e->dest->count < 0) - e->dest->count = 0; - if (e->dest->frequency < 0) - e->dest->frequency = 0; - } - count += e->count; - probability += e->probability; - remove_edge (e); - } + { + if (e->dest != EXIT_BLOCK_PTR) + { + e->dest->count -= e->count; + e->dest->frequency -= EDGE_FREQUENCY (e); + if (e->dest->count < 0) + e->dest->count = 0; + if (e->dest->frequency < 0) + e->dest->frequency = 0; + } + count += e->count; + probability += e->probability; + remove_edge (e); + } else - ei_next (&ei); + ei_next (&ei); } /* This is somewhat ugly: the call_expr expander often emits instructions @@ -2180,12 +2183,12 @@ while (NEXT_INSN (last)) { /* For instance an sqrt builtin expander expands if with - sibcall in the then and label for `else`. */ + sibcall in the then and label for `else`. */ if (LABEL_P (NEXT_INSN (last))) - { - *can_fallthru = true; - break; - } + { + *can_fallthru = true; + break; + } delete_insn (NEXT_INSN (last)); } @@ -2201,7 +2204,7 @@ last = BB_END (bb); if (BARRIER_P (last)) - BB_END (bb) = PREV_INSN (last); + BB_END (bb) = PREV_INSN (last); } maybe_dump_rtl_for_gimple_stmt (stmt, last2); @@ -2219,8 +2222,8 @@ (mode, gen_rtx_NE (BImode, mod, const0_rtx), gen_rtx_IF_THEN_ELSE (mode, gen_rtx_LT (BImode, - gen_rtx_DIV (mode, op1, mod), - const0_rtx), + gen_rtx_DIV (mode, op1, mod), + const0_rtx), constm1_rtx, const0_rtx), const0_rtx); } @@ -2235,8 +2238,8 @@ (mode, gen_rtx_NE (BImode, mod, const0_rtx), gen_rtx_IF_THEN_ELSE (mode, gen_rtx_GT (BImode, - gen_rtx_DIV (mode, op1, mod), - const0_rtx), + gen_rtx_DIV (mode, op1, mod), + const0_rtx), const1_rtx, const0_rtx), const0_rtx); } @@ -2263,13 +2266,13 @@ : 0) */ return gen_rtx_IF_THEN_ELSE (mode, gen_rtx_GE (BImode, gen_rtx_ABS (mode, mod), - gen_rtx_MINUS (mode, - gen_rtx_ABS (mode, op1), - gen_rtx_ABS (mode, mod))), + gen_rtx_MINUS (mode, + gen_rtx_ABS (mode, op1), + gen_rtx_ABS (mode, mod))), gen_rtx_IF_THEN_ELSE (mode, gen_rtx_GT (BImode, - gen_rtx_DIV (mode, op1, mod), - const0_rtx), + gen_rtx_DIV (mode, op1, mod), + const0_rtx), const1_rtx, constm1_rtx), const0_rtx); } @@ -2284,7 +2287,7 @@ /* (mod >= op1 - mod ? 1 : 0) */ return gen_rtx_IF_THEN_ELSE (mode, gen_rtx_GE (BImode, mod, - gen_rtx_MINUS (mode, op1, mod)), + gen_rtx_MINUS (mode, op1, mod)), const1_rtx, const0_rtx); } @@ -2313,8 +2316,8 @@ if (GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (xmode)) x = simplify_gen_subreg (mode, x, xmode, - subreg_lowpart_offset - (mode, xmode)); + subreg_lowpart_offset + (mode, xmode)); else if (POINTERS_EXTEND_UNSIGNED > 0) x = gen_rtx_ZERO_EXTEND (mode, x); else if (!POINTERS_EXTEND_UNSIGNED) @@ -2407,7 +2410,7 @@ ternary: op2 = expand_debug_expr (TREE_OPERAND (exp, 2)); if (!op2) - return NULL_RTX; + return NULL_RTX; /* Fall through. */ binary: @@ -2415,14 +2418,14 @@ case tcc_comparison: op1 = expand_debug_expr (TREE_OPERAND (exp, 1)); if (!op1) - return NULL_RTX; + return NULL_RTX; /* Fall through. */ unary: case tcc_unary: op0 = expand_debug_expr (TREE_OPERAND (exp, 0)); if (!op0) - return NULL_RTX; + return NULL_RTX; break; case tcc_type: @@ -2441,15 +2444,15 @@ { case STRING_CST: if (!lookup_constant_def (exp)) - { - if (strlen (TREE_STRING_POINTER (exp)) + 1 - != (size_t) TREE_STRING_LENGTH (exp)) - return NULL_RTX; - op0 = gen_rtx_CONST_STRING (Pmode, TREE_STRING_POINTER (exp)); - op0 = gen_rtx_MEM (BLKmode, op0); - set_mem_attributes (op0, exp, 0); - return op0; - } + { + if (strlen (TREE_STRING_POINTER (exp)) + 1 + != (size_t) TREE_STRING_LENGTH (exp)) + return NULL_RTX; + op0 = gen_rtx_CONST_STRING (Pmode, TREE_STRING_POINTER (exp)); + op0 = gen_rtx_MEM (BLKmode, op0); + set_mem_attributes (op0, exp, 0); + return op0; + } /* Fall through... */ case INTEGER_CST: @@ -2468,7 +2471,7 @@ op0 = DECL_RTL_IF_SET (exp); if (op0) - return op0; + return op0; op0 = gen_rtx_DEBUG_EXPR (mode); DEBUG_EXPR_TREE_DECL (op0) = exp; @@ -2502,7 +2505,7 @@ return NULL; } else - op0 = copy_rtx (op0); + op0 = copy_rtx (op0); if (GET_MODE (op0) == BLKmode /* If op0 is not BLKmode, but BLKmode is, adjust_mode @@ -2590,7 +2593,7 @@ case INDIRECT_REF: op0 = expand_debug_expr (TREE_OPERAND (exp, 0)); if (!op0) - return NULL; + return NULL; if (TREE_CODE (exp) == MEM_REF) { @@ -2633,9 +2636,9 @@ return NULL; op0 = expand_debug_expr - (tree_mem_ref_addr (build_pointer_type (TREE_TYPE (exp)), exp)); + (tree_mem_ref_addr (build_pointer_type (TREE_TYPE (exp)), exp)); if (!op0) - return NULL; + return NULL; if (POINTER_TYPE_P (TREE_TYPE (exp))) as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp))); @@ -2790,15 +2793,15 @@ case FLOAT_EXPR: if (unsignedp) - return gen_rtx_UNSIGNED_FLOAT (mode, op0); + return gen_rtx_UNSIGNED_FLOAT (mode, op0); else - return gen_rtx_FLOAT (mode, op0); + return gen_rtx_FLOAT (mode, op0); case FIX_TRUNC_EXPR: if (unsignedp) - return gen_rtx_UNSIGNED_FIX (mode, op0); + return gen_rtx_UNSIGNED_FIX (mode, op0); else - return gen_rtx_FIX (mode, op0); + return gen_rtx_FIX (mode, op0); case POINTER_PLUS_EXPR: /* For the rare target where pointers are not the same size as @@ -2830,110 +2833,110 @@ case TRUNC_DIV_EXPR: case EXACT_DIV_EXPR: if (unsignedp) - return gen_rtx_UDIV (mode, op0, op1); + return gen_rtx_UDIV (mode, op0, op1); else - return gen_rtx_DIV (mode, op0, op1); + return gen_rtx_DIV (mode, op0, op1); case TRUNC_MOD_EXPR: if (unsignedp) - return gen_rtx_UMOD (mode, op0, op1); + return gen_rtx_UMOD (mode, op0, op1); else - return gen_rtx_MOD (mode, op0, op1); + return gen_rtx_MOD (mode, op0, op1); case FLOOR_DIV_EXPR: if (unsignedp) - return gen_rtx_UDIV (mode, op0, op1); + return gen_rtx_UDIV (mode, op0, op1); else - { - rtx div = gen_rtx_DIV (mode, op0, op1); - rtx mod = gen_rtx_MOD (mode, op0, op1); - rtx adj = floor_sdiv_adjust (mode, mod, op1); - return gen_rtx_PLUS (mode, div, adj); - } + { + rtx div = gen_rtx_DIV (mode, op0, op1); + rtx mod = gen_rtx_MOD (mode, op0, op1); + rtx adj = floor_sdiv_adjust (mode, mod, op1); + return gen_rtx_PLUS (mode, div, adj); + } case FLOOR_MOD_EXPR: if (unsignedp) - return gen_rtx_UMOD (mode, op0, op1); + return gen_rtx_UMOD (mode, op0, op1); else - { - rtx mod = gen_rtx_MOD (mode, op0, op1); - rtx adj = floor_sdiv_adjust (mode, mod, op1); - adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); - return gen_rtx_PLUS (mode, mod, adj); - } + { + rtx mod = gen_rtx_MOD (mode, op0, op1); + rtx adj = floor_sdiv_adjust (mode, mod, op1); + adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); + return gen_rtx_PLUS (mode, mod, adj); + } case CEIL_DIV_EXPR: if (unsignedp) - { - rtx div = gen_rtx_UDIV (mode, op0, op1); - rtx mod = gen_rtx_UMOD (mode, op0, op1); - rtx adj = ceil_udiv_adjust (mode, mod, op1); - return gen_rtx_PLUS (mode, div, adj); - } + { + rtx div = gen_rtx_UDIV (mode, op0, op1); + rtx mod = gen_rtx_UMOD (mode, op0, op1); + rtx adj = ceil_udiv_adjust (mode, mod, op1); + return gen_rtx_PLUS (mode, div, adj); + } else - { - rtx div = gen_rtx_DIV (mode, op0, op1); - rtx mod = gen_rtx_MOD (mode, op0, op1); - rtx adj = ceil_sdiv_adjust (mode, mod, op1); - return gen_rtx_PLUS (mode, div, adj); - } + { + rtx div = gen_rtx_DIV (mode, op0, op1); + rtx mod = gen_rtx_MOD (mode, op0, op1); + rtx adj = ceil_sdiv_adjust (mode, mod, op1); + return gen_rtx_PLUS (mode, div, adj); + } case CEIL_MOD_EXPR: if (unsignedp) - { - rtx mod = gen_rtx_UMOD (mode, op0, op1); - rtx adj = ceil_udiv_adjust (mode, mod, op1); - adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); - return gen_rtx_PLUS (mode, mod, adj); - } + { + rtx mod = gen_rtx_UMOD (mode, op0, op1); + rtx adj = ceil_udiv_adjust (mode, mod, op1); + adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); + return gen_rtx_PLUS (mode, mod, adj); + } else - { - rtx mod = gen_rtx_MOD (mode, op0, op1); - rtx adj = ceil_sdiv_adjust (mode, mod, op1); - adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); - return gen_rtx_PLUS (mode, mod, adj); - } + { + rtx mod = gen_rtx_MOD (mode, op0, op1); + rtx adj = ceil_sdiv_adjust (mode, mod, op1); + adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); + return gen_rtx_PLUS (mode, mod, adj); + } case ROUND_DIV_EXPR: if (unsignedp) - { - rtx div = gen_rtx_UDIV (mode, op0, op1); - rtx mod = gen_rtx_UMOD (mode, op0, op1); - rtx adj = round_udiv_adjust (mode, mod, op1); - return gen_rtx_PLUS (mode, div, adj); - } + { + rtx div = gen_rtx_UDIV (mode, op0, op1); + rtx mod = gen_rtx_UMOD (mode, op0, op1); + rtx adj = round_udiv_adjust (mode, mod, op1); + return gen_rtx_PLUS (mode, div, adj); + } else - { - rtx div = gen_rtx_DIV (mode, op0, op1); - rtx mod = gen_rtx_MOD (mode, op0, op1); - rtx adj = round_sdiv_adjust (mode, mod, op1); - return gen_rtx_PLUS (mode, div, adj); - } + { + rtx div = gen_rtx_DIV (mode, op0, op1); + rtx mod = gen_rtx_MOD (mode, op0, op1); + rtx adj = round_sdiv_adjust (mode, mod, op1); + return gen_rtx_PLUS (mode, div, adj); + } case ROUND_MOD_EXPR: if (unsignedp) - { - rtx mod = gen_rtx_UMOD (mode, op0, op1); - rtx adj = round_udiv_adjust (mode, mod, op1); - adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); - return gen_rtx_PLUS (mode, mod, adj); - } + { + rtx mod = gen_rtx_UMOD (mode, op0, op1); + rtx adj = round_udiv_adjust (mode, mod, op1); + adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); + return gen_rtx_PLUS (mode, mod, adj); + } else - { - rtx mod = gen_rtx_MOD (mode, op0, op1); - rtx adj = round_sdiv_adjust (mode, mod, op1); - adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); - return gen_rtx_PLUS (mode, mod, adj); - } + { + rtx mod = gen_rtx_MOD (mode, op0, op1); + rtx adj = round_sdiv_adjust (mode, mod, op1); + adj = gen_rtx_NEG (mode, gen_rtx_MULT (mode, adj, op1)); + return gen_rtx_PLUS (mode, mod, adj); + } case LSHIFT_EXPR: return gen_rtx_ASHIFT (mode, op0, op1); case RSHIFT_EXPR: if (unsignedp) - return gen_rtx_LSHIFTRT (mode, op0, op1); + return gen_rtx_LSHIFTRT (mode, op0, op1); else - return gen_rtx_ASHIFTRT (mode, op0, op1); + return gen_rtx_ASHIFTRT (mode, op0, op1); case LROTATE_EXPR: return gen_rtx_ROTATE (mode, op0, op1); @@ -2943,15 +2946,15 @@ case MIN_EXPR: if (unsignedp) - return gen_rtx_UMIN (mode, op0, op1); + return gen_rtx_UMIN (mode, op0, op1); else - return gen_rtx_SMIN (mode, op0, op1); + return gen_rtx_SMIN (mode, op0, op1); case MAX_EXPR: if (unsignedp) - return gen_rtx_UMAX (mode, op0, op1); + return gen_rtx_UMAX (mode, op0, op1); else - return gen_rtx_SMAX (mode, op0, op1); + return gen_rtx_SMAX (mode, op0, op1); case BIT_AND_EXPR: case TRUTH_AND_EXPR: @@ -2976,27 +2979,27 @@ case LT_EXPR: if (unsignedp) - return gen_rtx_LTU (mode, op0, op1); + return gen_rtx_LTU (mode, op0, op1); else - return gen_rtx_LT (mode, op0, op1); + return gen_rtx_LT (mode, op0, op1); case LE_EXPR: if (unsignedp) - return gen_rtx_LEU (mode, op0, op1); + return gen_rtx_LEU (mode, op0, op1); else - return gen_rtx_LE (mode, op0, op1); + return gen_rtx_LE (mode, op0, op1); case GT_EXPR: if (unsignedp) - return gen_rtx_GTU (mode, op0, op1); + return gen_rtx_GTU (mode, op0, op1); else - return gen_rtx_GT (mode, op0, op1); + return gen_rtx_GT (mode, op0, op1); case GE_EXPR: if (unsignedp) - return gen_rtx_GEU (mode, op0, op1); + return gen_rtx_GEU (mode, op0, op1); else - return gen_rtx_GE (mode, op0, op1); + return gen_rtx_GE (mode, op0, op1); case EQ_EXPR: return gen_rtx_EQ (mode, op0, op1); @@ -3034,50 +3037,50 @@ case COMPLEX_EXPR: gcc_assert (COMPLEX_MODE_P (mode)); if (GET_MODE (op0) == VOIDmode) - op0 = gen_rtx_CONST (GET_MODE_INNER (mode), op0); + op0 = gen_rtx_CONST (GET_MODE_INNER (mode), op0); if (GET_MODE (op1) == VOIDmode) - op1 = gen_rtx_CONST (GET_MODE_INNER (mode), op1); + op1 = gen_rtx_CONST (GET_MODE_INNER (mode), op1); return gen_rtx_CONCAT (mode, op0, op1); case CONJ_EXPR: if (GET_CODE (op0) == CONCAT) - return gen_rtx_CONCAT (mode, XEXP (op0, 0), - gen_rtx_NEG (GET_MODE_INNER (mode), - XEXP (op0, 1))); + return gen_rtx_CONCAT (mode, XEXP (op0, 0), + gen_rtx_NEG (GET_MODE_INNER (mode), + XEXP (op0, 1))); + else + { + enum machine_mode imode = GET_MODE_INNER (mode); + rtx re, im; + + if (MEM_P (op0)) + { + re = adjust_address_nv (op0, imode, 0); + im = adjust_address_nv (op0, imode, GET_MODE_SIZE (imode)); + } else - { - enum machine_mode imode = GET_MODE_INNER (mode); - rtx re, im; - - if (MEM_P (op0)) - { - re = adjust_address_nv (op0, imode, 0); - im = adjust_address_nv (op0, imode, GET_MODE_SIZE (imode)); - } - else - { - enum machine_mode ifmode = int_mode_for_mode (mode); - enum machine_mode ihmode = int_mode_for_mode (imode); - rtx halfsize; - if (ifmode == BLKmode || ihmode == BLKmode) - return NULL; - halfsize = GEN_INT (GET_MODE_BITSIZE (ihmode)); - re = op0; - if (mode != ifmode) - re = gen_rtx_SUBREG (ifmode, re, 0); - re = gen_rtx_ZERO_EXTRACT (ihmode, re, halfsize, const0_rtx); - if (imode != ihmode) - re = gen_rtx_SUBREG (imode, re, 0); - im = copy_rtx (op0); - if (mode != ifmode) - im = gen_rtx_SUBREG (ifmode, im, 0); - im = gen_rtx_ZERO_EXTRACT (ihmode, im, halfsize, halfsize); - if (imode != ihmode) - im = gen_rtx_SUBREG (imode, im, 0); - } - im = gen_rtx_NEG (imode, im); - return gen_rtx_CONCAT (mode, re, im); - } + { + enum machine_mode ifmode = int_mode_for_mode (mode); + enum machine_mode ihmode = int_mode_for_mode (imode); + rtx halfsize; + if (ifmode == BLKmode || ihmode == BLKmode) + return NULL; + halfsize = GEN_INT (GET_MODE_BITSIZE (ihmode)); + re = op0; + if (mode != ifmode) + re = gen_rtx_SUBREG (ifmode, re, 0); + re = gen_rtx_ZERO_EXTRACT (ihmode, re, halfsize, const0_rtx); + if (imode != ihmode) + re = gen_rtx_SUBREG (imode, re, 0); + im = copy_rtx (op0); + if (mode != ifmode) + im = gen_rtx_SUBREG (ifmode, im, 0); + im = gen_rtx_ZERO_EXTRACT (ihmode, im, halfsize, halfsize); + if (imode != ihmode) + im = gen_rtx_SUBREG (imode, im, 0); + } + im = gen_rtx_NEG (imode, im); + return gen_rtx_CONCAT (mode, re, im); + } case ADDR_EXPR: op0 = expand_debug_expr (TREE_OPERAND (exp, 0)); @@ -3116,7 +3119,7 @@ case VECTOR_CST: exp = build_constructor_from_list (TREE_TYPE (exp), - TREE_VECTOR_CST_ELTS (exp)); + TREE_VECTOR_CST_ELTS (exp)); /* Fall through. */ case CONSTRUCTOR: @@ -3151,7 +3154,7 @@ return op0; } else - goto flag_unsupported; + goto flag_unsupported; case CALL_EXPR: /* ??? Maybe handle some builtins? */ @@ -3300,33 +3303,33 @@ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (DEBUG_INSN_P (insn)) { - tree value = (tree)INSN_VAR_LOCATION_LOC (insn); - rtx val; - enum machine_mode mode; - - if (value == NULL_TREE) - val = NULL_RTX; - else - { - val = expand_debug_expr (value); - gcc_assert (last == get_last_insn ()); - } - - if (!val) - val = gen_rtx_UNKNOWN_VAR_LOC (); - else - { - mode = GET_MODE (INSN_VAR_LOCATION (insn)); - - gcc_assert (mode == GET_MODE (val) - || (GET_MODE (val) == VOIDmode - && (CONST_INT_P (val) - || GET_CODE (val) == CONST_FIXED - || GET_CODE (val) == CONST_DOUBLE - || GET_CODE (val) == LABEL_REF))); - } - - INSN_VAR_LOCATION_LOC (insn) = val; + tree value = (tree)INSN_VAR_LOCATION_LOC (insn); + rtx val; + enum machine_mode mode; + + if (value == NULL_TREE) + val = NULL_RTX; + else + { + val = expand_debug_expr (value); + gcc_assert (last == get_last_insn ()); + } + + if (!val) + val = gen_rtx_UNKNOWN_VAR_LOC (); + else + { + mode = GET_MODE (INSN_VAR_LOCATION (insn)); + + gcc_assert (mode == GET_MODE (val) + || (GET_MODE (val) == VOIDmode + && (CONST_INT_P (val) + || GET_CODE (val) == CONST_FIXED + || GET_CODE (val) == CONST_DOUBLE + || GET_CODE (val) == LABEL_REF))); + } + + INSN_VAR_LOCATION_LOC (insn) = val; } flag_strict_aliasing = save_strict_alias; @@ -3347,7 +3350,7 @@ if (dump_file) fprintf (dump_file, "\n;; Generating RTL for gimple basic block %d\n", - bb->index); + bb->index); /* Note that since we are now transitioning from GIMPLE to RTL, we cannot use the gsi_*_bb() routines because they expect the basic @@ -3371,11 +3374,11 @@ gcc_assert (single_succ (bb) == EXIT_BLOCK_PTR); if (bb->next_bb == EXIT_BLOCK_PTR - && !gimple_return_retval (ret_stmt)) - { - gsi_remove (&gsi, false); - single_succ_edge (bb)->flags |= EDGE_FALLTHRU; - } + && !gimple_return_retval (ret_stmt)) + { + gsi_remove (&gsi, false); + single_succ_edge (bb)->flags |= EDGE_FALLTHRU; + } } gsi = gsi_start (stmts); @@ -3383,7 +3386,7 @@ { stmt = gsi_stmt (gsi); if (gimple_code (stmt) != GIMPLE_LABEL) - stmt = NULL; + stmt = NULL; } elt = pointer_map_contains (lab_rtx_for_bb, bb); @@ -3393,19 +3396,19 @@ last = get_last_insn (); if (stmt) - { - expand_gimple_stmt (stmt); - gsi_next (&gsi); - } + { + expand_gimple_stmt (stmt); + gsi_next (&gsi); + } if (elt) - emit_label ((rtx) *elt); + emit_label ((rtx) *elt); /* Java emits line number notes in the top of labels. - ??? Make this go away once line number notes are obsoleted. */ + ??? Make this go away once line number notes are obsoleted. */ BB_HEAD (bb) = NEXT_INSN (last); if (NOTE_P (BB_HEAD (bb))) - BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb)); + BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb)); note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb)); maybe_dump_rtl_for_gimple_stmt (stmt, last); @@ -3522,13 +3525,13 @@ currently_expanding_gimple_stmt = stmt; /* Expand this statement, then evaluate the resulting RTL and - fixup the CFG accordingly. */ + fixup the CFG accordingly. */ if (gimple_code (stmt) == GIMPLE_COND) - { - new_bb = expand_gimple_cond (bb, stmt); - if (new_bb) - return new_bb; - } + { + new_bb = expand_gimple_cond (bb, stmt); + if (new_bb) + return new_bb; + } else if (gimple_debug_bind_p (stmt)) { location_t sloc = get_curr_insn_source_location (); @@ -3591,37 +3594,37 @@ set_curr_insn_block (sblock); } else - { - if (is_gimple_call (stmt) && gimple_call_tail_p (stmt)) - { - bool can_fallthru; - new_bb = expand_gimple_tailcall (bb, stmt, &can_fallthru); - if (new_bb) - { - if (can_fallthru) - bb = new_bb; - else - return new_bb; - } - } - else - { - def_operand_p def_p; - def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); - - if (def_p != NULL) - { - /* Ignore this stmt if it is in the list of - replaceable expressions. */ - if (SA.values - && bitmap_bit_p (SA.values, - SSA_NAME_VERSION (DEF_FROM_PTR (def_p)))) - continue; - } - last = expand_gimple_stmt (stmt); - maybe_dump_rtl_for_gimple_stmt (stmt, last); - } - } + { + if (is_gimple_call (stmt) && gimple_call_tail_p (stmt)) + { + bool can_fallthru; + new_bb = expand_gimple_tailcall (bb, stmt, &can_fallthru); + if (new_bb) + { + if (can_fallthru) + bb = new_bb; + else + return new_bb; + } + } + else + { + def_operand_p def_p; + def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); + + if (def_p != NULL) + { + /* Ignore this stmt if it is in the list of + replaceable expressions. */ + if (SA.values + && bitmap_bit_p (SA.values, + SSA_NAME_VERSION (DEF_FROM_PTR (def_p)))) + continue; + } + last = expand_gimple_stmt (stmt); + maybe_dump_rtl_for_gimple_stmt (stmt, last); + } + } } currently_expanding_gimple_stmt = NULL; @@ -3630,17 +3633,17 @@ FOR_EACH_EDGE (e, ei, bb->succs) { if (e->goto_locus && e->goto_block) - { - set_curr_insn_source_location (e->goto_locus); - set_curr_insn_block (e->goto_block); - e->goto_locus = curr_insn_locator (); - } + { + set_curr_insn_source_location (e->goto_locus); + set_curr_insn_block (e->goto_block); + e->goto_locus = curr_insn_locator (); + } e->goto_block = NULL; if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb) - { - emit_jump (label_rtx_for_bb (e->dest)); - e->flags &= ~EDGE_FALLTHRU; - } + { + emit_jump (label_rtx_for_bb (e->dest)); + e->flags &= ~EDGE_FALLTHRU; + } } /* Expanded RTL can create a jump in the last instruction of block. @@ -3703,8 +3706,8 @@ flags = EDGE_FALLTHRU; init_block = create_basic_block (NEXT_INSN (get_insns ()), - get_last_insn (), - ENTRY_BLOCK_PTR); + get_last_insn (), + ENTRY_BLOCK_PTR); init_block->frequency = ENTRY_BLOCK_PTR->frequency; init_block->count = ENTRY_BLOCK_PTR->count; if (e) @@ -3771,7 +3774,7 @@ while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head))) head = NEXT_INSN (head); exit_block = create_basic_block (NEXT_INSN (head), end, - EXIT_BLOCK_PTR->prev_bb); + EXIT_BLOCK_PTR->prev_bb); exit_block->frequency = EXIT_BLOCK_PTR->frequency; exit_block->count = EXIT_BLOCK_PTR->count; @@ -3780,9 +3783,9 @@ { e = EDGE_PRED (EXIT_BLOCK_PTR, ix); if (!(e->flags & EDGE_ABNORMAL)) - redirect_edge_succ (e, exit_block); + redirect_edge_succ (e, exit_block); else - ix++; + ix++; } e = make_edge (exit_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU); @@ -3791,9 +3794,9 @@ FOR_EACH_EDGE (e2, ei, EXIT_BLOCK_PTR->preds) if (e2 != e) { - e->count -= e2->count; - exit_block->count -= e2->count; - exit_block->frequency -= EDGE_FREQUENCY (e2); + e->count -= e2->count; + exit_block->count -= e2->count; + exit_block->frequency -= EDGE_FREQUENCY (e2); } if (e->count < 0) e->count = 0; @@ -3810,7 +3813,7 @@ static tree discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees, - void *data ATTRIBUTE_UNUSED) + void *data ATTRIBUTE_UNUSED) { tree t = *tp; @@ -3819,26 +3822,26 @@ else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) { while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) - && is_gimple_min_invariant (TREE_OPERAND (t, 1)) - && (!TREE_OPERAND (t, 2) - || is_gimple_min_invariant (TREE_OPERAND (t, 2)))) - || (TREE_CODE (t) == COMPONENT_REF - && (!TREE_OPERAND (t,2) - || is_gimple_min_invariant (TREE_OPERAND (t, 2)))) - || TREE_CODE (t) == BIT_FIELD_REF - || TREE_CODE (t) == REALPART_EXPR - || TREE_CODE (t) == IMAGPART_EXPR - || TREE_CODE (t) == VIEW_CONVERT_EXPR - || CONVERT_EXPR_P (t)) - t = TREE_OPERAND (t, 0); + && is_gimple_min_invariant (TREE_OPERAND (t, 1)) + && (!TREE_OPERAND (t, 2) + || is_gimple_min_invariant (TREE_OPERAND (t, 2)))) + || (TREE_CODE (t) == COMPONENT_REF + && (!TREE_OPERAND (t,2) + || is_gimple_min_invariant (TREE_OPERAND (t, 2)))) + || TREE_CODE (t) == BIT_FIELD_REF + || TREE_CODE (t) == REALPART_EXPR + || TREE_CODE (t) == IMAGPART_EXPR + || TREE_CODE (t) == VIEW_CONVERT_EXPR + || CONVERT_EXPR_P (t)) + t = TREE_OPERAND (t, 0); if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) - { - t = get_base_address (t); - if (t && DECL_P (t) + { + t = get_base_address (t); + if (t && DECL_P (t) && DECL_MODE (t) != BLKmode) - TREE_ADDRESSABLE (t) = 1; - } + TREE_ADDRESSABLE (t) = 1; + } *walk_subtrees = 0; } @@ -3912,7 +3915,7 @@ crtl->stack_alignment_needed = preferred_stack_boundary; gcc_assert (crtl->stack_alignment_needed - <= crtl->stack_alignment_estimated); + <= crtl->stack_alignment_estimated); crtl->stack_realign_needed = INCOMING_STACK_BOUNDARY < crtl->stack_alignment_estimated; @@ -3962,7 +3965,7 @@ rewrite_out_of_ssa (&SA); timevar_pop (TV_OUT_OF_SSA); SA.partition_to_pseudo = (rtx *)xcalloc (SA.map->num_partitions, - sizeof (rtx)); + sizeof (rtx)); /* Some backends want to know that we are expanding to RTL. */ currently_expanding_to_rtl = 1; @@ -4053,26 +4056,26 @@ tree var = SSA_NAME_VAR (partition_to_var (SA.map, i)); if (TREE_CODE (var) != VAR_DECL - && !SA.partition_to_pseudo[i]) - SA.partition_to_pseudo[i] = DECL_RTL_IF_SET (var); + && !SA.partition_to_pseudo[i]) + SA.partition_to_pseudo[i] = DECL_RTL_IF_SET (var); gcc_assert (SA.partition_to_pseudo[i]); /* If this decl was marked as living in multiple places, reset this now to NULL. */ if (DECL_RTL_IF_SET (var) == pc_rtx) - SET_DECL_RTL (var, NULL); + SET_DECL_RTL (var, NULL); /* Some RTL parts really want to look at DECL_RTL(x) when x was a decl marked in REG_ATTR or MEM_ATTR. We could use - SET_DECL_RTL here making this available, but that would mean - to select one of the potentially many RTLs for one DECL. Instead - of doing that we simply reset the MEM_EXPR of the RTL in question, - then nobody can get at it and hence nobody can call DECL_RTL on it. */ + SET_DECL_RTL here making this available, but that would mean + to select one of the potentially many RTLs for one DECL. Instead + of doing that we simply reset the MEM_EXPR of the RTL in question, + then nobody can get at it and hence nobody can call DECL_RTL on it. */ if (!DECL_RTL_SET_P (var)) - { - if (MEM_P (SA.partition_to_pseudo[i])) - set_mem_expr (SA.partition_to_pseudo[i], NULL); - } + { + if (MEM_P (SA.partition_to_pseudo[i])) + set_mem_expr (SA.partition_to_pseudo[i], NULL); + } } /* If this function is `main', emit a call to `__main' @@ -4162,20 +4165,20 @@ edge e; edge_iterator ei; for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) - { - /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */ - e->flags &= ~EDGE_EXECUTABLE; - - /* At the moment not all abnormal edges match the RTL - representation. It is safe to remove them here as - find_many_sub_basic_blocks will rediscover them. - In the future we should get this fixed properly. */ - if ((e->flags & EDGE_ABNORMAL) - && !(e->flags & EDGE_SIBCALL)) - remove_edge (e); - else - ei_next (&ei); - } + { + /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */ + e->flags &= ~EDGE_EXECUTABLE; + + /* At the moment not all abnormal edges match the RTL + representation. It is safe to remove them here as + find_many_sub_basic_blocks will rediscover them. + In the future we should get this fixed properly. */ + if ((e->flags & EDGE_ABNORMAL) + && !(e->flags & EDGE_SIBCALL)) + remove_edge (e); + else + ei_next (&ei); + } } blocks = sbitmap_alloc (last_basic_block); @@ -4203,7 +4206,7 @@ if (dump_file) { fprintf (dump_file, - "\n\n;;\n;; Full RTL generated for this function:\n;;\n"); + "\n\n;;\n;; Full RTL generated for this function:\n;;\n"); /* And the pass manager will dump RTL for us. */ } @@ -4212,10 +4215,10 @@ { tree parent; for (parent = DECL_CONTEXT (current_function_decl); - parent != NULL_TREE; - parent = get_containing_scope (parent)) + parent != NULL_TREE; + parent = get_containing_scope (parent)) if (TREE_CODE (parent) == FUNCTION_DECL) - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1; + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1; } /* We are now committed to emitting code for this function. Do any @@ -4241,9 +4244,9 @@ { { RTL_PASS, - "expand", /* name */ + "expand", /* name */ NULL, /* gate */ - gimple_expand_cfg, /* execute */ + gimple_expand_cfg, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ @@ -4251,10 +4254,10 @@ PROP_ssa | PROP_gimple_leh | PROP_cfg | PROP_gimple_lcx, /* properties_required */ PROP_rtl, /* properties_provided */ - PROP_ssa | PROP_trees, /* properties_destroyed */ + PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow - | TODO_verify_stmts, /* todo_flags_start */ + | TODO_verify_stmts, /* todo_flags_start */ TODO_dump_func - | TODO_ggc_collect /* todo_flags_finish */ + | TODO_ggc_collect /* todo_flags_finish */ } }; diff -r 561a7518be6b -r 1b10fe6932e1 gcc/config.in diff -r 561a7518be6b -r 1b10fe6932e1 gcc/config/i386/i386.c --- a/gcc/config/i386/i386.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/i386/i386.c Sun Aug 21 07:53:12 2011 +0900 @@ -21855,6 +21855,18 @@ fnaddr = gen_rtx_MEM (QImode, fnaddr); } +#ifndef noCbC + if (pop + && sibcall + && !( GET_CODE (fnaddr) == MEM + && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF) ) + { + rtx eax = gen_rtx_REG (Pmode, AX_REG); + eax = copy_to_suggested_reg (XEXP (fnaddr, 0), eax, Pmode); + fnaddr = gen_rtx_MEM (QImode, eax); + } +#endif + call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1); if (retval) call = gen_rtx_SET (VOIDmode, retval, call); diff -r 561a7518be6b -r 1b10fe6932e1 gcc/config/i386/i386.md --- a/gcc/config/i386/i386.md Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/i386/i386.md Sun Aug 21 07:53:12 2011 +0900 @@ -11579,6 +11579,21 @@ DONE; }) +(define_expand "sibcall_value_pop" + [(parallel [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "" "") + (match_operand:SI 2 "" ""))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 4 "" "")))])] + "!TARGET_64BIT" +{ + ix86_expand_call (operands[0], operands[1], operands[2], + operands[3], operands[4], 1); + DONE; +}) + + ;; Call subroutine returning any type. (define_expand "untyped_call" diff -r 561a7518be6b -r 1b10fe6932e1 gcc/config/rs6000/rs6000.md --- a/gcc/config/rs6000/rs6000.md Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/rs6000/rs6000.md Sun Aug 21 07:53:12 2011 +0900 @@ -13023,6 +13023,35 @@ [(set_attr "type" "branch,branch") (set_attr "length" "4,8")]) + +;; added by kent. +;; for indirect sibcalls of Continuation based C. +;; this is based on call_indirect_nonlocal_sysv" +(define_insn "*sibcall_indirect_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) + (match_operand 1 "" "g,g,g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) + (use (reg:SI LR_REGNO)) + (return)] + "DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN" +{ + /* + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + */ + + return "b%T0"; +} + [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") + (set_attr "length" "4,4,8,8")]) + + + + (define_expand "sibcall_value" [(parallel [(set (match_operand 0 "register_operand" "") (call (mem:SI (match_operand 1 "address_operand" "")) diff -r 561a7518be6b -r 1b10fe6932e1 gcc/configure diff -r 561a7518be6b -r 1b10fe6932e1 gcc/configure.ac --- a/gcc/configure.ac Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/configure.ac Sun Aug 21 07:53:12 2011 +0900 @@ -413,6 +413,7 @@ rtlflag) ac_rtlflag_checking=1 ;; runtime) ac_runtime_checking=1 ;; tree) ac_tree_checking=1 ;; + macrofunc) ac_macrofunc_checking=1 ;; types) ac_types_checking=1 ;; valgrind) ac_valgrind_checking=1 ;; *) AC_MSG_ERROR(unknown check category $check) ;; @@ -456,6 +457,12 @@ ]) TREEBROWSER=tree-browser.o fi +if test x$ac_macrofunc_checking != x ; then + AC_DEFINE(ENABLE_TREE_CHECKING, 1, +[Define if you want all operations on trees (the basic data + ]) + MACROFUNC=cbc-tree-debug.o +fi if test x$ac_types_checking != x ; then AC_DEFINE(ENABLE_TYPES_CHECKING, 1, [Define if you want all gimple types to be verified after gimplifiation. @@ -463,6 +470,7 @@ ]) fi AC_SUBST(TREEBROWSER) +AC_SUBST(MACROFUNC) if test x$ac_rtl_checking != x ; then AC_DEFINE(ENABLE_RTL_CHECKING, 1, [Define if you want all operations on RTL (the basic data structure diff -r 561a7518be6b -r 1b10fe6932e1 gcc/function.c --- a/gcc/function.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/function.c Sun Aug 21 07:53:12 2011 +0900 @@ -3480,6 +3480,11 @@ SET_DECL_RTL (result, x); } +#ifndef noCbC + //if (CbC_IS_CODE_SEGMENT(TREE_TYPE(fndecl)) ) + //all.stack_args_size.constant = CbC_STACK_SIZE; +#endif + /* We have aligned all the args, so add space for the pretend args. */ crtl->args.pretend_args_size = all.pretend_args_size; all.stack_args_size.constant += all.extra_pretend_bytes; diff -r 561a7518be6b -r 1b10fe6932e1 gcc/gcc.c --- a/gcc/gcc.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/gcc.c Sun Aug 21 07:53:12 2011 +0900 @@ -914,6 +914,9 @@ {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0}, {".go", "#Go", 0, 1, 0}, /* Next come the entries for C. */ +#ifndef noCbC + {".cbc", "@c", 0, 1, 1}, +#endif {".c", "@c", 0, 0, 1}, {"@c", /* cc1 has an integrated ISO C preprocessor. We should invoke the diff -r 561a7518be6b -r 1b10fe6932e1 gcc/gimple.c --- a/gcc/gimple.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/gimple.c Sun Aug 21 07:53:12 2011 +0900 @@ -33,6 +33,9 @@ #include "tree-flow.h" #include "value-prof.h" #include "flags.h" +#ifndef noCbC +#include "cbc-tree.h" +#endif #include "alias.h" #include "demangle.h" #include "langhooks.h" @@ -60,7 +63,7 @@ operands vector the size of the structure minus the size of the 1 element tree array at the end (see gimple_ops). */ #define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) \ - (HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0), + (HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0), EXPORTED_CONST size_t gimple_ops_offset_[] = { #include "gsstruct.def" }; @@ -72,13 +75,13 @@ }; #undef DEFGSSTRUCT -#define DEFGSCODE(SYM, NAME, GSSCODE) NAME, +#define DEFGSCODE(SYM, NAME, GSSCODE) NAME, const char *const gimple_code_name[] = { #include "gimple.def" }; #undef DEFGSCODE -#define DEFGSCODE(SYM, NAME, GSSCODE) GSSCODE, +#define DEFGSCODE(SYM, NAME, GSSCODE) GSSCODE, EXPORTED_CONST enum gimple_statement_structure_enum gss_for_code_[] = { #include "gimple.def" }; @@ -185,7 +188,7 @@ static gimple gimple_build_with_ops_stat (enum gimple_code code, unsigned subcode, - unsigned num_ops MEM_STAT_DECL) + unsigned num_ops MEM_STAT_DECL) { gimple s = gimple_alloc_stat (code, num_ops PASS_MEM_STAT); gimple_set_subcode (s, subcode); @@ -304,6 +307,9 @@ gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t)); gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t)); gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); +#ifndef noCbC + gimple_call_set_cbc_goto (call, CALL_EXPR_CbC_GOTO (t)); +#endif gimple_call_set_nothrow (call, TREE_NOTHROW (t)); gimple_set_no_warning (call, TREE_NO_WARNING (t)); @@ -385,7 +391,7 @@ num_ops = get_gimple_rhs_num_ops (subcode) + 1; p = gimple_build_with_ops_stat (GIMPLE_ASSIGN, (unsigned)subcode, num_ops - PASS_MEM_STAT); + PASS_MEM_STAT); gimple_assign_set_lhs (p, lhs); gimple_assign_set_rhs1 (p, op1); if (op2) @@ -430,7 +436,7 @@ gimple gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs, - tree t_label, tree f_label) + tree t_label, tree f_label) { gimple p; @@ -451,9 +457,9 @@ tree *lhs_p, tree *rhs_p) { gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison - || TREE_CODE (cond) == TRUTH_NOT_EXPR - || is_gimple_min_invariant (cond) - || SSA_VAR_P (cond)); + || TREE_CODE (cond) == TRUTH_NOT_EXPR + || is_gimple_min_invariant (cond) + || SSA_VAR_P (cond)); extract_ops_from_tree (cond, code_p, lhs_p, rhs_p); @@ -566,7 +572,7 @@ gcc_assert (nlabels == 0 || noutputs == 0); p = gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK, - ninputs + noutputs + nclobbers + nlabels); + ninputs + noutputs + nclobbers + nlabels); p->gimple_asm.ni = ninputs; p->gimple_asm.no = noutputs; @@ -595,7 +601,7 @@ gimple gimple_build_asm_vec (const char *string, VEC(tree,gc)* inputs, VEC(tree,gc)* outputs, VEC(tree,gc)* clobbers, - VEC(tree,gc)* labels) + VEC(tree,gc)* labels) { gimple p; unsigned i; @@ -604,7 +610,7 @@ VEC_length (tree, inputs), VEC_length (tree, outputs), VEC_length (tree, clobbers), - VEC_length (tree, labels)); + VEC_length (tree, labels)); for (i = 0; i < VEC_length (tree, inputs); i++) gimple_asm_set_input_op (p, i, VEC_index (tree, inputs, i)); @@ -676,7 +682,7 @@ gimple gimple_build_try (gimple_seq eval, gimple_seq cleanup, - enum gimple_try_flags kind) + enum gimple_try_flags kind) { gimple p; @@ -727,7 +733,7 @@ { /* nlabels + 1 default label + 1 index. */ gimple p = gimple_build_with_ops (GIMPLE_SWITCH, ERROR_MARK, - 1 + (default_label != NULL) + nlabels); + 1 + (default_label != NULL) + nlabels); gimple_switch_set_index (p, index); if (default_label) gimple_switch_set_default_label (p, default_label); @@ -797,8 +803,8 @@ gimple_build_debug_bind_stat (tree var, tree value, gimple stmt MEM_STAT_DECL) { gimple p = gimple_build_with_ops_stat (GIMPLE_DEBUG, - (unsigned)GIMPLE_DEBUG_BIND, 2 - PASS_MEM_STAT); + (unsigned)GIMPLE_DEBUG_BIND, 2 + PASS_MEM_STAT); gimple_debug_bind_set_var (p, var); gimple_debug_bind_set_value (p, value); @@ -838,7 +844,7 @@ gimple gimple_build_omp_for (gimple_seq body, tree clauses, size_t collapse, - gimple_seq pre_body) + gimple_seq pre_body) { gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0); if (body) @@ -863,7 +869,7 @@ gimple gimple_build_omp_parallel (gimple_seq body, tree clauses, tree child_fn, - tree data_arg) + tree data_arg) { gimple p = gimple_alloc (GIMPLE_OMP_PARALLEL, 0); if (body) @@ -887,8 +893,8 @@ gimple gimple_build_omp_task (gimple_seq body, tree clauses, tree child_fn, - tree data_arg, tree copy_fn, tree arg_size, - tree arg_align) + tree data_arg, tree copy_fn, tree arg_size, + tree arg_align) { gimple p = gimple_alloc (GIMPLE_OMP_TASK, 0); if (body) @@ -1065,17 +1071,17 @@ void gimple_check_failed (const_gimple gs, const char *file, int line, - const char *function, enum gimple_code code, - enum tree_code subcode) + const char *function, enum gimple_code code, + enum tree_code subcode) { internal_error ("gimple check: expected %s(%s), have %s(%s) in %s, at %s:%d", - gimple_code_name[code], - tree_code_name[subcode], - gimple_code_name[gimple_code (gs)], - gs->gsbase.subcode > 0 - ? tree_code_name[gs->gsbase.subcode] - : "", - function, trim_filename (file), line); + gimple_code_name[code], + tree_code_name[subcode], + gimple_code_name[gimple_code (gs)], + gs->gsbase.subcode > 0 + ? tree_code_name[gs->gsbase.subcode] + : "", + function, trim_filename (file), line); } #endif /* ENABLE_GIMPLE_CHECKING */ @@ -1190,7 +1196,7 @@ return true; for (i = gsi_start (body); !gsi_end_p (i); gsi_next (&i)) if (!empty_stmt_p (gsi_stmt (i)) - && !is_gimple_debug (gsi_stmt (i))) + && !is_gimple_debug (gsi_stmt (i))) return false; return true; @@ -1227,7 +1233,7 @@ gimple walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt, - walk_tree_fn callback_op, struct walk_stmt_info *wi) + walk_tree_fn callback_op, struct walk_stmt_info *wi) { gimple_stmt_iterator gsi; @@ -1235,13 +1241,13 @@ { tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi); if (ret) - { - /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist - to hold it. */ - gcc_assert (wi); - wi->callback_result = ret; - return gsi_stmt (gsi); - } + { + /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist + to hold it. */ + gcc_assert (wi); + wi->callback_result = ret; + return gsi_stmt (gsi); + } } if (wi) @@ -1255,7 +1261,7 @@ static tree walk_gimple_asm (gimple stmt, walk_tree_fn callback_op, - struct walk_stmt_info *wi) + struct walk_stmt_info *wi) { tree ret, op; unsigned noutputs; @@ -1276,12 +1282,12 @@ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); oconstraints[i] = constraint; parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg, - &is_inout); + &is_inout); if (wi) - wi->val_only = (allows_reg || !allows_mem); + wi->val_only = (allows_reg || !allows_mem); ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL); if (ret) - return ret; + return ret; } n = gimple_asm_ninputs (stmt); @@ -1290,16 +1296,16 @@ op = gimple_asm_input_op (stmt, i); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); parse_input_constraint (&constraint, 0, 0, noutputs, 0, - oconstraints, &allows_mem, &allows_reg); + oconstraints, &allows_mem, &allows_reg); if (wi) - { - wi->val_only = (allows_reg || !allows_mem); + { + wi->val_only = (allows_reg || !allows_mem); /* Although input "m" is not really a LHS, we need a lvalue. */ - wi->is_lhs = !wi->val_only; - } + wi->is_lhs = !wi->val_only; + } ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL); if (ret) - return ret; + return ret; } if (wi) @@ -1314,7 +1320,7 @@ op = gimple_asm_label_op (stmt, i); ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL); if (ret) - return ret; + return ret; } return NULL_TREE; @@ -1328,7 +1334,7 @@ Additional parameters to walk_tree must be stored in WI. For each operand OP, walk_tree is called as: - walk_tree (&OP, CALLBACK_OP, WI, WI->PSET) + walk_tree (&OP, CALLBACK_OP, WI, WI->PSET) If CALLBACK_OP returns non-NULL for an operand, the remaining operands are not scanned. @@ -1338,7 +1344,7 @@ tree walk_gimple_op (gimple stmt, walk_tree_fn callback_op, - struct walk_stmt_info *wi) + struct walk_stmt_info *wi) { struct pointer_set_t *pset = (wi) ? wi->pset : NULL; unsigned i; @@ -1358,33 +1364,33 @@ } for (i = 1; i < gimple_num_ops (stmt); i++) - { - ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, - pset); - if (ret) - return ret; - } + { + ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, + pset); + if (ret) + return ret; + } /* Walk the LHS. If the RHS is appropriate for a memory, we - may use a COMPONENT_REF on the LHS. */ + may use a COMPONENT_REF on the LHS. */ if (wi) - { + { /* If the RHS has more than 1 operand, it is not appropriate for the memory. */ - wi->val_only = !is_gimple_mem_rhs (gimple_assign_rhs1 (stmt)) + wi->val_only = !is_gimple_mem_rhs (gimple_assign_rhs1 (stmt)) || !gimple_assign_single_p (stmt); - wi->is_lhs = true; - } + wi->is_lhs = true; + } ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset); if (ret) - return ret; + return ret; if (wi) - { - wi->val_only = true; - wi->is_lhs = false; - } + { + wi->val_only = true; + wi->is_lhs = false; + } break; case GIMPLE_CALL: @@ -1434,148 +1440,148 @@ case GIMPLE_CATCH: ret = walk_tree (gimple_catch_types_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; break; case GIMPLE_EH_FILTER: ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; break; case GIMPLE_ASM: ret = walk_gimple_asm (stmt, callback_op, wi); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_CONTINUE: ret = walk_tree (gimple_omp_continue_control_def_ptr (stmt), - callback_op, wi, pset); + callback_op, wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_continue_control_use_ptr (stmt), - callback_op, wi, pset); + callback_op, wi, pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_CRITICAL: ret = walk_tree (gimple_omp_critical_name_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_FOR: ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; for (i = 0; i < gimple_omp_for_collapse (stmt); i++) - { - ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op, - wi, pset); - if (ret) - return ret; - ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op, - wi, pset); - if (ret) - return ret; - ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op, - wi, pset); - if (ret) - return ret; - ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op, - wi, pset); - } + { + ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op, + wi, pset); if (ret) - return ret; + return ret; + ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op, + wi, pset); + if (ret) + return ret; + ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op, + wi, pset); + } + if (ret) + return ret; break; case GIMPLE_OMP_PARALLEL: ret = walk_tree (gimple_omp_parallel_clauses_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_parallel_child_fn_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_parallel_data_arg_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_TASK: ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_SECTIONS: ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_SINGLE: ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_ATOMIC_LOAD: ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt), callback_op, wi, - pset); + pset); if (ret) - return ret; + return ret; break; case GIMPLE_OMP_ATOMIC_STORE: ret = walk_tree (gimple_omp_atomic_store_val_ptr (stmt), callback_op, - wi, pset); + wi, pset); if (ret) - return ret; + return ret; break; /* Tuples that do not have operands. */ @@ -1587,15 +1593,15 @@ default: { - enum gimple_statement_structure_enum gss; - gss = gimple_statement_structure (stmt); - if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS) - for (i = 0; i < gimple_num_ops (stmt); i++) - { - ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset); - if (ret) - return ret; - } + enum gimple_statement_structure_enum gss; + gss = gimple_statement_structure (stmt); + if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS) + for (i = 0; i < gimple_num_ops (stmt); i++) + { + ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset); + if (ret) + return ret; + } } break; } @@ -1621,7 +1627,7 @@ tree walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt, - walk_tree_fn callback_op, struct walk_stmt_info *wi) + walk_tree_fn callback_op, struct walk_stmt_info *wi) { gimple ret; tree tree_ret; @@ -1642,10 +1648,10 @@ bool handled_ops = false; tree_ret = callback_stmt (gsi, &handled_ops, wi); if (handled_ops) - return tree_ret; + return tree_ret; /* If CALLBACK_STMT did not handle operands, it should not have - a value to return. */ + a value to return. */ gcc_assert (tree_ret == NULL); /* Re-read stmt in case the callback changed it. */ @@ -1657,7 +1663,7 @@ { tree_ret = walk_gimple_op (stmt, callback_op, wi); if (tree_ret) - return tree_ret; + return tree_ret; } /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them. */ @@ -1665,42 +1671,42 @@ { case GIMPLE_BIND: ret = walk_gimple_seq (gimple_bind_body (stmt), callback_stmt, - callback_op, wi); + callback_op, wi); if (ret) - return wi->callback_result; + return wi->callback_result; break; case GIMPLE_CATCH: ret = walk_gimple_seq (gimple_catch_handler (stmt), callback_stmt, - callback_op, wi); + callback_op, wi); if (ret) - return wi->callback_result; + return wi->callback_result; break; case GIMPLE_EH_FILTER: ret = walk_gimple_seq (gimple_eh_filter_failure (stmt), callback_stmt, - callback_op, wi); + callback_op, wi); if (ret) - return wi->callback_result; + return wi->callback_result; break; case GIMPLE_TRY: ret = walk_gimple_seq (gimple_try_eval (stmt), callback_stmt, callback_op, - wi); + wi); if (ret) - return wi->callback_result; + return wi->callback_result; ret = walk_gimple_seq (gimple_try_cleanup (stmt), callback_stmt, - callback_op, wi); + callback_op, wi); if (ret) - return wi->callback_result; + return wi->callback_result; break; case GIMPLE_OMP_FOR: ret = walk_gimple_seq (gimple_omp_for_pre_body (stmt), callback_stmt, - callback_op, wi); + callback_op, wi); if (ret) - return wi->callback_result; + return wi->callback_result; /* FALL THROUGH. */ case GIMPLE_OMP_CRITICAL: @@ -1712,16 +1718,16 @@ case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SINGLE: ret = walk_gimple_seq (gimple_omp_body (stmt), callback_stmt, callback_op, - wi); + wi); if (ret) - return wi->callback_result; + return wi->callback_result; break; case GIMPLE_WITH_CLEANUP_EXPR: ret = walk_gimple_seq (gimple_wce_cleanup (stmt), callback_stmt, - callback_op, wi); + callback_op, wi); if (ret) - return wi->callback_result; + return wi->callback_result; break; default: @@ -1742,8 +1748,8 @@ if (fn == NULL) { /* If FNDECL still does not have a function structure associated - with it, then it does not make sense for it to receive a - GIMPLE body. */ + with it, then it does not make sense for it to receive a + GIMPLE body. */ gcc_assert (seq == NULL); } else @@ -1788,9 +1794,9 @@ { t = TREE_TYPE (gimple_call_fn (stmt)); if (t && TREE_CODE (t) == POINTER_TYPE) - flags = flags_from_decl_or_type (TREE_TYPE (t)); + flags = flags_from_decl_or_type (TREE_TYPE (t)); else - flags = 0; + flags = 0; } if (stmt->gsbase.subcode & GF_CALL_NOTHROW) @@ -1938,17 +1944,17 @@ t = gimple_label_label (stmt); uid = LABEL_DECL_UID (t); if (uid == -1) - { - unsigned old_len = VEC_length (basic_block, label_to_block_map); - LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++; - if (old_len <= (unsigned) uid) - { - unsigned new_len = 3 * uid / 2 + 1; - - VEC_safe_grow_cleared (basic_block, gc, label_to_block_map, - new_len); - } - } + { + unsigned old_len = VEC_length (basic_block, label_to_block_map); + LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++; + if (old_len <= (unsigned) uid) + { + unsigned new_len = 3 * uid / 2 + 1; + + VEC_safe_grow_cleared (basic_block, gc, label_to_block_map, + new_len); + } + } VEC_replace (basic_block, label_to_block_map, uid, bb); } @@ -2006,7 +2012,7 @@ stmt = new_stmt; /* The LHS needs to be reset as this also changes the SSA name - on the LHS. */ + on the LHS. */ gimple_assign_set_lhs (stmt, lhs); } @@ -2222,20 +2228,20 @@ if (num_ops > 0) { for (i = 0; i < num_ops; i++) - gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i))); + gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i))); /* Clear out SSA operand vectors on COPY. */ if (gimple_has_ops (stmt)) - { - gimple_set_def_ops (copy, NULL); - gimple_set_use_ops (copy, NULL); - } + { + gimple_set_def_ops (copy, NULL); + gimple_set_use_ops (copy, NULL); + } if (gimple_has_mem_ops (stmt)) - { - gimple_set_vdef (copy, gimple_vdef (stmt)); - gimple_set_vuse (copy, gimple_vuse (stmt)); - } + { + gimple_set_vdef (copy, gimple_vdef (stmt)); + gimple_set_vuse (copy, gimple_vuse (stmt)); + } /* SSA operands need to be updated. */ gimple_set_modified (copy, true); @@ -2256,10 +2262,10 @@ s->gsbase.modified = (unsigned) modifiedp; if (modifiedp - && cfun->gimple_df - && is_gimple_call (s) - && gimple_call_noreturn_p (s)) - VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), s); + && cfun->gimple_df + && is_gimple_call (s) + && gimple_call_noreturn_p (s)) + VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), s); } } @@ -2291,36 +2297,36 @@ if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE))) return true; else if (gimple_call_flags (s) & ECF_LOOPING_CONST_OR_PURE) - /* An infinite loop is considered a side effect. */ - return true; + /* An infinite loop is considered a side effect. */ + return true; if (gimple_call_lhs (s) && TREE_SIDE_EFFECTS (gimple_call_lhs (s))) - { - gcc_assert (gimple_has_volatile_ops (s)); - return true; - } + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } if (TREE_SIDE_EFFECTS (gimple_call_fn (s))) return true; for (i = 0; i < nargs; i++) if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i))) - { - gcc_assert (gimple_has_volatile_ops (s)); - return true; - } + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } return false; } else { for (i = 0; i < gimple_num_ops (s); i++) - if (TREE_SIDE_EFFECTS (gimple_op (s, i))) - { - gcc_assert (gimple_has_volatile_ops (s)); - return true; - } + if (TREE_SIDE_EFFECTS (gimple_op (s, i))) + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } } return false; @@ -2348,10 +2354,10 @@ because we must ignore a volatile LHS. */ if (TREE_SIDE_EFFECTS (gimple_call_fn (s)) || TREE_THIS_VOLATILE (gimple_call_fn (s))) - { - gcc_assert (gimple_has_volatile_ops (s)); - return true; - } + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } for (i = 0; i < nargs; i++) if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i)) @@ -2364,12 +2370,12 @@ { /* Skip the first operand, the LHS. */ for (i = 1; i < gimple_num_ops (s); i++) - if (TREE_SIDE_EFFECTS (gimple_op (s, i)) + if (TREE_SIDE_EFFECTS (gimple_op (s, i)) || TREE_THIS_VOLATILE (gimple_op (s, i))) - { - gcc_assert (gimple_has_volatile_ops (s)); - return true; - } + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } } else if (is_gimple_debug (s)) return false; @@ -2377,12 +2383,12 @@ { /* For statements without an LHS, examine all arguments. */ for (i = 0; i < gimple_num_ops (s); i++) - if (TREE_SIDE_EFFECTS (gimple_op (s, i)) + if (TREE_SIDE_EFFECTS (gimple_op (s, i)) || TREE_THIS_VOLATILE (gimple_op (s, i))) - { - gcc_assert (gimple_has_volatile_ops (s)); - return true; - } + { + gcc_assert (gimple_has_volatile_ops (s)); + return true; + } } return false; @@ -2417,18 +2423,18 @@ t = gimple_call_fndecl (s); /* Assume that calls to weak functions may trap. */ if (!t || !DECL_P (t) || DECL_WEAK (t)) - return true; + return true; return false; case GIMPLE_ASSIGN: t = gimple_expr_type (s); op = gimple_assign_rhs_code (s); if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS) - div = gimple_assign_rhs2 (s); + div = gimple_assign_rhs2 (s); return (operation_could_trap_p (op, FLOAT_TYPE_P (t), - (INTEGRAL_TYPE_P (t) - && TYPE_OVERFLOW_TRAPS (t)), - div)); + (INTEGRAL_TYPE_P (t) + && TYPE_OVERFLOW_TRAPS (t)), + div)); default: break; @@ -2469,7 +2475,7 @@ for (i = 0; i < (int) gimple_alloc_kind_all; ++i) { fprintf (stderr, "%-20s %7d %10d\n", gimple_alloc_kind_names[i], - gimple_alloc_counts[i], gimple_alloc_sizes[i]); + gimple_alloc_counts[i], gimple_alloc_sizes[i]); total_tuples += gimple_alloc_counts[i]; total_bytes += gimple_alloc_sizes[i]; } @@ -2569,10 +2575,10 @@ is_gimple_lvalue (tree t) { return (is_gimple_addressable (t) - || TREE_CODE (t) == WITH_SIZE_EXPR - /* These are complex lvalues, but don't have addresses, so they - go here. */ - || TREE_CODE (t) == BIT_FIELD_REF); + || TREE_CODE (t) == WITH_SIZE_EXPR + /* These are complex lvalues, but don't have addresses, so they + go here. */ + || TREE_CODE (t) == BIT_FIELD_REF); } /* Return true if T is a GIMPLE condition. */ @@ -2581,9 +2587,9 @@ is_gimple_condexpr (tree t) { return (is_gimple_val (t) || (COMPARISON_CLASS_P (t) - && !tree_could_trap_p (t) - && is_gimple_val (TREE_OPERAND (t, 0)) - && is_gimple_val (TREE_OPERAND (t, 1)))); + && !tree_could_trap_p (t) + && is_gimple_val (TREE_OPERAND (t, 0)) + && is_gimple_val (TREE_OPERAND (t, 1)))); } /* Return true if T is something whose address can be taken. */ @@ -2613,9 +2619,9 @@ /* Vector constant constructors are gimple invariant. */ case CONSTRUCTOR: if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - return TREE_CONSTANT (t); + return TREE_CONSTANT (t); else - return false; + return false; default: return false; @@ -2636,9 +2642,9 @@ while (handled_component_p (op)) { if ((TREE_CODE (op) == ARRAY_REF - || TREE_CODE (op) == ARRAY_RANGE_REF) - && !is_gimple_val (TREE_OPERAND (op, 1))) - return false; + || TREE_CODE (op) == ARRAY_RANGE_REF) + && !is_gimple_val (TREE_OPERAND (op, 1))) + return false; op = TREE_OPERAND (op, 0); } @@ -2670,22 +2676,22 @@ while (handled_component_p (op)) { switch (TREE_CODE (op)) - { - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (!is_gimple_constant (TREE_OPERAND (op, 1)) - || TREE_OPERAND (op, 2) != NULL_TREE - || TREE_OPERAND (op, 3) != NULL_TREE) - return NULL; - break; - - case COMPONENT_REF: - if (TREE_OPERAND (op, 2) != NULL_TREE) - return NULL; - break; - - default:; - } + { + case ARRAY_REF: + case ARRAY_RANGE_REF: + if (!is_gimple_constant (TREE_OPERAND (op, 1)) + || TREE_OPERAND (op, 2) != NULL_TREE + || TREE_OPERAND (op, 3) != NULL_TREE) + return NULL; + break; + + case COMPONENT_REF: + if (TREE_OPERAND (op, 2) != NULL_TREE) + return NULL; + break; + + default:; + } op = TREE_OPERAND (op, 0); } @@ -2815,9 +2821,9 @@ is_gimple_variable (tree t) { return (TREE_CODE (t) == VAR_DECL - || TREE_CODE (t) == PARM_DECL - || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == SSA_NAME); + || TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == RESULT_DECL + || TREE_CODE (t) == SSA_NAME); } /* Return true if T is a GIMPLE identifier (something with an address). */ @@ -2826,11 +2832,11 @@ is_gimple_id (tree t) { return (is_gimple_variable (t) - || TREE_CODE (t) == FUNCTION_DECL - || TREE_CODE (t) == LABEL_DECL - || TREE_CODE (t) == CONST_DECL - /* Allow string constants, since they are addressable. */ - || TREE_CODE (t) == STRING_CST); + || TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == LABEL_DECL + || TREE_CODE (t) == CONST_DECL + /* Allow string constants, since they are addressable. */ + || TREE_CODE (t) == STRING_CST); } /* Return true if TYPE is a suitable type for a scalar register variable. */ @@ -3013,21 +3019,21 @@ { case tcc_expression: switch (code) - { - case INIT_EXPR: - case MODIFY_EXPR: - case VA_ARG_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - /* All of these have side-effects, no matter what their - operands are. */ - return; - - default: - break; - } + { + case INIT_EXPR: + case MODIFY_EXPR: + case VA_ARG_EXPR: + case PREDECREMENT_EXPR: + case PREINCREMENT_EXPR: + case POSTDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + /* All of these have side-effects, no matter what their + operands are. */ + return; + + default: + break; + } /* Fall through. */ case tcc_comparison: /* a comparison expression */ @@ -3037,11 +3043,11 @@ case tcc_vl_exp: /* a function call */ TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t); for (i = 0; i < len; ++i) - { - tree op = TREE_OPERAND (t, i); - if (op && TREE_SIDE_EFFECTS (op)) - TREE_SIDE_EFFECTS (t) = 1; - } + { + tree op = TREE_OPERAND (t, i); + if (op && TREE_SIDE_EFFECTS (op)) + TREE_SIDE_EFFECTS (t) = 1; + } break; case tcc_constant: @@ -3071,24 +3077,24 @@ { tree top0 = TREE_OPERAND (t, 0); t = build2 (NE_EXPR, TREE_TYPE (t), - top0, build_int_cst (TREE_TYPE (top0), 0)); + top0, build_int_cst (TREE_TYPE (top0), 0)); } /* For !x use x == 0. */ else if (TREE_CODE (t) == TRUTH_NOT_EXPR) { tree top0 = TREE_OPERAND (t, 0); t = build2 (EQ_EXPR, TREE_TYPE (t), - top0, build_int_cst (TREE_TYPE (top0), 0)); + top0, build_int_cst (TREE_TYPE (top0), 0)); } /* For cmp ? 1 : 0 use cmp. */ else if (TREE_CODE (t) == COND_EXPR - && COMPARISON_CLASS_P (TREE_OPERAND (t, 0)) - && integer_onep (TREE_OPERAND (t, 1)) - && integer_zerop (TREE_OPERAND (t, 2))) + && COMPARISON_CLASS_P (TREE_OPERAND (t, 0)) + && integer_onep (TREE_OPERAND (t, 1)) + && integer_zerop (TREE_OPERAND (t, 2))) { tree top0 = TREE_OPERAND (t, 0); t = build2 (TREE_CODE (top0), TREE_TYPE (t), - TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); + TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); } if (is_gimple_condexpr (t)) @@ -3126,9 +3132,11 @@ gimple_set_location (new_stmt, gimple_location (stmt)); gimple_call_copy_flags (new_stmt, stmt); gimple_call_set_chain (new_stmt, gimple_call_chain (stmt)); +#ifndef noCbC + gimple_call_set_cbc_goto (new_stmt, gimple_call_cbc_goto_p (stmt)); +#endif gimple_set_modified (new_stmt, true); - return new_stmt; } @@ -3166,7 +3174,7 @@ hashval_t val1 = pair->uid1; hashval_t val2 = pair->uid2; return (iterative_hash_hashval_t (val2, val1) - ^ iterative_hash_hashval_t (val1, val2)); + ^ iterative_hash_hashval_t (val1, val2)); } /* Compare two type pairs pointed-to by P1 and P2. */ @@ -3177,7 +3185,7 @@ const struct type_pair_d *pair1 = (const struct type_pair_d *) p1; const struct type_pair_d *pair2 = (const struct type_pair_d *) p2; return ((pair1->uid1 == pair2->uid1 && pair1->uid2 == pair2->uid2) - || (pair1->uid1 == pair2->uid2 && pair1->uid2 == pair2->uid1)); + || (pair1->uid1 == pair2->uid2 && pair1->uid2 == pair2->uid1)); } /* Lookup the pair of types T1 and T2 in *VISITED_P. Insert a new @@ -3283,8 +3291,8 @@ { name1 = DECL_NAME (name1); if (for_completion_p - && !name1) - return false; + && !name1) + return false; } gcc_assert (!name1 || TREE_CODE (name1) == IDENTIFIER_NODE); @@ -3292,8 +3300,8 @@ { name2 = DECL_NAME (name2); if (for_completion_p - && !name2) - return false; + && !name2) + return false; } gcc_assert (!name2 || TREE_CODE (name2) == IDENTIFIER_NODE); @@ -3345,12 +3353,12 @@ unsigned HOST_WIDE_INT bit_offset1, bit_offset2; bit_offset1 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f1)); byte_offset1 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f1)) - + bit_offset1 / BITS_PER_UNIT); + + bit_offset1 / BITS_PER_UNIT); bit_offset2 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f2)); byte_offset2 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f2)) - + bit_offset2 / BITS_PER_UNIT); + + bit_offset2 / BITS_PER_UNIT); if (byte_offset1 != byte_offset2) - return false; + return false; return bit_offset1 % BITS_PER_UNIT == bit_offset2 % BITS_PER_UNIT; } @@ -3445,7 +3453,7 @@ || TREE_CODE (t1) == OFFSET_TYPE) { /* Can't be the same type if they have different alignment, - sign, precision or mode. */ + sign, precision or mode. */ if (TYPE_ALIGN (t1) != TYPE_ALIGN (t2) || TYPE_PRECISION (t1) != TYPE_PRECISION (t2) || TYPE_MODE (t1) != TYPE_MODE (t2) @@ -3686,70 +3694,70 @@ case INTEGER_TYPE: case BOOLEAN_TYPE: { - tree min1 = TYPE_MIN_VALUE (t1); - tree max1 = TYPE_MAX_VALUE (t1); - tree min2 = TYPE_MIN_VALUE (t2); - tree max2 = TYPE_MAX_VALUE (t2); - bool min_equal_p = false; - bool max_equal_p = false; - - /* If either type has a minimum value, the other type must - have the same. */ - if (min1 == NULL_TREE && min2 == NULL_TREE) - min_equal_p = true; - else if (min1 && min2 && operand_equal_p (min1, min2, 0)) - min_equal_p = true; - - /* Likewise, if either type has a maximum value, the other - type must have the same. */ - if (max1 == NULL_TREE && max2 == NULL_TREE) - max_equal_p = true; - else if (max1 && max2 && operand_equal_p (max1, max2, 0)) - max_equal_p = true; - - if (!min_equal_p || !max_equal_p) - goto different_types; - - goto same_types; + tree min1 = TYPE_MIN_VALUE (t1); + tree max1 = TYPE_MAX_VALUE (t1); + tree min2 = TYPE_MIN_VALUE (t2); + tree max2 = TYPE_MAX_VALUE (t2); + bool min_equal_p = false; + bool max_equal_p = false; + + /* If either type has a minimum value, the other type must + have the same. */ + if (min1 == NULL_TREE && min2 == NULL_TREE) + min_equal_p = true; + else if (min1 && min2 && operand_equal_p (min1, min2, 0)) + min_equal_p = true; + + /* Likewise, if either type has a maximum value, the other + type must have the same. */ + if (max1 == NULL_TREE && max2 == NULL_TREE) + max_equal_p = true; + else if (max1 && max2 && operand_equal_p (max1, max2, 0)) + max_equal_p = true; + + if (!min_equal_p || !max_equal_p) + goto different_types; + + goto same_types; } case ENUMERAL_TYPE: { - /* FIXME lto, we cannot check bounds on enumeral types because - different front ends will produce different values. - In C, enumeral types are integers, while in C++ each element - will have its own symbolic value. We should decide how enums - are to be represented in GIMPLE and have each front end lower - to that. */ - tree v1, v2; - - /* For enumeral types, all the values must be the same. */ - if (TYPE_VALUES (t1) == TYPE_VALUES (t2)) - goto same_types; - - for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2); - v1 && v2; - v1 = TREE_CHAIN (v1), v2 = TREE_CHAIN (v2)) - { - tree c1 = TREE_VALUE (v1); - tree c2 = TREE_VALUE (v2); - - if (TREE_CODE (c1) == CONST_DECL) - c1 = DECL_INITIAL (c1); - - if (TREE_CODE (c2) == CONST_DECL) - c2 = DECL_INITIAL (c2); - - if (tree_int_cst_equal (c1, c2) != 1) - goto different_types; - } - - /* If one enumeration has more values than the other, they - are not the same. */ - if (v1 || v2) - goto different_types; - - goto same_types; + /* FIXME lto, we cannot check bounds on enumeral types because + different front ends will produce different values. + In C, enumeral types are integers, while in C++ each element + will have its own symbolic value. We should decide how enums + are to be represented in GIMPLE and have each front end lower + to that. */ + tree v1, v2; + + /* For enumeral types, all the values must be the same. */ + if (TYPE_VALUES (t1) == TYPE_VALUES (t2)) + goto same_types; + + for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2); + v1 && v2; + v1 = TREE_CHAIN (v1), v2 = TREE_CHAIN (v2)) + { + tree c1 = TREE_VALUE (v1); + tree c2 = TREE_VALUE (v2); + + if (TREE_CODE (c1) == CONST_DECL) + c1 = DECL_INITIAL (c1); + + if (TREE_CODE (c2) == CONST_DECL) + c2 = DECL_INITIAL (c2); + + if (tree_int_cst_equal (c1, c2) != 1) + goto different_types; + } + + /* If one enumeration has more values than the other, they + are not the same. */ + if (v1 || v2) + goto different_types; + + goto same_types; } case RECORD_TYPE: @@ -3980,14 +3988,14 @@ sccstack, sccstate, sccstate_obstack, mode); if (!cstate) - cstate = (struct sccs *)* pointer_map_contains (sccstate, t); + cstate = (struct sccs *)* pointer_map_contains (sccstate, t); state->low = MIN (state->low, cstate->low); /* If the type is no longer on the SCC stack and thus is not part of the parents SCC mix in its hash value. Otherwise we will - ignore the type for hashing purposes and return the unaltered - hash value. */ + ignore the type for hashing purposes and return the unaltered + hash value. */ if (!cstate->on_sccstack) - return tem; + return tem; } if (cstate->dfsnum < state->dfsnum && cstate->on_sccstack) @@ -4319,49 +4327,49 @@ gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type)); /* If t is not its main variant then make t unreachable from its - main variant list. Otherwise we'd queue up a lot of duplicates - there. */ + main variant list. Otherwise we'd queue up a lot of duplicates + there. */ if (t != TYPE_MAIN_VARIANT (t)) - { - tree tem = TYPE_MAIN_VARIANT (t); - while (tem && TYPE_NEXT_VARIANT (tem) != t) - tem = TYPE_NEXT_VARIANT (tem); - if (tem) - TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t); - TYPE_NEXT_VARIANT (t) = NULL_TREE; - } + { + tree tem = TYPE_MAIN_VARIANT (t); + while (tem && TYPE_NEXT_VARIANT (tem) != t) + tem = TYPE_NEXT_VARIANT (tem); + if (tem) + TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t); + TYPE_NEXT_VARIANT (t) = NULL_TREE; + } /* If we are a pointer then remove us from the pointer-to or - reference-to chain. Otherwise we'd queue up a lot of duplicates - there. */ + reference-to chain. Otherwise we'd queue up a lot of duplicates + there. */ if (TREE_CODE (t) == POINTER_TYPE) - { - if (TYPE_POINTER_TO (TREE_TYPE (t)) == t) - TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t); - else - { - tree tem = TYPE_POINTER_TO (TREE_TYPE (t)); - while (tem && TYPE_NEXT_PTR_TO (tem) != t) - tem = TYPE_NEXT_PTR_TO (tem); - if (tem) - TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t); - } - TYPE_NEXT_PTR_TO (t) = NULL_TREE; - } + { + if (TYPE_POINTER_TO (TREE_TYPE (t)) == t) + TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t); + else + { + tree tem = TYPE_POINTER_TO (TREE_TYPE (t)); + while (tem && TYPE_NEXT_PTR_TO (tem) != t) + tem = TYPE_NEXT_PTR_TO (tem); + if (tem) + TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t); + } + TYPE_NEXT_PTR_TO (t) = NULL_TREE; + } else if (TREE_CODE (t) == REFERENCE_TYPE) - { - if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t) - TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t); - else - { - tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t)); - while (tem && TYPE_NEXT_REF_TO (tem) != t) - tem = TYPE_NEXT_REF_TO (tem); - if (tem) - TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t); - } - TYPE_NEXT_REF_TO (t) = NULL_TREE; - } + { + if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t) + TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t); + else + { + tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t)); + while (tem && TYPE_NEXT_REF_TO (tem) != t) + tem = TYPE_NEXT_REF_TO (tem); + if (tem) + TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t); + } + TYPE_NEXT_REF_TO (t) = NULL_TREE; + } leader->type = t; leader->leader = new_type; @@ -4464,12 +4472,12 @@ { if (gimple_types) fprintf (stderr, "GIMPLE type table: size %ld, %ld elements, " - "%ld searches, %ld collisions (ratio: %f)\n", - (long) htab_size (gimple_types), - (long) htab_elements (gimple_types), - (long) gimple_types->searches, - (long) gimple_types->collisions, - htab_collisions (gimple_types)); + "%ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (gimple_types), + (long) htab_elements (gimple_types), + (long) gimple_types->searches, + (long) gimple_types->collisions, + htab_collisions (gimple_types)); else fprintf (stderr, "GIMPLE type table is empty\n"); if (type_hash_cache) @@ -4504,12 +4512,12 @@ fprintf (stderr, "GIMPLE canonical type hash table is empty\n"); if (gtc_visited) fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld " - "elements, %ld searches, %ld collisions (ratio: %f)\n", - (long) htab_size (gtc_visited), - (long) htab_elements (gtc_visited), - (long) gtc_visited->searches, - (long) gtc_visited->collisions, - htab_collisions (gtc_visited)); + "elements, %ld searches, %ld collisions (ratio: %f)\n", + (long) htab_size (gtc_visited), + (long) htab_elements (gtc_visited), + (long) gtc_visited->searches, + (long) gtc_visited->collisions, + htab_collisions (gtc_visited)); else fprintf (stderr, "GIMPLE type comparison table is empty\n"); } @@ -4594,53 +4602,53 @@ if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node) return unsignedp ? unsigned_intQI_type_node : intQI_type_node; -#define GIMPLE_FIXED_TYPES(NAME) \ +#define GIMPLE_FIXED_TYPES(NAME) \ if (type1 == short_ ## NAME ## _type_node \ || type1 == unsigned_short_ ## NAME ## _type_node) \ return unsignedp ? unsigned_short_ ## NAME ## _type_node \ - : short_ ## NAME ## _type_node; \ + : short_ ## NAME ## _type_node; \ if (type1 == NAME ## _type_node \ || type1 == unsigned_ ## NAME ## _type_node) \ return unsignedp ? unsigned_ ## NAME ## _type_node \ - : NAME ## _type_node; \ + : NAME ## _type_node; \ if (type1 == long_ ## NAME ## _type_node \ || type1 == unsigned_long_ ## NAME ## _type_node) \ return unsignedp ? unsigned_long_ ## NAME ## _type_node \ - : long_ ## NAME ## _type_node; \ + : long_ ## NAME ## _type_node; \ if (type1 == long_long_ ## NAME ## _type_node \ || type1 == unsigned_long_long_ ## NAME ## _type_node) \ return unsignedp ? unsigned_long_long_ ## NAME ## _type_node \ - : long_long_ ## NAME ## _type_node; + : long_long_ ## NAME ## _type_node; #define GIMPLE_FIXED_MODE_TYPES(NAME) \ if (type1 == NAME ## _type_node \ || type1 == u ## NAME ## _type_node) \ return unsignedp ? u ## NAME ## _type_node \ - : NAME ## _type_node; + : NAME ## _type_node; #define GIMPLE_FIXED_TYPES_SAT(NAME) \ if (type1 == sat_ ## short_ ## NAME ## _type_node \ || type1 == sat_ ## unsigned_short_ ## NAME ## _type_node) \ return unsignedp ? sat_ ## unsigned_short_ ## NAME ## _type_node \ - : sat_ ## short_ ## NAME ## _type_node; \ + : sat_ ## short_ ## NAME ## _type_node; \ if (type1 == sat_ ## NAME ## _type_node \ || type1 == sat_ ## unsigned_ ## NAME ## _type_node) \ return unsignedp ? sat_ ## unsigned_ ## NAME ## _type_node \ - : sat_ ## NAME ## _type_node; \ + : sat_ ## NAME ## _type_node; \ if (type1 == sat_ ## long_ ## NAME ## _type_node \ || type1 == sat_ ## unsigned_long_ ## NAME ## _type_node) \ return unsignedp ? sat_ ## unsigned_long_ ## NAME ## _type_node \ - : sat_ ## long_ ## NAME ## _type_node; \ + : sat_ ## long_ ## NAME ## _type_node; \ if (type1 == sat_ ## long_long_ ## NAME ## _type_node \ || type1 == sat_ ## unsigned_long_long_ ## NAME ## _type_node) \ return unsignedp ? sat_ ## unsigned_long_long_ ## NAME ## _type_node \ - : sat_ ## long_long_ ## NAME ## _type_node; - -#define GIMPLE_FIXED_MODE_TYPES_SAT(NAME) \ + : sat_ ## long_long_ ## NAME ## _type_node; + +#define GIMPLE_FIXED_MODE_TYPES_SAT(NAME) \ if (type1 == sat_ ## NAME ## _type_node \ || type1 == sat_ ## u ## NAME ## _type_node) \ return unsignedp ? sat_ ## u ## NAME ## _type_node \ - : sat_ ## NAME ## _type_node; + : sat_ ## NAME ## _type_node; GIMPLE_FIXED_TYPES (fract); GIMPLE_FIXED_TYPES_SAT (fract); @@ -4678,8 +4686,8 @@ || TYPE_UNSIGNED (type) == unsignedp) return type; -#define TYPE_OK(node) \ - (TYPE_MODE (type) == TYPE_MODE (node) \ +#define TYPE_OK(node) \ + (TYPE_MODE (type) == TYPE_MODE (node) \ && TYPE_PRECISION (type) == TYPE_PRECISION (node)) if (TYPE_OK (signed_char_type_node)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; @@ -4757,7 +4765,7 @@ TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; u = TREE_OPERAND (u, 0)) if (TREE_CODE (u) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) return 0; /* That's all the expressions we handle specially. */ @@ -4780,7 +4788,7 @@ /* t1 == t can happen for boolean nodes which are always unsigned. */ if (t1 != t) - return get_alias_set (t1); + return get_alias_set (t1); } return -1; @@ -4817,9 +4825,9 @@ if (TREE_CODE (*tp) == MEM_REF && TREE_OPERAND (*tp, 0) == count_p->ptr) { if (wi_p->is_lhs) - count_p->num_stores++; + count_p->num_stores++; else - count_p->num_loads++; + count_p->num_loads++; } return NULL_TREE; @@ -4833,7 +4841,7 @@ void count_uses_and_derefs (tree ptr, gimple stmt, unsigned *num_uses_p, - unsigned *num_loads_p, unsigned *num_stores_p) + unsigned *num_loads_p, unsigned *num_stores_p) { ssa_op_iter i; tree use; @@ -4902,9 +4910,9 @@ bool walk_stmt_load_store_addr_ops (gimple stmt, void *data, - bool (*visit_load)(gimple, tree, void *), - bool (*visit_store)(gimple, tree, void *), - bool (*visit_addr)(gimple, tree, void *)) + bool (*visit_load)(gimple, tree, void *), + bool (*visit_store)(gimple, tree, void *), + bool (*visit_addr)(gimple, tree, void *)) { bool ret = false; unsigned i; @@ -4912,14 +4920,14 @@ { tree lhs, rhs; if (visit_store) - { - lhs = get_base_loadstore (gimple_assign_lhs (stmt)); - if (lhs) - ret |= visit_store (stmt, lhs, data); - } + { + lhs = get_base_loadstore (gimple_assign_lhs (stmt)); + if (lhs) + ret |= visit_store (stmt, lhs, data); + } rhs = gimple_assign_rhs1 (stmt); while (handled_component_p (rhs)) - rhs = TREE_OPERAND (rhs, 0); + rhs = TREE_OPERAND (rhs, 0); if (visit_addr) { if (TREE_CODE (rhs) == ADDR_EXPR) @@ -4935,59 +4943,59 @@ if (TREE_CODE (lhs) == TARGET_MEM_REF && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR) ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data); - } + } if (visit_load) - { - rhs = get_base_loadstore (rhs); - if (rhs) - ret |= visit_load (stmt, rhs, data); - } + { + rhs = get_base_loadstore (rhs); + if (rhs) + ret |= visit_load (stmt, rhs, data); + } } else if (visit_addr - && (is_gimple_assign (stmt) - || gimple_code (stmt) == GIMPLE_COND)) + && (is_gimple_assign (stmt) + || gimple_code (stmt) == GIMPLE_COND)) { for (i = 0; i < gimple_num_ops (stmt); ++i) - if (gimple_op (stmt, i) - && TREE_CODE (gimple_op (stmt, i)) == ADDR_EXPR) - ret |= visit_addr (stmt, TREE_OPERAND (gimple_op (stmt, i), 0), data); + if (gimple_op (stmt, i) + && TREE_CODE (gimple_op (stmt, i)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (gimple_op (stmt, i), 0), data); } else if (is_gimple_call (stmt)) { if (visit_store) - { - tree lhs = gimple_call_lhs (stmt); - if (lhs) - { - lhs = get_base_loadstore (lhs); - if (lhs) - ret |= visit_store (stmt, lhs, data); - } - } + { + tree lhs = gimple_call_lhs (stmt); + if (lhs) + { + lhs = get_base_loadstore (lhs); + if (lhs) + ret |= visit_store (stmt, lhs, data); + } + } if (visit_load || visit_addr) - for (i = 0; i < gimple_call_num_args (stmt); ++i) - { - tree rhs = gimple_call_arg (stmt, i); - if (visit_addr - && TREE_CODE (rhs) == ADDR_EXPR) - ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data); - else if (visit_load) - { - rhs = get_base_loadstore (rhs); - if (rhs) - ret |= visit_load (stmt, rhs, data); - } - } + for (i = 0; i < gimple_call_num_args (stmt); ++i) + { + tree rhs = gimple_call_arg (stmt, i); + if (visit_addr + && TREE_CODE (rhs) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data); + else if (visit_load) + { + rhs = get_base_loadstore (rhs); + if (rhs) + ret |= visit_load (stmt, rhs, data); + } + } if (visit_addr - && gimple_call_chain (stmt) - && TREE_CODE (gimple_call_chain (stmt)) == ADDR_EXPR) - ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (stmt), 0), - data); + && gimple_call_chain (stmt) + && TREE_CODE (gimple_call_chain (stmt)) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (stmt), 0), + data); if (visit_addr - && gimple_call_return_slot_opt_p (stmt) - && gimple_call_lhs (stmt) != NULL_TREE - && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt)))) - ret |= visit_addr (stmt, gimple_call_lhs (stmt), data); + && gimple_call_return_slot_opt_p (stmt) + && gimple_call_lhs (stmt) != NULL_TREE + && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt)))) + ret |= visit_addr (stmt, gimple_call_lhs (stmt), data); } else if (gimple_code (stmt) == GIMPLE_ASM) { @@ -4998,77 +5006,77 @@ noutputs = gimple_asm_noutputs (stmt); oconstraints = XALLOCAVEC (const char *, noutputs); if (visit_store || visit_addr) - for (i = 0; i < gimple_asm_noutputs (stmt); ++i) - { - tree link = gimple_asm_output_op (stmt, i); - tree op = get_base_loadstore (TREE_VALUE (link)); - if (op && visit_store) - ret |= visit_store (stmt, op, data); - if (visit_addr) - { - constraint = TREE_STRING_POINTER - (TREE_VALUE (TREE_PURPOSE (link))); - oconstraints[i] = constraint; - parse_output_constraint (&constraint, i, 0, 0, &allows_mem, - &allows_reg, &is_inout); - if (op && !allows_reg && allows_mem) - ret |= visit_addr (stmt, op, data); - } - } + for (i = 0; i < gimple_asm_noutputs (stmt); ++i) + { + tree link = gimple_asm_output_op (stmt, i); + tree op = get_base_loadstore (TREE_VALUE (link)); + if (op && visit_store) + ret |= visit_store (stmt, op, data); + if (visit_addr) + { + constraint = TREE_STRING_POINTER + (TREE_VALUE (TREE_PURPOSE (link))); + oconstraints[i] = constraint; + parse_output_constraint (&constraint, i, 0, 0, &allows_mem, + &allows_reg, &is_inout); + if (op && !allows_reg && allows_mem) + ret |= visit_addr (stmt, op, data); + } + } if (visit_load || visit_addr) - for (i = 0; i < gimple_asm_ninputs (stmt); ++i) - { - tree link = gimple_asm_input_op (stmt, i); - tree op = TREE_VALUE (link); - if (visit_addr - && TREE_CODE (op) == ADDR_EXPR) - ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); - else if (visit_load || visit_addr) - { - op = get_base_loadstore (op); - if (op) - { - if (visit_load) - ret |= visit_load (stmt, op, data); - if (visit_addr) - { - constraint = TREE_STRING_POINTER - (TREE_VALUE (TREE_PURPOSE (link))); - parse_input_constraint (&constraint, 0, 0, noutputs, - 0, oconstraints, - &allows_mem, &allows_reg); - if (!allows_reg && allows_mem) - ret |= visit_addr (stmt, op, data); - } - } - } - } + for (i = 0; i < gimple_asm_ninputs (stmt); ++i) + { + tree link = gimple_asm_input_op (stmt, i); + tree op = TREE_VALUE (link); + if (visit_addr + && TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + else if (visit_load || visit_addr) + { + op = get_base_loadstore (op); + if (op) + { + if (visit_load) + ret |= visit_load (stmt, op, data); + if (visit_addr) + { + constraint = TREE_STRING_POINTER + (TREE_VALUE (TREE_PURPOSE (link))); + parse_input_constraint (&constraint, 0, 0, noutputs, + 0, oconstraints, + &allows_mem, &allows_reg); + if (!allows_reg && allows_mem) + ret |= visit_addr (stmt, op, data); + } + } + } + } } else if (gimple_code (stmt) == GIMPLE_RETURN) { tree op = gimple_return_retval (stmt); if (op) - { - if (visit_addr - && TREE_CODE (op) == ADDR_EXPR) - ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); - else if (visit_load) - { - op = get_base_loadstore (op); - if (op) - ret |= visit_load (stmt, op, data); - } - } + { + if (visit_addr + && TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + else if (visit_load) + { + op = get_base_loadstore (op); + if (op) + ret |= visit_load (stmt, op, data); + } + } } else if (visit_addr - && gimple_code (stmt) == GIMPLE_PHI) + && gimple_code (stmt) == GIMPLE_PHI) { for (i = 0; i < gimple_phi_num_args (stmt); ++i) - { - tree op = PHI_ARG_DEF (stmt, i); - if (TREE_CODE (op) == ADDR_EXPR) - ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); - } + { + tree op = PHI_ARG_DEF (stmt, i); + if (TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + } } return ret; @@ -5079,18 +5087,18 @@ bool walk_stmt_load_store_ops (gimple stmt, void *data, - bool (*visit_load)(gimple, tree, void *), - bool (*visit_store)(gimple, tree, void *)) + bool (*visit_load)(gimple, tree, void *), + bool (*visit_store)(gimple, tree, void *)) { return walk_stmt_load_store_addr_ops (stmt, data, - visit_load, visit_store, NULL); + visit_load, visit_store, NULL); } /* Helper for gimple_ior_addresses_taken_1. */ static bool gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED, - tree addr, void *data) + tree addr, void *data) { bitmap addresses_taken = (bitmap)data; addr = get_base_address (addr); @@ -5111,7 +5119,7 @@ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt) { return walk_stmt_load_store_addr_ops (stmt, addresses_taken, NULL, NULL, - gimple_ior_addresses_taken_1); + gimple_ior_addresses_taken_1); } @@ -5129,14 +5137,14 @@ int dmgl_opts = DMGL_NO_OPTS; if (verbosity >= 2) - { - dmgl_opts = DMGL_VERBOSE - | DMGL_ANSI - | DMGL_GNU_V3 - | DMGL_RET_POSTFIX; - if (TREE_CODE (decl) == FUNCTION_DECL) - dmgl_opts |= DMGL_PARAMS; - } + { + dmgl_opts = DMGL_VERBOSE + | DMGL_ANSI + | DMGL_GNU_V3 + | DMGL_RET_POSTFIX; + if (TREE_CODE (decl) == FUNCTION_DECL) + dmgl_opts |= DMGL_PARAMS; + } mangled_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); str = cplus_demangle_v3 (mangled_str, dmgl_opts); diff -r 561a7518be6b -r 1b10fe6932e1 gcc/gimple.h --- a/gcc/gimple.h Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/gimple.h Sun Aug 21 07:53:12 2011 +0900 @@ -101,6 +101,9 @@ GF_CALL_RETURN_SLOT_OPT = 1 << 2, GF_CALL_TAILCALL = 1 << 3, GF_CALL_VA_ARG_PACK = 1 << 4, +#ifndef noCbC + GF_CALL_CBC_GOTO = 1 << 5, +#endif GF_CALL_NOTHROW = 1 << 5, GF_OMP_PARALLEL_COMBINED = 1 << 0, @@ -2172,6 +2175,21 @@ s->gsbase.subcode &= ~GF_CALL_TAILCALL; } +#ifndef noCbC +/* If CBCGOTO_P is true, mark call statement S as being a cbc goto + (i.e., a call just before the exit of a function). These calls are + candidate for tail call optimization. */ + +static inline void +gimple_call_set_cbc_goto (gimple s, bool cbcgoto_p) +{ + GIMPLE_CHECK (s, GIMPLE_CALL); + if (cbcgoto_p) + s->gsbase.subcode |= GF_CALL_CBC_GOTO; + else + s->gsbase.subcode &= ~GF_CALL_CBC_GOTO; +} +#endif /* Return true if GIMPLE_CALL S is marked as a tail call. */ @@ -2182,6 +2200,16 @@ return (s->gsbase.subcode & GF_CALL_TAILCALL) != 0; } +#ifndef noCbC +/* Return true if GIMPLE_CALL S is marked as a cbc goto. */ + +static inline bool +gimple_call_cbc_goto_p (gimple s) +{ + GIMPLE_CHECK (s, GIMPLE_CALL); + return (s->gsbase.subcode & GF_CALL_CBC_GOTO) != 0; +} +#endif /* Set the inlinable status of GIMPLE_CALL S to INLINABLE_P. */ diff -r 561a7518be6b -r 1b10fe6932e1 gcc/gimplify.c --- a/gcc/gimplify.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/gimplify.c Sun Aug 21 07:53:12 2011 +0900 @@ -45,6 +45,10 @@ #include "splay-tree.h" #include "vec.h" #include "gimple.h" +#ifndef noCbC +#include "cbc-tree.h" +#endif + #include "tree-pass.h" #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name. */ @@ -64,7 +68,7 @@ GOVD_DEBUG_PRIVATE = 256, GOVD_PRIVATE_OUTER_REF = 512, GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE - | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL) + | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL) }; @@ -219,7 +223,7 @@ struct gimplify_ctx *c = gimplify_ctxp; gcc_assert (c && (c->bind_expr_stack == NULL - || VEC_empty (gimple, c->bind_expr_stack))); + || VEC_empty (gimple, c->bind_expr_stack))); VEC_free (gimple, heap, c->bind_expr_stack); gimplify_ctxp = c->prev_context; @@ -385,10 +389,10 @@ for (i = 2; i < 8 && len > i; i++) { if (name[len - i] == '.') - { - name[len - i] = '\0'; - break; - } + { + name[len - i] = '\0'; + break; + } } } @@ -428,8 +432,8 @@ TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type); tmp_var = build_decl (input_location, - VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL, - type); + VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL, + type); /* The variable was declared by the compiler. */ DECL_ARTIFICIAL (tmp_var) = 1; @@ -518,20 +522,20 @@ elt.val = val; if (gimplify_ctxp->temp_htab == NULL) gimplify_ctxp->temp_htab - = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free); + = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free); slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT); if (*slot == NULL) - { - elt_p = XNEW (elt_t); - elt_p->val = val; - elt_p->temp = ret = create_tmp_from_val (val); - *slot = (void *) elt_p; - } + { + elt_p = XNEW (elt_t); + elt_p->val = val; + elt_p->temp = ret = create_tmp_from_val (val); + *slot = (void *) elt_p; + } else - { - elt_p = (elt_t *) *slot; + { + elt_p = (elt_t *) *slot; ret = elt_p->temp; - } + } } return ret; @@ -547,7 +551,7 @@ is_gimple_reg_rhs_or_call (tree t) { return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS - || TREE_CODE (t) == CALL_EXPR); + || TREE_CODE (t) == CALL_EXPR); } /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that @@ -563,7 +567,7 @@ return is_gimple_val (t); else return (is_gimple_val (t) || is_gimple_lvalue (t) - || TREE_CODE (t) == CALL_EXPR); + || TREE_CODE (t) == CALL_EXPR); } /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */ @@ -577,13 +581,13 @@ /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */ gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call, - fb_rvalue); + fb_rvalue); t = lookup_tmp_var (val, is_formal); if (is_formal && (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)) + || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)) DECL_GIMPLE_REG_P (t) = 1; mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val)); @@ -655,20 +659,20 @@ gimple_bind_set_vars (scope, temps); } else - { - /* We need to attach the nodes both to the BIND_EXPR and to its - associated BLOCK for debugging purposes. The key point here - is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR - is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */ - if (BLOCK_VARS (block)) - BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps); - else - { - gimple_bind_set_vars (scope, - chainon (gimple_bind_vars (scope), temps)); - BLOCK_VARS (block) = temps; - } - } + { + /* We need to attach the nodes both to the BIND_EXPR and to its + associated BLOCK for debugging purposes. The key point here + is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR + is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */ + if (BLOCK_VARS (block)) + BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps); + else + { + gimple_bind_set_vars (scope, + chainon (gimple_bind_vars (scope), temps)); + BLOCK_VARS (block) = temps; + } + } } } @@ -717,13 +721,13 @@ /* Mark temporaries local within the nearest enclosing parallel. */ if (gimplify_omp_ctxp) - { - struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; - while (ctx && ctx->region_type == ORT_WORKSHARE) - ctx = ctx->outer_context; - if (ctx) - omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN); - } + { + struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; + while (ctx && ctx->region_type == ORT_WORKSHARE) + ctx = ctx->outer_context; + if (ctx) + omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN); + } } else if (cfun) record_vars (tmp); @@ -732,7 +736,7 @@ gimple_seq body_seq; /* This case is for nested functions. We need to expose the locals - they create. */ + they create. */ body_seq = gimple_body (current_function_decl); declare_vars (tmp, gimple_seq_first_stmt (body_seq), false); } @@ -791,7 +795,7 @@ static void annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi, - location_t location) + location_t location) { if (gsi_end_p (gsi)) gsi = gsi_start (seq); @@ -918,9 +922,9 @@ || TREE_CODE_CLASS (code) == tcc_constant) { if (TREE_VISITED (t)) - *walk_subtrees = 0; + *walk_subtrees = 0; else - TREE_VISITED (t) = 1; + TREE_VISITED (t) = 1; } /* If this node has been visited already, unshare it and don't look @@ -1034,66 +1038,66 @@ tree *p; /* Set p to point to the body of the wrapper. Loop until we find - something that isn't a wrapper. */ + something that isn't a wrapper. */ for (p = &wrapper; p && *p; ) - { - switch (TREE_CODE (*p)) - { - case BIND_EXPR: - TREE_SIDE_EFFECTS (*p) = 1; - TREE_TYPE (*p) = void_type_node; - /* For a BIND_EXPR, the body is operand 1. */ - p = &BIND_EXPR_BODY (*p); - break; - - case CLEANUP_POINT_EXPR: - case TRY_FINALLY_EXPR: - case TRY_CATCH_EXPR: - TREE_SIDE_EFFECTS (*p) = 1; - TREE_TYPE (*p) = void_type_node; - p = &TREE_OPERAND (*p, 0); - break; - - case STATEMENT_LIST: - { - tree_stmt_iterator i = tsi_last (*p); - TREE_SIDE_EFFECTS (*p) = 1; - TREE_TYPE (*p) = void_type_node; - p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i); - } - break; - - case COMPOUND_EXPR: - /* Advance to the last statement. Set all container types to void. */ - for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1)) - { - TREE_SIDE_EFFECTS (*p) = 1; - TREE_TYPE (*p) = void_type_node; - } - break; - - default: - goto out; - } - } + { + switch (TREE_CODE (*p)) + { + case BIND_EXPR: + TREE_SIDE_EFFECTS (*p) = 1; + TREE_TYPE (*p) = void_type_node; + /* For a BIND_EXPR, the body is operand 1. */ + p = &BIND_EXPR_BODY (*p); + break; + + case CLEANUP_POINT_EXPR: + case TRY_FINALLY_EXPR: + case TRY_CATCH_EXPR: + TREE_SIDE_EFFECTS (*p) = 1; + TREE_TYPE (*p) = void_type_node; + p = &TREE_OPERAND (*p, 0); + break; + + case STATEMENT_LIST: + { + tree_stmt_iterator i = tsi_last (*p); + TREE_SIDE_EFFECTS (*p) = 1; + TREE_TYPE (*p) = void_type_node; + p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i); + } + break; + + case COMPOUND_EXPR: + /* Advance to the last statement. Set all container types to void. */ + for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1)) + { + TREE_SIDE_EFFECTS (*p) = 1; + TREE_TYPE (*p) = void_type_node; + } + break; + + default: + goto out; + } + } out: if (p == NULL || IS_EMPTY_STMT (*p)) - temp = NULL_TREE; + temp = NULL_TREE; else if (temp) - { - /* The wrapper is on the RHS of an assignment that we're pushing - down. */ - gcc_assert (TREE_CODE (temp) == INIT_EXPR - || TREE_CODE (temp) == MODIFY_EXPR); - TREE_OPERAND (temp, 1) = *p; - *p = temp; - } + { + /* The wrapper is on the RHS of an assignment that we're pushing + down. */ + gcc_assert (TREE_CODE (temp) == INIT_EXPR + || TREE_CODE (temp) == MODIFY_EXPR); + TREE_OPERAND (temp, 1) = *p; + *p = temp; + } else - { - temp = create_tmp_var (type, "retval"); - *p = build2 (INIT_EXPR, type, temp, *p); - } + { + temp = create_tmp_var (type, "retval"); + *p = build2 (INIT_EXPR, type, temp, *p); + } return temp; } @@ -1114,7 +1118,7 @@ gimple_call_set_lhs (*save, tmp_var); *restore = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_RESTORE], - 1, tmp_var); + 1, tmp_var); } /* Gimplify a BIND_EXPR. Just voidify and recurse. */ @@ -1134,21 +1138,21 @@ for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t)) { if (TREE_CODE (t) == VAR_DECL) - { - struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; - - /* Mark variable as local. */ - if (ctx && !is_global_var (t) - && (! DECL_SEEN_IN_BIND_EXPR_P (t) - || splay_tree_lookup (ctx->variables, - (splay_tree_key) t) == NULL)) - omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN); - - DECL_SEEN_IN_BIND_EXPR_P (t) = 1; - - if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun) - cfun->has_local_explicit_reg_vars = true; - } + { + struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; + + /* Mark variable as local. */ + if (ctx && !is_global_var (t) + && (! DECL_SEEN_IN_BIND_EXPR_P (t) + || splay_tree_lookup (ctx->variables, + (splay_tree_key) t) == NULL)) + omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN); + + DECL_SEEN_IN_BIND_EXPR_P (t) = 1; + + if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun) + cfun->has_local_explicit_reg_vars = true; + } /* Preliminarily mark non-addressed complex variables as eligible for promotion to gimple registers. We'll transform their uses @@ -1178,14 +1182,14 @@ gimple_seq cleanup, new_body; /* Save stack on entry and restore it on exit. Add a try_finally - block to achieve this. Note that mudflap depends on the - format of the emitted code: see mx_register_decls(). */ + block to achieve this. Note that mudflap depends on the + format of the emitted code: see mx_register_decls(). */ build_stack_save_restore (&stack_save, &stack_restore); cleanup = new_body = NULL; gimplify_seq_add_stmt (&cleanup, stack_restore); gs = gimple_build_try (gimple_bind_body (gimple_bind), cleanup, - GIMPLE_TRY_FINALLY); + GIMPLE_TRY_FINALLY); gimplify_seq_add_stmt (&new_body, stack_save); gimplify_seq_add_stmt (&new_body, gs); @@ -1234,7 +1238,16 @@ return GS_ALL_DONE; } - if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) + if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))) +#ifndef noCbC + || ( ret_expr + && TREE_CODE(ret_expr)==CALL_EXPR + && CbC_IS_CbC_GOTO(ret_expr) + //&& !CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl))) + && !(current_function_decl&&CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl)))) + //&& !(current_function_decl&&CbC_IS_CODE_SEGMENT(current_function_decl))) +#endif + ) result_decl = NULL_TREE; else { @@ -1242,11 +1255,11 @@ /* See through a return by reference. */ if (TREE_CODE (result_decl) == INDIRECT_REF) - result_decl = TREE_OPERAND (result_decl, 0); + result_decl = TREE_OPERAND (result_decl, 0); gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR - || TREE_CODE (ret_expr) == INIT_EXPR) - && TREE_CODE (result_decl) == RESULT_DECL); + || TREE_CODE (ret_expr) == INIT_EXPR) + && TREE_CODE (result_decl) == RESULT_DECL); } /* If aggregate_value_p is true, then we can return the bare RESULT_DECL. @@ -1280,9 +1293,9 @@ result = create_tmp_reg (TREE_TYPE (result_decl), NULL); /* ??? With complex control flow (usually involving abnormal edges), - we can wind up warning about an uninitialized value for this. Due - to how this variable is constructed and initialized, this is never - true. Give up and never warn. */ + we can wind up warning about an uninitialized value for this. Due + to how this variable is constructed and initialized, this is never + true. Give up and never warn. */ TREE_NO_WARNING (result) = 1; gimplify_ctxp->return_temp = result; @@ -1364,11 +1377,11 @@ tree init = DECL_INITIAL (decl); if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST - || (!TREE_STATIC (decl) - && flag_stack_check == GENERIC_STACK_CHECK - && compare_tree_int (DECL_SIZE_UNIT (decl), - STACK_CHECK_MAX_VAR_SIZE) > 0)) - gimplify_vla_decl (decl, seq_p); + || (!TREE_STATIC (decl) + && flag_stack_check == GENERIC_STACK_CHECK + && compare_tree_int (DECL_SIZE_UNIT (decl), + STACK_CHECK_MAX_VAR_SIZE) > 0)) + gimplify_vla_decl (decl, seq_p); /* Some front ends do not explicitly declare all anonymous artificial variables. We compensate here by declaring the @@ -1502,7 +1515,7 @@ gimple gimple_switch; /* If someone can be bothered to fill in the labels, they can - be bothered to null out the body too. */ + be bothered to null out the body too. */ gcc_assert (!SWITCH_LABELS (switch_expr)); /* save old labels, get new ones from body, then restore the old @@ -1516,91 +1529,91 @@ i = 0; while (i < VEC_length (tree, labels)) - { - tree elt = VEC_index (tree, labels, i); - tree low = CASE_LOW (elt); - bool remove_element = FALSE; - - if (low) - { - /* Discard empty ranges. */ - tree high = CASE_HIGH (elt); - if (high && tree_int_cst_lt (high, low)) - remove_element = TRUE; - } - else - { - /* The default case must be the last label in the list. */ - gcc_assert (!default_case); - default_case = elt; - remove_element = TRUE; - } - - if (remove_element) - VEC_ordered_remove (tree, labels, i); - else - i++; - } + { + tree elt = VEC_index (tree, labels, i); + tree low = CASE_LOW (elt); + bool remove_element = FALSE; + + if (low) + { + /* Discard empty ranges. */ + tree high = CASE_HIGH (elt); + if (high && tree_int_cst_lt (high, low)) + remove_element = TRUE; + } + else + { + /* The default case must be the last label in the list. */ + gcc_assert (!default_case); + default_case = elt; + remove_element = TRUE; + } + + if (remove_element) + VEC_ordered_remove (tree, labels, i); + else + i++; + } len = i; if (!VEC_empty (tree, labels)) - sort_case_labels (labels); + sort_case_labels (labels); if (!default_case) - { - tree type = TREE_TYPE (switch_expr); - - /* If the switch has no default label, add one, so that we jump - around the switch body. If the labels already cover the whole - range of type, add the default label pointing to one of the - existing labels. */ - if (type == void_type_node) - type = TREE_TYPE (SWITCH_COND (switch_expr)); - if (len - && INTEGRAL_TYPE_P (type) - && TYPE_MIN_VALUE (type) - && TYPE_MAX_VALUE (type) - && tree_int_cst_equal (CASE_LOW (VEC_index (tree, labels, 0)), - TYPE_MIN_VALUE (type))) - { - tree low, high = CASE_HIGH (VEC_index (tree, labels, len - 1)); - if (!high) - high = CASE_LOW (VEC_index (tree, labels, len - 1)); - if (tree_int_cst_equal (high, TYPE_MAX_VALUE (type))) - { - for (i = 1; i < len; i++) - { - high = CASE_LOW (VEC_index (tree, labels, i)); - low = CASE_HIGH (VEC_index (tree, labels, i - 1)); - if (!low) - low = CASE_LOW (VEC_index (tree, labels, i - 1)); - if ((TREE_INT_CST_LOW (low) + 1 - != TREE_INT_CST_LOW (high)) - || (TREE_INT_CST_HIGH (low) - + (TREE_INT_CST_LOW (high) == 0) - != TREE_INT_CST_HIGH (high))) - break; - } - if (i == len) - default_case = build3 (CASE_LABEL_EXPR, void_type_node, - NULL_TREE, NULL_TREE, - CASE_LABEL (VEC_index (tree, - labels, 0))); - } - } - - if (!default_case) - { - gimple new_default; - - default_case - = build3 (CASE_LABEL_EXPR, void_type_node, - NULL_TREE, NULL_TREE, - create_artificial_label (UNKNOWN_LOCATION)); - new_default = gimple_build_label (CASE_LABEL (default_case)); - gimplify_seq_add_stmt (&switch_body_seq, new_default); - } - } + { + tree type = TREE_TYPE (switch_expr); + + /* If the switch has no default label, add one, so that we jump + around the switch body. If the labels already cover the whole + range of type, add the default label pointing to one of the + existing labels. */ + if (type == void_type_node) + type = TREE_TYPE (SWITCH_COND (switch_expr)); + if (len + && INTEGRAL_TYPE_P (type) + && TYPE_MIN_VALUE (type) + && TYPE_MAX_VALUE (type) + && tree_int_cst_equal (CASE_LOW (VEC_index (tree, labels, 0)), + TYPE_MIN_VALUE (type))) + { + tree low, high = CASE_HIGH (VEC_index (tree, labels, len - 1)); + if (!high) + high = CASE_LOW (VEC_index (tree, labels, len - 1)); + if (tree_int_cst_equal (high, TYPE_MAX_VALUE (type))) + { + for (i = 1; i < len; i++) + { + high = CASE_LOW (VEC_index (tree, labels, i)); + low = CASE_HIGH (VEC_index (tree, labels, i - 1)); + if (!low) + low = CASE_LOW (VEC_index (tree, labels, i - 1)); + if ((TREE_INT_CST_LOW (low) + 1 + != TREE_INT_CST_LOW (high)) + || (TREE_INT_CST_HIGH (low) + + (TREE_INT_CST_LOW (high) == 0) + != TREE_INT_CST_HIGH (high))) + break; + } + if (i == len) + default_case = build3 (CASE_LABEL_EXPR, void_type_node, + NULL_TREE, NULL_TREE, + CASE_LABEL (VEC_index (tree, + labels, 0))); + } + } + + if (!default_case) + { + gimple new_default; + + default_case + = build3 (CASE_LABEL_EXPR, void_type_node, + NULL_TREE, NULL_TREE, + create_artificial_label (UNKNOWN_LOCATION)); + new_default = gimple_build_label (CASE_LABEL (default_case)); + gimplify_seq_add_stmt (&switch_body_seq, new_default); + } + } gimple_switch = gimple_build_switch_vec (SWITCH_COND (switch_expr), default_case, labels); @@ -1719,18 +1732,18 @@ int type_quals; /* We need to preserve qualifiers and propagate them from - operand 0. */ + operand 0. */ type_quals = TYPE_QUALS (type) - | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0))); + | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0))); if (TYPE_QUALS (type) != type_quals) - type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals); + type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals); /* Set the type of the COMPONENT_REF to the underlying type. */ TREE_TYPE (expr) = type; #ifdef ENABLE_TYPES_CHECKING /* It is now a FE error, if the conversion from the canonical - type to the original expression type is not useless. */ + type to the original expression type is not useless. */ gcc_assert (useless_type_conversion_p (old_type, type)); #endif } @@ -1769,7 +1782,7 @@ ddatype = TREE_TYPE (datype); pddatype = build_pointer_type (ddatype); if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)), - pddatype)) + pddatype)) return; /* The lower bound and element sizes must be constant. */ @@ -1781,8 +1794,8 @@ /* All checks succeeded. Build a new node to merge the cast. */ *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0), - TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), - NULL_TREE, NULL_TREE); + TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), + NULL_TREE, NULL_TREE); *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p); /* We can have stripped a required restrict qualifier above. */ @@ -1814,8 +1827,8 @@ && POINTER_TYPE_P (TREE_TYPE (*expr_p)) && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) && (tem = maybe_fold_offset_to_address - (EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0), - integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE) + (EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0), + integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE) *expr_p = tem; /* If we still have a conversion at the toplevel, @@ -1825,22 +1838,22 @@ tree sub = TREE_OPERAND (*expr_p, 0); /* If a NOP conversion is changing the type of a COMPONENT_REF - expression, then canonicalize its type now in order to expose more - redundant conversions. */ + expression, then canonicalize its type now in order to expose more + redundant conversions. */ if (TREE_CODE (sub) == COMPONENT_REF) - canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0)); + canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0)); /* If a NOP conversion is changing a pointer to array of foo - to a pointer to foo, embed that change in the ADDR_EXPR. */ + to a pointer to foo, embed that change in the ADDR_EXPR. */ else if (TREE_CODE (sub) == ADDR_EXPR) - canonicalize_addr_expr (expr_p); + canonicalize_addr_expr (expr_p); } /* If we have a conversion to a non-register type force the use of a VIEW_CONVERT_EXPR instead. */ if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p))) *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p), - TREE_OPERAND (*expr_p, 0)); + TREE_OPERAND (*expr_p, 0)); return GS_OK; } @@ -1881,7 +1894,7 @@ tree value_expr = DECL_VALUE_EXPR (decl); /* For referenced nonlocal VLAs add a decl for debugging purposes - to the current function. */ + to the current function. */ if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST && nonlocal_vlas != NULL @@ -1919,10 +1932,10 @@ node *EXPR_P. compound_lval - : min_lval '[' val ']' - | min_lval '.' ID - | compound_lval '[' val ']' - | compound_lval '.' ID + : min_lval '[' val ']' + | min_lval '.' ID + | compound_lval '[' val ']' + | compound_lval '.' ID This is not part of the original SIMPLE definition, which separates array and member references, but it seems reasonable to handle them @@ -1939,7 +1952,7 @@ static enum gimplify_status gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, - fallback_t fallback) + fallback_t fallback) { tree *p; VEC(tree,heap) *stack; @@ -1958,17 +1971,17 @@ restart: /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */ if (TREE_CODE (*p) == INDIRECT_REF) - *p = fold_indirect_ref_loc (loc, *p); + *p = fold_indirect_ref_loc (loc, *p); if (handled_component_p (*p)) - ; + ; /* Expand DECL_VALUE_EXPR now. In some cases that may expose - additional COMPONENT_REFs. */ + additional COMPONENT_REFs. */ else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL) - && gimplify_var_or_parm_decl (p) == GS_OK) - goto restart; + && gimplify_var_or_parm_decl (p) == GS_OK) + goto restart; else - break; + break; VEC_safe_push (tree, heap, stack, *p); } @@ -1992,73 +2005,73 @@ tree t = VEC_index (tree, stack, i); if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) - { - /* Gimplify the low bound and element type size and put them into - the ARRAY_REF. If these values are set, they have already been - gimplified. */ - if (TREE_OPERAND (t, 2) == NULL_TREE) - { - tree low = unshare_expr (array_ref_low_bound (t)); - if (!is_gimple_min_invariant (low)) - { - TREE_OPERAND (t, 2) = low; - tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, - post_p, is_gimple_reg, - fb_rvalue); - ret = MIN (ret, tret); - } - } - - if (!TREE_OPERAND (t, 3)) - { - tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); - tree elmt_size = unshare_expr (array_ref_element_size (t)); - tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); - - /* Divide the element size by the alignment of the element - type (above). */ - elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor); - - if (!is_gimple_min_invariant (elmt_size)) - { - TREE_OPERAND (t, 3) = elmt_size; - tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, - post_p, is_gimple_reg, - fb_rvalue); - ret = MIN (ret, tret); - } - } - } + { + /* Gimplify the low bound and element type size and put them into + the ARRAY_REF. If these values are set, they have already been + gimplified. */ + if (TREE_OPERAND (t, 2) == NULL_TREE) + { + tree low = unshare_expr (array_ref_low_bound (t)); + if (!is_gimple_min_invariant (low)) + { + TREE_OPERAND (t, 2) = low; + tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, + post_p, is_gimple_reg, + fb_rvalue); + ret = MIN (ret, tret); + } + } + + if (!TREE_OPERAND (t, 3)) + { + tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))); + tree elmt_size = unshare_expr (array_ref_element_size (t)); + tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type)); + + /* Divide the element size by the alignment of the element + type (above). */ + elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor); + + if (!is_gimple_min_invariant (elmt_size)) + { + TREE_OPERAND (t, 3) = elmt_size; + tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, + post_p, is_gimple_reg, + fb_rvalue); + ret = MIN (ret, tret); + } + } + } else if (TREE_CODE (t) == COMPONENT_REF) - { - /* Set the field offset into T and gimplify it. */ - if (!TREE_OPERAND (t, 2)) - { - tree offset = unshare_expr (component_ref_field_offset (t)); - tree field = TREE_OPERAND (t, 1); - tree factor - = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); - - /* Divide the offset by its alignment. */ - offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor); - - if (!is_gimple_min_invariant (offset)) - { - TREE_OPERAND (t, 2) = offset; - tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, - post_p, is_gimple_reg, - fb_rvalue); - ret = MIN (ret, tret); - } - } - } + { + /* Set the field offset into T and gimplify it. */ + if (!TREE_OPERAND (t, 2)) + { + tree offset = unshare_expr (component_ref_field_offset (t)); + tree field = TREE_OPERAND (t, 1); + tree factor + = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT); + + /* Divide the offset by its alignment. */ + offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor); + + if (!is_gimple_min_invariant (offset)) + { + TREE_OPERAND (t, 2) = offset; + tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, + post_p, is_gimple_reg, + fb_rvalue); + ret = MIN (ret, tret); + } + } + } } /* Step 2 is to gimplify the base expression. Make sure lvalue is set so as to match the min_lval predicate. Failure to do so may result in the creation of large aggregate temporaries. */ tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, - fallback | fb_lvalue); + fallback | fb_lvalue); ret = MIN (ret, tret); /* And finally, the indices and operands to BIT_FIELD_REF. During this @@ -2068,31 +2081,31 @@ tree t = VEC_pop (tree, stack); if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) - { - /* Gimplify the dimension. */ - if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))) - { - tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, - is_gimple_val, fb_rvalue); - ret = MIN (ret, tret); - } - } + { + /* Gimplify the dimension. */ + if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))) + { + tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, + is_gimple_val, fb_rvalue); + ret = MIN (ret, tret); + } + } else if (TREE_CODE (t) == BIT_FIELD_REF) - { - tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, - is_gimple_val, fb_rvalue); - ret = MIN (ret, tret); - tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, - is_gimple_val, fb_rvalue); - ret = MIN (ret, tret); - } + { + tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, + is_gimple_val, fb_rvalue); + ret = MIN (ret, tret); + tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p, + is_gimple_val, fb_rvalue); + ret = MIN (ret, tret); + } STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0)); /* The innermost expression P may have originally had - TREE_SIDE_EFFECTS set which would have caused all the outer - expressions in *EXPR_P leading to P to also have had - TREE_SIDE_EFFECTS set. */ + TREE_SIDE_EFFECTS set which would have caused all the outer + expressions in *EXPR_P leading to P to also have had + TREE_SIDE_EFFECTS set. */ recalculate_side_effects (t); } @@ -2113,17 +2126,17 @@ (++, --, +=, -=). PRE_P points to the list where side effects that must happen before - *EXPR_P should be stored. + *EXPR_P should be stored. POST_P points to the list where side effects that must happen after - *EXPR_P should be stored. + *EXPR_P should be stored. WANT_VALUE is nonzero iff we want to use the value of this expression - in another expression. */ + in another expression. */ static enum gimplify_status gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, - bool want_value) + bool want_value) { enum tree_code code; tree lhs, lvalue, rhs, t1; @@ -2136,7 +2149,7 @@ code = TREE_CODE (*expr_p); gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR - || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR); + || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR); /* Prefix or postfix? */ if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) @@ -2173,15 +2186,15 @@ if (postfix) { if (!is_gimple_min_lval (lvalue)) - { - mark_addressable (lvalue); - lvalue = build_fold_addr_expr_loc (input_location, lvalue); - gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue); - lvalue = build_fold_indirect_ref_loc (input_location, lvalue); - } + { + mark_addressable (lvalue); + lvalue = build_fold_addr_expr_loc (input_location, lvalue); + gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue); + lvalue = build_fold_indirect_ref_loc (input_location, lvalue); + } ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue); if (ret == GS_ERROR) - return ret; + return ret; } /* For POINTERs increment, use POINTER_PLUS_EXPR. */ @@ -2189,7 +2202,7 @@ { rhs = fold_convert_loc (loc, sizetype, rhs); if (arith_code == MINUS_EXPR) - rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs); + rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs); arith_code = POINTER_PLUS_EXPR; } @@ -2311,38 +2324,38 @@ tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); if (new_tree && new_tree != *expr_p) - { - /* There was a transformation of this call which computes the - same value, but in a more efficient way. Return and try - again. */ - *expr_p = new_tree; - return GS_OK; - } + { + /* There was a transformation of this call which computes the + same value, but in a more efficient way. Return and try + again. */ + *expr_p = new_tree; + return GS_OK; + } if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_VA_START) + && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_VA_START) + { + builtin_va_start_p = TRUE; + if (call_expr_nargs (*expr_p) < 2) { - builtin_va_start_p = TRUE; - if (call_expr_nargs (*expr_p) < 2) - { - error ("too few arguments to function %"); - *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); - return GS_OK; - } - - if (fold_builtin_next_arg (*expr_p, true)) - { - *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); - return GS_OK; - } - } + error ("too few arguments to function %"); + *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); + return GS_OK; + } + + if (fold_builtin_next_arg (*expr_p, true)) + { + *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p)); + return GS_OK; + } + } } /* There is a sequence point before the call, so any side effects in the calling expression must occur before the actual call. Force gimplify_expr to use an internal post queue. */ ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL, - is_gimple_call_addr, fb_rvalue); + is_gimple_call_addr, fb_rvalue); nargs = call_expr_nargs (*expr_p); @@ -2374,31 +2387,31 @@ tree last_arg_fndecl = get_callee_fndecl (last_arg); if (last_arg_fndecl - && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL - && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK) - { - tree call = *expr_p; - - --nargs; - *expr_p = build_call_array_loc (loc, TREE_TYPE (call), - CALL_EXPR_FN (call), - nargs, CALL_EXPR_ARGP (call)); - - /* Copy all CALL_EXPR flags, location and block, except - CALL_EXPR_VA_ARG_PACK flag. */ - CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call); - CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call); - CALL_EXPR_RETURN_SLOT_OPT (*expr_p) - = CALL_EXPR_RETURN_SLOT_OPT (call); - CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call); - CALL_CANNOT_INLINE_P (*expr_p) = CALL_CANNOT_INLINE_P (call); - SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call)); - TREE_BLOCK (*expr_p) = TREE_BLOCK (call); - - /* Set CALL_EXPR_VA_ARG_PACK. */ - CALL_EXPR_VA_ARG_PACK (*expr_p) = 1; - } + && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL + && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK) + { + tree call = *expr_p; + + --nargs; + *expr_p = build_call_array_loc (loc, TREE_TYPE (call), + CALL_EXPR_FN (call), + nargs, CALL_EXPR_ARGP (call)); + + /* Copy all CALL_EXPR flags, location and block, except + CALL_EXPR_VA_ARG_PACK flag. */ + CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call); + CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call); + CALL_EXPR_RETURN_SLOT_OPT (*expr_p) + = CALL_EXPR_RETURN_SLOT_OPT (call); + CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call); + CALL_CANNOT_INLINE_P (*expr_p) = CALL_CANNOT_INLINE_P (call); + SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call)); + TREE_BLOCK (*expr_p) = TREE_BLOCK (call); + + /* Set CALL_EXPR_VA_ARG_PACK. */ + CALL_EXPR_VA_ARG_PACK (*expr_p) = 1; + } } /* Finally, gimplify the function arguments. */ @@ -2415,7 +2428,7 @@ if ((i != 1) || !builtin_va_start_p) { t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, - EXPR_LOCATION (*expr_p)); + EXPR_LOCATION (*expr_p)); if (t == GS_ERROR) ret = GS_ERROR; @@ -2437,13 +2450,13 @@ tree new_tree = fold_call_expr (input_location, *expr_p, !want_value); if (new_tree && new_tree != *expr_p) - { - /* There was a transformation of this call which computes the - same value, but in a more efficient way. Return and try - again. */ - *expr_p = new_tree; - return GS_OK; - } + { + /* There was a transformation of this call which computes the + same value, but in a more efficient way. Return and try + again. */ + *expr_p = new_tree; + return GS_OK; + } } else { @@ -2458,9 +2471,9 @@ { int flags = call_expr_flags (*expr_p); if (flags & (ECF_CONST | ECF_PURE) - /* An infinite loop is considered a side effect. */ - && !(flags & (ECF_LOOPING_CONST_OR_PURE))) - TREE_SIDE_EFFECTS (*expr_p) = 0; + /* An infinite loop is considered a side effect. */ + && !(flags & (ECF_LOOPING_CONST_OR_PURE))) + TREE_SIDE_EFFECTS (*expr_p) = 0; } /* If the value is not needed by the caller, emit a new GIMPLE_CALL @@ -2501,7 +2514,7 @@ static tree shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p, - location_t locus) + location_t locus) { tree local_label = NULL_TREE; tree t, expr = NULL; @@ -2515,12 +2528,12 @@ /* Turn if (a && b) into - if (a); else goto no; - if (b) goto yes; else goto no; - (no:) */ + if (a); else goto no; + if (b) goto yes; else goto no; + (no:) */ if (false_label_p == NULL) - false_label_p = &local_label; + false_label_p = &local_label; /* Keep the original source location on the first 'if'. */ t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus); @@ -2529,7 +2542,7 @@ /* Set the source location of the && on the second 'if'. */ new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus; t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p, - new_locus); + new_locus); append_to_statement_list (t, &expr); } else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR) @@ -2538,12 +2551,12 @@ /* Turn if (a || b) into - if (a) goto yes; - if (b) goto yes; else goto no; - (yes:) */ + if (a) goto yes; + if (b) goto yes; else goto no; + (yes:) */ if (true_label_p == NULL) - true_label_p = &local_label; + true_label_p = &local_label; /* Keep the original source location on the first 'if'. */ t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus); @@ -2552,7 +2565,7 @@ /* Set the source location of the || on the second 'if'. */ new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus; t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p, - new_locus); + new_locus); append_to_statement_list (t, &expr); } else if (TREE_CODE (pred) == COND_EXPR) @@ -2560,25 +2573,25 @@ location_t new_locus; /* As long as we're messing with gotos, turn if (a ? b : c) into - if (a) - if (b) goto yes; else goto no; - else - if (c) goto yes; else goto no; */ + if (a) + if (b) goto yes; else goto no; + else + if (c) goto yes; else goto no; */ /* Keep the original source location on the first 'if'. Set the source - location of the ? on the second 'if'. */ + location of the ? on the second 'if'. */ new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus; expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0), - shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, - false_label_p, locus), - shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p, - false_label_p, new_locus)); + shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, + false_label_p, locus), + shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p, + false_label_p, new_locus)); } else { expr = build3 (COND_EXPR, void_type_node, pred, - build_and_jump (true_label_p), - build_and_jump (false_label_p)); + build_and_jump (true_label_p), + build_and_jump (false_label_p)); SET_EXPR_LOCATION (expr, locus); } @@ -2612,9 +2625,9 @@ if (!else_se) { /* If there is no 'else', turn - if (a && b) then c - into - if (a) if (b) then c. */ + if (a && b) then c + into + if (a) if (b) then c. */ while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR) { /* Keep the original source location on the first 'if'. */ @@ -2634,9 +2647,9 @@ if (!then_se) { /* If there is no 'then', turn - if (a || b); else d - into - if (a); else if (b); else d. */ + if (a || b); else d + into + if (a); else if (b); else d. */ while (TREE_CODE (pred) == TRUTH_ORIF_EXPR) { /* Keep the original source location on the first 'if'. */ @@ -2745,18 +2758,18 @@ if (else_se) { if (jump_over_else) - { - tree last = expr_last (expr); - t = build_and_jump (&end_label); - if (EXPR_HAS_LOCATION (last)) - SET_EXPR_LOCATION (t, EXPR_LOCATION (last)); - append_to_statement_list (t, &expr); - } + { + tree last = expr_last (expr); + t = build_and_jump (&end_label); + if (EXPR_HAS_LOCATION (last)) + SET_EXPR_LOCATION (t, EXPR_LOCATION (last)); + append_to_statement_list (t, &expr); + } if (emit_false) - { - t = build1 (LABEL_EXPR, void_type_node, false_label); - append_to_statement_list (t, &expr); - } + { + t = build1 (LABEL_EXPR, void_type_node, false_label); + append_to_statement_list (t, &expr); + } append_to_statement_list (else_, &expr); } if (emit_end && end_label) @@ -2832,7 +2845,7 @@ default: /* Other expressions that get here must have boolean values, but - might need to be converted to the appropriate mode. */ + might need to be converted to the appropriate mode. */ return fold_convert_loc (loc, boolean_type_node, expr); } } @@ -2860,10 +2873,10 @@ COND_EXPR_COND (*expr_p) = cond; tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); ret = MIN (ret, tret); tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); return MIN (ret, tret); } @@ -2894,10 +2907,10 @@ /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;' into - if (p) if (p) - t1 = a; a; - else or else - t1 = b; b; + if (p) if (p) + t1 = a; a; + else or else + t1 = b; b; t1; The second form is used when *EXPR_P is of type void. @@ -2991,27 +3004,27 @@ expr = shortcut_cond_expr (expr); if (expr != *expr_p) - { - *expr_p = expr; - - /* We can't rely on gimplify_expr to re-gimplify the expanded - form properly, as cleanups might cause the target labels to be - wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to - set up a conditional context. */ - gimple_push_condition (); - gimplify_stmt (expr_p, &seq); - gimple_pop_condition (pre_p); - gimple_seq_add_seq (pre_p, seq); - - return GS_ALL_DONE; - } + { + *expr_p = expr; + + /* We can't rely on gimplify_expr to re-gimplify the expanded + form properly, as cleanups might cause the target labels to be + wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to + set up a conditional context. */ + gimple_push_condition (); + gimplify_stmt (expr_p, &seq); + gimple_pop_condition (pre_p); + gimple_seq_add_seq (pre_p, seq); + + return GS_ALL_DONE; + } } /* Now do the normal gimplification. */ /* Gimplify condition. */ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr, - fb_rvalue); + fb_rvalue); if (ret == GS_ERROR) return GS_ERROR; gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE); @@ -3023,14 +3036,14 @@ && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) - == current_function_decl) + == current_function_decl) /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR - have different locations, otherwise we end up with incorrect - location information on the branches. */ + have different locations, otherwise we end up with incorrect + location information on the branches. */ && (optimize - || !EXPR_HAS_LOCATION (expr) - || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1)) - || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1)))) + || !EXPR_HAS_LOCATION (expr) + || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1)) + || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1)))) { label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1)); have_then_clause_p = true; @@ -3041,14 +3054,14 @@ && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) - == current_function_decl) + == current_function_decl) /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR - have different locations, otherwise we end up with incorrect - location information on the branches. */ + have different locations, otherwise we end up with incorrect + location information on the branches. */ && (optimize - || !EXPR_HAS_LOCATION (expr) - || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2)) - || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2)))) + || !EXPR_HAS_LOCATION (expr) + || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2)) + || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2)))) { label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2)); have_else_clause_p = true; @@ -3057,7 +3070,7 @@ label_false = create_artificial_label (UNKNOWN_LOCATION); gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1, - &arm2); + &arm2); gimple_cond = gimple_build_cond (pred_code, arm1, arm2, label_true, label_false); @@ -3067,39 +3080,39 @@ if (!have_then_clause_p) { /* For if (...) {} else { code; } put label_true after - the else block. */ + the else block. */ if (TREE_OPERAND (expr, 1) == NULL_TREE - && !have_else_clause_p - && TREE_OPERAND (expr, 2) != NULL_TREE) - label_cont = label_true; + && !have_else_clause_p + && TREE_OPERAND (expr, 2) != NULL_TREE) + label_cont = label_true; else - { - gimplify_seq_add_stmt (&seq, gimple_build_label (label_true)); - have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq); - /* For if (...) { code; } else {} or - if (...) { code; } else goto label; or - if (...) { code; return; } else { ... } - label_cont isn't needed. */ - if (!have_else_clause_p - && TREE_OPERAND (expr, 2) != NULL_TREE - && gimple_seq_may_fallthru (seq)) - { - gimple g; - label_cont = create_artificial_label (UNKNOWN_LOCATION); - - g = gimple_build_goto (label_cont); - - /* GIMPLE_COND's are very low level; they have embedded - gotos. This particular embedded goto should not be marked - with the location of the original COND_EXPR, as it would - correspond to the COND_EXPR's condition, not the ELSE or the - THEN arms. To avoid marking it with the wrong location, flag - it as "no location". */ - gimple_set_do_not_emit_location (g); - - gimplify_seq_add_stmt (&seq, g); - } - } + { + gimplify_seq_add_stmt (&seq, gimple_build_label (label_true)); + have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq); + /* For if (...) { code; } else {} or + if (...) { code; } else goto label; or + if (...) { code; return; } else { ... } + label_cont isn't needed. */ + if (!have_else_clause_p + && TREE_OPERAND (expr, 2) != NULL_TREE + && gimple_seq_may_fallthru (seq)) + { + gimple g; + label_cont = create_artificial_label (UNKNOWN_LOCATION); + + g = gimple_build_goto (label_cont); + + /* GIMPLE_COND's are very low level; they have embedded + gotos. This particular embedded goto should not be marked + with the location of the original COND_EXPR, as it would + correspond to the COND_EXPR's condition, not the ELSE or the + THEN arms. To avoid marking it with the wrong location, flag + it as "no location". */ + gimple_set_do_not_emit_location (g); + + gimplify_seq_add_stmt (&seq, g); + } + } } if (!have_else_clause_p) { @@ -3151,7 +3164,7 @@ static enum gimplify_status gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, - gimple_seq *seq_p) + gimple_seq *seq_p) { tree t, to, to_ptr, from, from_ptr; gimple gs; @@ -3198,7 +3211,7 @@ static enum gimplify_status gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value, - gimple_seq *seq_p) + gimple_seq *seq_p) { tree t, from, to, to_ptr; gimple gs; @@ -3212,7 +3225,7 @@ from = TREE_OPERAND (from, 0); gcc_assert (TREE_CODE (from) == CONSTRUCTOR - && VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (from))); + && VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (from))); /* Now proceed. */ to = TREE_OPERAND (*expr_p, 0); @@ -3282,12 +3295,12 @@ tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t))); for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type)) - if (POINTER_TYPE_P (TREE_VALUE (type)) - && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) - && alias_sets_conflict_p (data->lhs_alias_set, - get_alias_set - (TREE_TYPE (TREE_VALUE (type))))) - return t; + if (POINTER_TYPE_P (TREE_VALUE (type)) + && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl)) + && alias_sets_conflict_p (data->lhs_alias_set, + get_alias_set + (TREE_TYPE (TREE_VALUE (type))))) + return t; } if (IS_TYPE_OR_DECL_P (t)) @@ -3301,7 +3314,7 @@ static void gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, - struct gimplify_init_ctor_preeval_data *data) + struct gimplify_init_ctor_preeval_data *data) { enum gimplify_status one; @@ -3309,7 +3322,7 @@ if (TREE_CONSTANT (*expr_p)) { /* Ensure it does not have side effects, it might contain a reference to - the object we're initializing. */ + the object we're initializing. */ gcc_assert (!TREE_SIDE_EFFECTS (*expr_p)); return; } @@ -3374,7 +3387,7 @@ loop_entry: object[var] = value; if (var == upper) - goto loop_exit; + goto loop_exit; var = var + 1; goto loop_entry; loop_exit: @@ -3386,12 +3399,12 @@ already been taken care of for us, in gimplify_init_ctor_preeval(). */ static void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *, - gimple_seq *, bool); + gimple_seq *, bool); static void gimplify_init_ctor_eval_range (tree object, tree lower, tree upper, - tree value, tree array_elt_type, - gimple_seq *pre_p, bool cleared) + tree value, tree array_elt_type, + gimple_seq *pre_p, bool cleared) { tree loop_entry_label, loop_exit_label, fall_thru_label; tree var, var_type, cref, tmp; @@ -3410,7 +3423,7 @@ /* Build the reference. */ cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), - var, NULL_TREE, NULL_TREE); + var, NULL_TREE, NULL_TREE); /* If we are a constructor, just call gimplify_init_ctor_eval to do the store. Otherwise just assign value to the reference. */ @@ -3419,20 +3432,20 @@ /* NB we might have to call ourself recursively through gimplify_init_ctor_eval if the value is a constructor. */ gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), - pre_p, cleared); + pre_p, cleared); else gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value)); /* We exit the loop when the index var is equal to the upper bound. */ gimplify_seq_add_stmt (pre_p, - gimple_build_cond (EQ_EXPR, var, upper, - loop_exit_label, fall_thru_label)); + gimple_build_cond (EQ_EXPR, var, upper, + loop_exit_label, fall_thru_label)); gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label)); /* Otherwise, increment the index var... */ tmp = build2 (PLUS_EXPR, var_type, var, - fold_convert (var_type, integer_one_node)); + fold_convert (var_type, integer_one_node)); gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp)); /* ...and jump back to the loop entry. */ @@ -3472,7 +3485,7 @@ static void gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts, - gimple_seq *pre_p, bool cleared) + gimple_seq *pre_p, bool cleared) { tree array_elt_type = NULL; unsigned HOST_WIDE_INT ix; @@ -3487,68 +3500,68 @@ /* NULL values are created above for gimplification errors. */ if (value == NULL) - continue; + continue; if (cleared && initializer_zerop (value)) - continue; + continue; /* ??? Here's to hoping the front end fills in all of the indices, - so we don't have to figure out what's missing ourselves. */ + so we don't have to figure out what's missing ourselves. */ gcc_assert (purpose); /* Skip zero-sized fields, unless value has side-effects. This can - happen with calls to functions returning a zero-sized type, which - we shouldn't discard. As a number of downstream passes don't - expect sets of zero-sized fields, we rely on the gimplification of - the MODIFY_EXPR we make below to drop the assignment statement. */ + happen with calls to functions returning a zero-sized type, which + we shouldn't discard. As a number of downstream passes don't + expect sets of zero-sized fields, we rely on the gimplification of + the MODIFY_EXPR we make below to drop the assignment statement. */ if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose)) - continue; + continue; /* If we have a RANGE_EXPR, we have to build a loop to assign the - whole range. */ + whole range. */ if (TREE_CODE (purpose) == RANGE_EXPR) - { - tree lower = TREE_OPERAND (purpose, 0); - tree upper = TREE_OPERAND (purpose, 1); - - /* If the lower bound is equal to upper, just treat it as if - upper was the index. */ - if (simple_cst_equal (lower, upper)) - purpose = upper; - else - { - gimplify_init_ctor_eval_range (object, lower, upper, value, - array_elt_type, pre_p, cleared); - continue; - } - } + { + tree lower = TREE_OPERAND (purpose, 0); + tree upper = TREE_OPERAND (purpose, 1); + + /* If the lower bound is equal to upper, just treat it as if + upper was the index. */ + if (simple_cst_equal (lower, upper)) + purpose = upper; + else + { + gimplify_init_ctor_eval_range (object, lower, upper, value, + array_elt_type, pre_p, cleared); + continue; + } + } if (array_elt_type) - { - /* Do not use bitsizetype for ARRAY_REF indices. */ - if (TYPE_DOMAIN (TREE_TYPE (object))) - purpose = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))), - purpose); - cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), - purpose, NULL_TREE, NULL_TREE); - } + { + /* Do not use bitsizetype for ARRAY_REF indices. */ + if (TYPE_DOMAIN (TREE_TYPE (object))) + purpose = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))), + purpose); + cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object), + purpose, NULL_TREE, NULL_TREE); + } else - { - gcc_assert (TREE_CODE (purpose) == FIELD_DECL); - cref = build3 (COMPONENT_REF, TREE_TYPE (purpose), - unshare_expr (object), purpose, NULL_TREE); - } + { + gcc_assert (TREE_CODE (purpose) == FIELD_DECL); + cref = build3 (COMPONENT_REF, TREE_TYPE (purpose), + unshare_expr (object), purpose, NULL_TREE); + } if (TREE_CODE (value) == CONSTRUCTOR - && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE) - gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), - pre_p, cleared); + && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE) + gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value), + pre_p, cleared); else - { - tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value); - gimplify_and_add (init, pre_p); - ggc_free (init); - } + { + tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value); + gimplify_and_add (init, pre_p); + ggc_free (init); + } } } @@ -3614,27 +3627,27 @@ tree value = VEC_index (constructor_elt, elts, idx)->value; tree newval = value; if (TREE_CODE (value) == CONSTRUCTOR) - newval = optimize_compound_literals_in_ctor (value); + newval = optimize_compound_literals_in_ctor (value); else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR) - { - tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value); - tree decl = DECL_EXPR_DECL (decl_s); - tree init = DECL_INITIAL (decl); - - if (!TREE_ADDRESSABLE (value) - && !TREE_ADDRESSABLE (decl) - && init) - newval = optimize_compound_literals_in_ctor (init); - } + { + tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value); + tree decl = DECL_EXPR_DECL (decl_s); + tree init = DECL_INITIAL (decl); + + if (!TREE_ADDRESSABLE (value) + && !TREE_ADDRESSABLE (decl) + && init) + newval = optimize_compound_literals_in_ctor (init); + } if (newval == value) - continue; + continue; if (ctor == orig_ctor) - { - ctor = copy_node (orig_ctor); - CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts); - elts = CONSTRUCTOR_ELTS (ctor); - } + { + ctor = copy_node (orig_ctor); + CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts); + elts = CONSTRUCTOR_ELTS (ctor); + } VEC_index (constructor_elt, elts, idx)->value = newval; } return ctor; @@ -3657,7 +3670,7 @@ static enum gimplify_status gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, - bool want_value, bool notify_temp_creation) + bool want_value, bool notify_temp_creation) { tree object, ctor, type; enum gimplify_status ret; @@ -3668,9 +3681,9 @@ if (!notify_temp_creation) { ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, - is_gimple_lvalue, fb_lvalue); + is_gimple_lvalue, fb_lvalue); if (ret == GS_ERROR) - return ret; + return ret; } object = TREE_OPERAND (*expr_p, 0); @@ -3983,15 +3996,15 @@ else { /* If we have gimplified both sides of the initializer but have - not emitted an assignment, do so now. */ + not emitted an assignment, do so now. */ if (*expr_p) - { - tree lhs = TREE_OPERAND (*expr_p, 0); - tree rhs = TREE_OPERAND (*expr_p, 1); - gimple init = gimple_build_assign (lhs, rhs); - gimplify_seq_add_stmt (pre_p, init); - *expr_p = NULL; - } + { + tree lhs = TREE_OPERAND (*expr_p, 0); + tree rhs = TREE_OPERAND (*expr_p, 1); + gimple init = gimple_build_assign (lhs, rhs); + gimplify_seq_add_stmt (pre_p, init); + *expr_p = NULL; + } return GS_ALL_DONE; } @@ -4107,7 +4120,7 @@ tree osub = sub; sub = gimple_fold_indirect_ref (sub); if (! sub) - sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub); + sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub); type_domain = TYPE_DOMAIN (TREE_TYPE (sub)); if (type_domain && TYPE_MIN_VALUE (type_domain)) min_val = TYPE_MIN_VALUE (type_domain); @@ -4137,8 +4150,8 @@ static enum gimplify_status gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, - gimple_seq *pre_p, gimple_seq *post_p, - bool want_value) + gimple_seq *pre_p, gimple_seq *post_p, + bool want_value) { enum gimplify_status ret = GS_UNHANDLED; bool changed; @@ -4453,21 +4466,21 @@ /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P. modify_expr - : varname '=' rhs - | '*' ID '=' rhs + : varname '=' rhs + | '*' ID '=' rhs PRE_P points to the list where side effects that must happen before - *EXPR_P should be stored. + *EXPR_P should be stored. POST_P points to the list where side effects that must happen after - *EXPR_P should be stored. + *EXPR_P should be stored. WANT_VALUE is nonzero iff we want to use the value of this expression - in another expression. */ + in another expression. */ static enum gimplify_status gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, - bool want_value) + bool want_value) { tree *from_p = &TREE_OPERAND (*expr_p, 1); tree *to_p = &TREE_OPERAND (*expr_p, 0); @@ -4476,7 +4489,7 @@ location_t loc = EXPR_LOCATION (*expr_p); gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR - || TREE_CODE (*expr_p) == INIT_EXPR); + || TREE_CODE (*expr_p) == INIT_EXPR); /* Insert pointer conversions required by the middle-end that are not required by the frontend. This fixes middle-end type checking for @@ -4485,12 +4498,12 @@ { STRIP_USELESS_TYPE_CONVERSION (*from_p); if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p))) - *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p); + *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p); } /* See if any simplifications can be done based on what the RHS is. */ ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, - want_value); + want_value); if (ret != GS_UNHANDLED) return ret; @@ -4531,13 +4544,13 @@ created GIMPLE_CALL will be the last statement in *PRE_P and all we need to do here is set 'a' to be its LHS. */ ret = gimplify_expr (from_p, pre_p, post_p, rhs_predicate_for (*to_p), - fb_rvalue); + fb_rvalue); if (ret == GS_ERROR) return ret; /* Now see if the above changed *from_p to something we handle specially. */ ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p, - want_value); + want_value); if (ret != GS_UNHANDLED) return ret; @@ -4550,14 +4563,14 @@ tree size = TREE_OPERAND (*from_p, 1); if (TREE_CODE (from) == CONSTRUCTOR) - return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p); + return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p); if (is_gimple_addressable (from)) - { - *from_p = from; - return gimplify_modify_expr_to_memcpy (expr_p, size, want_value, - pre_p); - } + { + *from_p = from; + return gimplify_modify_expr_to_memcpy (expr_p, size, want_value, + pre_p); + } } /* Transform partial stores to non-addressable complex variables into @@ -4577,8 +4590,8 @@ && !DECL_IGNORED_P (*to_p)) { if (!DECL_NAME (*from_p) && DECL_NAME (*to_p)) - DECL_NAME (*from_p) - = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p))); + DECL_NAME (*from_p) + = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p))); DECL_DEBUG_EXPR_IS_FROM (*from_p) = 1; SET_DECL_DEBUG_EXPR (*from_p, *to_p); } @@ -4589,7 +4602,7 @@ if (TREE_CODE (*from_p) == CALL_EXPR) { /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL - instead of a GIMPLE_ASSIGN. */ + instead of a GIMPLE_ASSIGN. */ assign = gimple_build_call_from_tree (*from_p); if (!gimple_call_noreturn_p (assign)) gimple_call_set_lhs (assign, *to_p); @@ -4605,7 +4618,7 @@ if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) { /* If we've somehow already got an SSA_NAME on the LHS, then - we've probably modified it twice. Not good. */ + we've probably modified it twice. Not good. */ gcc_assert (TREE_CODE (*to_p) != SSA_NAME); *to_p = make_ssa_name (*to_p, assign); gimple_set_lhs (assign, *to_p); @@ -4676,7 +4689,7 @@ Expressions of the form 'a && b' are gimplified to: - a && b ? true : false + a && b ? true : false LOCUS is the source location to be put on the generated COND_EXPR. gimplify_cond_expr will do the rest. */ @@ -4688,8 +4701,8 @@ tree type = TREE_TYPE (*expr_p); *expr_p = build3 (COND_EXPR, type, *expr_p, - fold_convert_loc (locus, type, boolean_true_node), - fold_convert_loc (locus, type, boolean_false_node)); + fold_convert_loc (locus, type, boolean_true_node), + fold_convert_loc (locus, type, boolean_false_node)); SET_EXPR_LOCATION (*expr_p, locus); @@ -4715,9 +4728,9 @@ tree *sub_p = &TREE_OPERAND (t, 0); if (TREE_CODE (*sub_p) == COMPOUND_EXPR) - gimplify_compound_expr (sub_p, pre_p, false); + gimplify_compound_expr (sub_p, pre_p, false); else - gimplify_stmt (sub_p, pre_p); + gimplify_stmt (sub_p, pre_p); t = TREE_OPERAND (t, 1); } @@ -4754,16 +4767,16 @@ if (!SAVE_EXPR_RESOLVED_P (*expr_p)) { /* The operand may be a void-valued expression such as SAVE_EXPRs - generated by the Java frontend for class initialization. It is - being executed only for its side-effects. */ + generated by the Java frontend for class initialization. It is + being executed only for its side-effects. */ if (TREE_TYPE (val) == void_type_node) - { - ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, - is_gimple_stmt, fb_none); - val = NULL; - } + { + ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, + is_gimple_stmt, fb_none); + val = NULL; + } else - val = get_initialized_tmp_var (val, pre_p, post_p); + val = get_initialized_tmp_var (val, pre_p, post_p); TREE_OPERAND (*expr_p, 0) = val; SAVE_EXPR_RESOLVED_P (*expr_p) = 1; @@ -4777,15 +4790,15 @@ /* Re-write the ADDR_EXPR node pointed to by EXPR_P unary_expr - : ... - | '&' varname - ... + : ... + | '&' varname + ... PRE_P points to the list where side effects that must happen before - *EXPR_P should be stored. + *EXPR_P should be stored. POST_P points to the list where side effects that must happen after - *EXPR_P should be stored. */ + *EXPR_P should be stored. */ static enum gimplify_status gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) @@ -4800,21 +4813,21 @@ case INDIRECT_REF: do_indirect_ref: /* Check if we are dealing with an expression of the form '&*ptr'. - While the front end folds away '&*ptr' into 'ptr', these - expressions may be generated internally by the compiler (e.g., - builtins like __builtin_va_end). */ + While the front end folds away '&*ptr' into 'ptr', these + expressions may be generated internally by the compiler (e.g., + builtins like __builtin_va_end). */ /* Caution: the silent array decomposition semantics we allow for - ADDR_EXPR means we can't always discard the pair. */ + ADDR_EXPR means we can't always discard the pair. */ /* Gimplification of the ADDR_EXPR operand may drop - cv-qualification conversions, so make sure we add them if - needed. */ + cv-qualification conversions, so make sure we add them if + needed. */ { - tree op00 = TREE_OPERAND (op0, 0); - tree t_expr = TREE_TYPE (expr); - tree t_op00 = TREE_TYPE (op00); + tree op00 = TREE_OPERAND (op0, 0); + tree t_expr = TREE_TYPE (expr); + tree t_op00 = TREE_TYPE (op00); if (!useless_type_conversion_p (t_expr, t_op00)) - op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00); + op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00); *expr_p = op00; ret = GS_OK; } @@ -4822,53 +4835,53 @@ case VIEW_CONVERT_EXPR: /* Take the address of our operand and then convert it to the type of - this ADDR_EXPR. - - ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at - all clear. The impact of this transformation is even less clear. */ + this ADDR_EXPR. + + ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at + all clear. The impact of this transformation is even less clear. */ /* If the operand is a useless conversion, look through it. Doing so - guarantees that the ADDR_EXPR and its operand will remain of the - same type. */ + guarantees that the ADDR_EXPR and its operand will remain of the + same type. */ if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0))) - op0 = TREE_OPERAND (op0, 0); + op0 = TREE_OPERAND (op0, 0); *expr_p = fold_convert_loc (loc, TREE_TYPE (expr), - build_fold_addr_expr_loc (loc, - TREE_OPERAND (op0, 0))); + build_fold_addr_expr_loc (loc, + TREE_OPERAND (op0, 0))); ret = GS_OK; break; default: /* We use fb_either here because the C frontend sometimes takes - the address of a call that returns a struct; see - gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make - the implied temporary explicit. */ + the address of a call that returns a struct; see + gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make + the implied temporary explicit. */ /* Make the operand addressable. */ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, - is_gimple_addressable, fb_either); + is_gimple_addressable, fb_either); if (ret == GS_ERROR) - break; + break; /* Then mark it. Beware that it may not be possible to do so directly - if a temporary has been created by the gimplification. */ + if a temporary has been created by the gimplification. */ prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p); op0 = TREE_OPERAND (expr, 0); /* For various reasons, the gimplification of the expression - may have made a new INDIRECT_REF. */ + may have made a new INDIRECT_REF. */ if (TREE_CODE (op0) == INDIRECT_REF) - goto do_indirect_ref; + goto do_indirect_ref; mark_addressable (TREE_OPERAND (expr, 0)); /* The FEs may end up building ADDR_EXPRs early on a decl with - an incomplete type. Re-build ADDR_EXPRs in canonical form - here. */ + an incomplete type. Re-build ADDR_EXPRs in canonical form + here. */ if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr)))) - *expr_p = build_fold_addr_expr (op0); + *expr_p = build_fold_addr_expr (op0); /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */ recompute_tree_invariant_for_addr_expr (*expr_p); @@ -4876,7 +4889,7 @@ /* If we re-built the ADDR_EXPR add a conversion to the original type if required. */ if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p))) - *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); + *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); break; } @@ -4921,126 +4934,126 @@ link_next = TREE_CHAIN (link); oconstraints[i] - = constraint - = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); + = constraint + = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); constraint_len = strlen (constraint); if (constraint_len == 0) continue; ok = parse_output_constraint (&constraint, i, 0, 0, - &allows_mem, &allows_reg, &is_inout); + &allows_mem, &allows_reg, &is_inout); if (!ok) - { - ret = GS_ERROR; - is_inout = false; - } + { + ret = GS_ERROR; + is_inout = false; + } if (!allows_reg && allows_mem) - mark_addressable (TREE_VALUE (link)); + mark_addressable (TREE_VALUE (link)); tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, - is_inout ? is_gimple_min_lval : is_gimple_lvalue, - fb_lvalue | fb_mayfail); + is_inout ? is_gimple_min_lval : is_gimple_lvalue, + fb_lvalue | fb_mayfail); if (tret == GS_ERROR) - { - error ("invalid lvalue in asm output %d", i); - ret = tret; - } + { + error ("invalid lvalue in asm output %d", i); + ret = tret; + } VEC_safe_push (tree, gc, outputs, link); TREE_CHAIN (link) = NULL_TREE; if (is_inout) - { - /* An input/output operand. To give the optimizers more - flexibility, split it into separate input and output - operands. */ - tree input; - char buf[10]; - - /* Turn the in/out constraint into an output constraint. */ - char *p = xstrdup (constraint); - p[0] = '='; - TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p); - - /* And add a matching input constraint. */ - if (allows_reg) - { - sprintf (buf, "%d", i); - - /* If there are multiple alternatives in the constraint, - handle each of them individually. Those that allow register - will be replaced with operand number, the others will stay - unchanged. */ - if (strchr (p, ',') != NULL) - { - size_t len = 0, buflen = strlen (buf); - char *beg, *end, *str, *dst; - - for (beg = p + 1;;) - { - end = strchr (beg, ','); - if (end == NULL) - end = strchr (beg, '\0'); - if ((size_t) (end - beg) < buflen) - len += buflen + 1; - else - len += end - beg + 1; - if (*end) - beg = end + 1; - else - break; - } - - str = (char *) alloca (len); - for (beg = p + 1, dst = str;;) - { - const char *tem; - bool mem_p, reg_p, inout_p; - - end = strchr (beg, ','); - if (end) - *end = '\0'; - beg[-1] = '='; - tem = beg - 1; - parse_output_constraint (&tem, i, 0, 0, - &mem_p, ®_p, &inout_p); - if (dst != str) - *dst++ = ','; - if (reg_p) - { - memcpy (dst, buf, buflen); - dst += buflen; - } - else - { - if (end) - len = end - beg; - else - len = strlen (beg); - memcpy (dst, beg, len); - dst += len; - } - if (end) - beg = end + 1; - else - break; - } - *dst = '\0'; - input = build_string (dst - str, str); - } - else - input = build_string (strlen (buf), buf); - } - else - input = build_string (constraint_len - 1, constraint + 1); - - free (p); - - input = build_tree_list (build_tree_list (NULL_TREE, input), - unshare_expr (TREE_VALUE (link))); - ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input); - } + { + /* An input/output operand. To give the optimizers more + flexibility, split it into separate input and output + operands. */ + tree input; + char buf[10]; + + /* Turn the in/out constraint into an output constraint. */ + char *p = xstrdup (constraint); + p[0] = '='; + TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p); + + /* And add a matching input constraint. */ + if (allows_reg) + { + sprintf (buf, "%d", i); + + /* If there are multiple alternatives in the constraint, + handle each of them individually. Those that allow register + will be replaced with operand number, the others will stay + unchanged. */ + if (strchr (p, ',') != NULL) + { + size_t len = 0, buflen = strlen (buf); + char *beg, *end, *str, *dst; + + for (beg = p + 1;;) + { + end = strchr (beg, ','); + if (end == NULL) + end = strchr (beg, '\0'); + if ((size_t) (end - beg) < buflen) + len += buflen + 1; + else + len += end - beg + 1; + if (*end) + beg = end + 1; + else + break; + } + + str = (char *) alloca (len); + for (beg = p + 1, dst = str;;) + { + const char *tem; + bool mem_p, reg_p, inout_p; + + end = strchr (beg, ','); + if (end) + *end = '\0'; + beg[-1] = '='; + tem = beg - 1; + parse_output_constraint (&tem, i, 0, 0, + &mem_p, ®_p, &inout_p); + if (dst != str) + *dst++ = ','; + if (reg_p) + { + memcpy (dst, buf, buflen); + dst += buflen; + } + else + { + if (end) + len = end - beg; + else + len = strlen (beg); + memcpy (dst, beg, len); + dst += len; + } + if (end) + beg = end + 1; + else + break; + } + *dst = '\0'; + input = build_string (dst - str, str); + } + else + input = build_string (strlen (buf), buf); + } + else + input = build_string (constraint_len - 1, constraint + 1); + + free (p); + + input = build_tree_list (build_tree_list (NULL_TREE, input), + unshare_expr (TREE_VALUE (link))); + ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input); + } } link_next = NULL_TREE; @@ -5049,20 +5062,20 @@ link_next = TREE_CHAIN (link); constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_input_constraint (&constraint, 0, 0, noutputs, 0, - oconstraints, &allows_mem, &allows_reg); + oconstraints, &allows_mem, &allows_reg); /* If we can't make copies, we can only accept memory. */ if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link)))) - { - if (allows_mem) - allows_reg = 0; - else - { - error ("impossible constraint in %"); - error ("non-memory input %d must stay in memory", i); - return GS_ERROR; - } - } + { + if (allows_mem) + allows_reg = 0; + else + { + error ("impossible constraint in %"); + error ("non-memory input %d must stay in memory", i); + return GS_ERROR; + } + } /* If the operand is a memory input, it should be an lvalue. */ if (!allows_reg && allows_mem) @@ -5086,12 +5099,12 @@ } } else - { - tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, - is_gimple_asm_val, fb_rvalue); - if (tret == GS_ERROR) - ret = tret; - } + { + tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p, + is_gimple_asm_val, fb_rvalue); + if (tret == GS_ERROR) + ret = tret; + } TREE_CHAIN (link) = NULL_TREE; VEC_safe_push (tree, gc, inputs, link); @@ -5107,7 +5120,7 @@ if (ret != GS_ERROR) { stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)), - inputs, outputs, clobbers, labels); + inputs, outputs, clobbers, labels); gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr)); gimple_asm_set_input (stmt, ASM_INPUT_P (expr)); @@ -5158,9 +5171,9 @@ gimple wce = gsi_stmt (iter); if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR) - { - if (gsi_one_before_end_p (iter)) - { + { + if (gsi_one_before_end_p (iter)) + { /* Note that gsi_insert_seq_before and gsi_remove do not scan operands, unlike some other sequence mutators. */ if (!gimple_wce_cleanup_eh_only (wce)) @@ -5186,11 +5199,11 @@ /* Do not use gsi_replace here, as it may scan operands. We want to do a simple structural modification only. */ *gsi_stmt_ptr (&iter) = gtry; - iter = gsi_start (seq); - } - } + iter = gsi_start (seq); + } + } else - gsi_next (&iter); + gsi_next (&iter); } gimplify_seq_add_seq (pre_p, body_sequence); @@ -5224,24 +5237,24 @@ if (gimple_conditional_context ()) { /* If we're in a conditional context, this is more complex. We only - want to run the cleanup if we actually ran the initialization that - necessitates it, but we want to run it after the end of the - conditional context. So we wrap the try/finally around the - condition and use a flag to determine whether or not to actually - run the destructor. Thus - - test ? f(A()) : 0 - - becomes (approximately) - - flag = 0; - try { - if (test) { A::A(temp); flag = 1; val = f(temp); } - else { val = 0; } - } finally { - if (flag) A::~A(temp); - } - val + want to run the cleanup if we actually ran the initialization that + necessitates it, but we want to run it after the end of the + conditional context. So we wrap the try/finally around the + condition and use a flag to determine whether or not to actually + run the destructor. Thus + + test ? f(A()) : 0 + + becomes (approximately) + + flag = 0; + try { + if (test) { A::A(temp); flag = 1; val = f(temp); } + else { val = 0; } + } finally { + if (flag) A::~A(temp); + } + val */ tree flag = create_tmp_var (boolean_type_node, "cleanup"); gimple ffalse = gimple_build_assign (flag, boolean_false_node); @@ -5256,8 +5269,8 @@ gimplify_seq_add_stmt (pre_p, ftrue); /* Because of this manipulation, and the EH edges that jump - threading cannot redirect, the temporary (VAR) will appear - to be used uninitialized. Don't warn. */ + threading cannot redirect, the temporary (VAR) will appear + to be used uninitialized. Don't warn. */ TREE_NO_WARNING (var) = 1; } else @@ -5282,41 +5295,41 @@ if (init) { /* TARGET_EXPR temps aren't part of the enclosing block, so add it - to the temps list. Handle also variable length TARGET_EXPRs. */ + to the temps list. Handle also variable length TARGET_EXPRs. */ if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST) - { - if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp))) - gimplify_type_sizes (TREE_TYPE (temp), pre_p); - gimplify_vla_decl (temp, pre_p); - } + { + if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp))) + gimplify_type_sizes (TREE_TYPE (temp), pre_p); + gimplify_vla_decl (temp, pre_p); + } else - gimple_add_tmp_var (temp); + gimple_add_tmp_var (temp); /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the - expression is supposed to initialize the slot. */ + expression is supposed to initialize the slot. */ if (VOID_TYPE_P (TREE_TYPE (init))) - ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); + ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); else - { - tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init); - init = init_expr; - ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); - init = NULL; - ggc_free (init_expr); - } + { + tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init); + init = init_expr; + ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); + init = NULL; + ggc_free (init_expr); + } if (ret == GS_ERROR) - { - /* PR c++/28266 Make sure this is expanded only once. */ - TARGET_EXPR_INITIAL (targ) = NULL_TREE; - return GS_ERROR; - } + { + /* PR c++/28266 Make sure this is expanded only once. */ + TARGET_EXPR_INITIAL (targ) = NULL_TREE; + return GS_ERROR; + } if (init) - gimplify_and_add (init, pre_p); + gimplify_and_add (init, pre_p); /* If needed, push the cleanup for the temp. */ if (TARGET_EXPR_CLEANUP (targ)) - gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), - CLEANUP_EH_ONLY (targ), pre_p); + gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), + CLEANUP_EH_ONLY (targ), pre_p); /* Only expand this once. */ TREE_OPERAND (targ, 3) = init; @@ -5368,14 +5381,14 @@ { n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); if (n != NULL) - { - if (n->value & GOVD_SHARED) - n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN); - else - return; - } + { + if (n->value & GOVD_SHARED) + n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN); + else + return; + } else if (ctx->region_type != ORT_WORKSHARE) - omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); + omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE); ctx = ctx->outer_context; } @@ -5460,13 +5473,13 @@ if (n != NULL) { /* We shouldn't be re-adding the decl with the same data - sharing class. */ + sharing class. */ gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0); /* The only combination of data sharing classes we should see is - FIRSTPRIVATE and LASTPRIVATE. */ + FIRSTPRIVATE and LASTPRIVATE. */ nflags = n->value | flags; gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS) - == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)); + == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)); n->value = nflags; return; } @@ -5477,32 +5490,32 @@ if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) { /* Add the pointer replacement variable as PRIVATE if the variable - replacement is private, else FIRSTPRIVATE since we'll need the - address of the original variable either for SHARED, or for the - copy into or out of the context. */ + replacement is private, else FIRSTPRIVATE since we'll need the + address of the original variable either for SHARED, or for the + copy into or out of the context. */ if (!(flags & GOVD_LOCAL)) - { - nflags = flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE; - nflags |= flags & GOVD_SEEN; - t = DECL_VALUE_EXPR (decl); - gcc_assert (TREE_CODE (t) == INDIRECT_REF); - t = TREE_OPERAND (t, 0); - gcc_assert (DECL_P (t)); - omp_add_variable (ctx, t, nflags); - } + { + nflags = flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE; + nflags |= flags & GOVD_SEEN; + t = DECL_VALUE_EXPR (decl); + gcc_assert (TREE_CODE (t) == INDIRECT_REF); + t = TREE_OPERAND (t, 0); + gcc_assert (DECL_P (t)); + omp_add_variable (ctx, t, nflags); + } /* Add all of the variable and type parameters (which should have - been gimplified to a formal temporary) as FIRSTPRIVATE. */ + been gimplified to a formal temporary) as FIRSTPRIVATE. */ omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl)); omp_firstprivatize_variable (ctx, DECL_SIZE (decl)); omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); /* The variable-sized variable itself is never SHARED, only some form - of PRIVATE. The sharing would take place via the pointer variable - which we remapped above. */ + of PRIVATE. The sharing would take place via the pointer variable + which we remapped above. */ if (flags & GOVD_SHARED) - flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE - | (flags & (GOVD_SEEN | GOVD_EXPLICIT)); + flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE + | (flags & (GOVD_SEEN | GOVD_EXPLICIT)); /* We're going to make use of the TYPE_SIZE_UNIT at least in the alloca statement we generate for the variable, so make sure it @@ -5521,13 +5534,13 @@ omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl)); /* Similar to the direct variable sized case above, we'll need the - size of references being privatized. */ + size of references being privatized. */ if ((flags & GOVD_SHARED) == 0) - { - t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); - if (TREE_CODE (t) != INTEGER_CST) - omp_notice_variable (ctx, t, true); - } + { + t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); + if (TREE_CODE (t) != INTEGER_CST) + omp_notice_variable (ctx, t, true); + } } splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags); @@ -5596,15 +5609,15 @@ struct gimplify_omp_ctx *octx; if (ctx->region_type == ORT_WORKSHARE) - goto do_outer; + goto do_outer; /* ??? Some compiler-generated variables (like SAVE_EXPRs) could be - remapped firstprivate instead of shared. To some extent this is - addressed in omp_firstprivatize_type_sizes, but not effectively. */ + remapped firstprivate instead of shared. To some extent this is + addressed in omp_firstprivatize_type_sizes, but not effectively. */ default_kind = ctx->default_kind; kind = lang_hooks.decls.omp_predetermined_sharing (decl); if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED) - default_kind = kind; + default_kind = kind; switch (default_kind) { @@ -5660,8 +5673,8 @@ } if ((flags & GOVD_PRIVATE) - && lang_hooks.decls.omp_private_outer_ref (decl)) - flags |= GOVD_PRIVATE_OUTER_REF; + && lang_hooks.decls.omp_private_outer_ref (decl)) + flags |= GOVD_PRIVATE_OUTER_REF; omp_add_variable (ctx, decl, flags); @@ -5716,32 +5729,32 @@ if (n != NULL) { if (n->value & GOVD_SHARED) - { - if (ctx == gimplify_omp_ctxp) - { - error ("iteration variable %qE should be private", - DECL_NAME (decl)); - n->value = GOVD_PRIVATE; - return true; - } - else - return false; - } + { + if (ctx == gimplify_omp_ctxp) + { + error ("iteration variable %qE should be private", + DECL_NAME (decl)); + n->value = GOVD_PRIVATE; + return true; + } + else + return false; + } else if ((n->value & GOVD_EXPLICIT) != 0 - && (ctx == gimplify_omp_ctxp - || (ctx->region_type == ORT_COMBINED_PARALLEL - && gimplify_omp_ctxp->outer_context == ctx))) - { - if ((n->value & GOVD_FIRSTPRIVATE) != 0) - error ("iteration variable %qE should not be firstprivate", - DECL_NAME (decl)); - else if ((n->value & GOVD_REDUCTION) != 0) - error ("iteration variable %qE should not be reduction", - DECL_NAME (decl)); - } + && (ctx == gimplify_omp_ctxp + || (ctx->region_type == ORT_COMBINED_PARALLEL + && gimplify_omp_ctxp->outer_context == ctx))) + { + if ((n->value & GOVD_FIRSTPRIVATE) != 0) + error ("iteration variable %qE should not be firstprivate", + DECL_NAME (decl)); + else if ((n->value & GOVD_REDUCTION) != 0) + error ("iteration variable %qE should not be reduction", + DECL_NAME (decl)); + } return (ctx == gimplify_omp_ctxp - || (ctx->region_type == ORT_COMBINED_PARALLEL - && gimplify_omp_ctxp->outer_context == ctx)); + || (ctx->region_type == ORT_COMBINED_PARALLEL + && gimplify_omp_ctxp->outer_context == ctx)); } if (ctx->region_type != ORT_WORKSHARE) @@ -5764,13 +5777,13 @@ { ctx = ctx->outer_context; if (ctx == NULL) - return !(is_global_var (decl) - /* References might be private, but might be shared too. */ - || lang_hooks.decls.omp_privatize_by_reference (decl)); + return !(is_global_var (decl) + /* References might be private, but might be shared too. */ + || lang_hooks.decls.omp_privatize_by_reference (decl)); n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); if (n != NULL) - return (n->value & GOVD_SHARED) == 0; + return (n->value & GOVD_SHARED) == 0; } while (ctx->region_type == ORT_WORKSHARE); return false; @@ -5781,7 +5794,7 @@ static void gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, - enum omp_region_type region_type) + enum omp_region_type region_type) { struct gimplify_omp_ctx *ctx, *outer_ctx; struct gimplify_ctx gctx; @@ -5799,142 +5812,142 @@ tree decl; switch (OMP_CLAUSE_CODE (c)) - { - case OMP_CLAUSE_PRIVATE: - flags = GOVD_PRIVATE | GOVD_EXPLICIT; - if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c))) - { - flags |= GOVD_PRIVATE_OUTER_REF; - OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1; - } - else - notice_outer = false; - goto do_add; - case OMP_CLAUSE_SHARED: - flags = GOVD_SHARED | GOVD_EXPLICIT; - goto do_add; - case OMP_CLAUSE_FIRSTPRIVATE: - flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; - check_non_private = "firstprivate"; - goto do_add; - case OMP_CLAUSE_LASTPRIVATE: - flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT; - check_non_private = "lastprivate"; - goto do_add; - case OMP_CLAUSE_REDUCTION: - flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT; - check_non_private = "reduction"; - goto do_add; - - do_add: - decl = OMP_CLAUSE_DECL (c); - if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) - { - remove = true; - break; - } - omp_add_variable (ctx, decl, flags); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION - && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) - { - omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), - GOVD_LOCAL | GOVD_SEEN); - gimplify_omp_ctxp = ctx; - push_gimplify_context (&gctx); - - OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = gimple_seq_alloc (); - OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = gimple_seq_alloc (); - - gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), - &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)); - pop_gimplify_context - (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))); - push_gimplify_context (&gctx); - gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), - &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)); - pop_gimplify_context - (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c))); - OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE; - OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE; - - gimplify_omp_ctxp = outer_ctx; - } - else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE - && OMP_CLAUSE_LASTPRIVATE_STMT (c)) - { - gimplify_omp_ctxp = ctx; - push_gimplify_context (&gctx); - if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR) - { - tree bind = build3 (BIND_EXPR, void_type_node, NULL, - NULL, NULL); - TREE_SIDE_EFFECTS (bind) = 1; - BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c); - OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind; - } - gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c), - &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)); - pop_gimplify_context - (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))); - OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE; - - gimplify_omp_ctxp = outer_ctx; - } - if (notice_outer) - goto do_notice; - break; - - case OMP_CLAUSE_COPYIN: - case OMP_CLAUSE_COPYPRIVATE: - decl = OMP_CLAUSE_DECL (c); - if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) - { - remove = true; - break; - } - do_notice: - if (outer_ctx) - omp_notice_variable (outer_ctx, decl, true); - if (check_non_private - && region_type == ORT_WORKSHARE - && omp_check_private (ctx, decl)) - { - error ("%s variable %qE is private in outer context", - check_non_private, DECL_NAME (decl)); - remove = true; - } - break; - - case OMP_CLAUSE_IF: - OMP_CLAUSE_OPERAND (c, 0) - = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0)); - /* Fall through. */ - - case OMP_CLAUSE_SCHEDULE: - case OMP_CLAUSE_NUM_THREADS: - if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, - is_gimple_val, fb_rvalue) == GS_ERROR) - remove = true; - break; - - case OMP_CLAUSE_NOWAIT: - case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_UNTIED: - case OMP_CLAUSE_COLLAPSE: - break; - - case OMP_CLAUSE_DEFAULT: - ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c); - break; - - default: - gcc_unreachable (); - } + { + case OMP_CLAUSE_PRIVATE: + flags = GOVD_PRIVATE | GOVD_EXPLICIT; + if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c))) + { + flags |= GOVD_PRIVATE_OUTER_REF; + OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1; + } + else + notice_outer = false; + goto do_add; + case OMP_CLAUSE_SHARED: + flags = GOVD_SHARED | GOVD_EXPLICIT; + goto do_add; + case OMP_CLAUSE_FIRSTPRIVATE: + flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT; + check_non_private = "firstprivate"; + goto do_add; + case OMP_CLAUSE_LASTPRIVATE: + flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT; + check_non_private = "lastprivate"; + goto do_add; + case OMP_CLAUSE_REDUCTION: + flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT; + check_non_private = "reduction"; + goto do_add; + + do_add: + decl = OMP_CLAUSE_DECL (c); + if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) + { + remove = true; + break; + } + omp_add_variable (ctx, decl, flags); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) + { + omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), + GOVD_LOCAL | GOVD_SEEN); + gimplify_omp_ctxp = ctx; + push_gimplify_context (&gctx); + + OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = gimple_seq_alloc (); + OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = gimple_seq_alloc (); + + gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), + &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)); + pop_gimplify_context + (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))); + push_gimplify_context (&gctx); + gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), + &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)); + pop_gimplify_context + (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c))); + OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE; + OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE; + + gimplify_omp_ctxp = outer_ctx; + } + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE + && OMP_CLAUSE_LASTPRIVATE_STMT (c)) + { + gimplify_omp_ctxp = ctx; + push_gimplify_context (&gctx); + if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR) + { + tree bind = build3 (BIND_EXPR, void_type_node, NULL, + NULL, NULL); + TREE_SIDE_EFFECTS (bind) = 1; + BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c); + OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind; + } + gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c), + &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)); + pop_gimplify_context + (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))); + OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE; + + gimplify_omp_ctxp = outer_ctx; + } + if (notice_outer) + goto do_notice; + break; + + case OMP_CLAUSE_COPYIN: + case OMP_CLAUSE_COPYPRIVATE: + decl = OMP_CLAUSE_DECL (c); + if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node) + { + remove = true; + break; + } + do_notice: + if (outer_ctx) + omp_notice_variable (outer_ctx, decl, true); + if (check_non_private + && region_type == ORT_WORKSHARE + && omp_check_private (ctx, decl)) + { + error ("%s variable %qE is private in outer context", + check_non_private, DECL_NAME (decl)); + remove = true; + } + break; + + case OMP_CLAUSE_IF: + OMP_CLAUSE_OPERAND (c, 0) + = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0)); + /* Fall through. */ + + case OMP_CLAUSE_SCHEDULE: + case OMP_CLAUSE_NUM_THREADS: + if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, + is_gimple_val, fb_rvalue) == GS_ERROR) + remove = true; + break; + + case OMP_CLAUSE_NOWAIT: + case OMP_CLAUSE_ORDERED: + case OMP_CLAUSE_UNTIED: + case OMP_CLAUSE_COLLAPSE: + break; + + case OMP_CLAUSE_DEFAULT: + ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c); + break; + + default: + gcc_unreachable (); + } if (remove) - *list_p = OMP_CLAUSE_CHAIN (c); + *list_p = OMP_CLAUSE_CHAIN (c); else - list_p = &OMP_CLAUSE_CHAIN (c); + list_p = &OMP_CLAUSE_CHAIN (c); } gimplify_omp_ctxp = ctx; @@ -5965,26 +5978,26 @@ else private_debug = lang_hooks.decls.omp_private_debug_clause (decl, - !!(flags & GOVD_SHARED)); + !!(flags & GOVD_SHARED)); if (private_debug) code = OMP_CLAUSE_PRIVATE; else if (flags & GOVD_SHARED) { if (is_global_var (decl)) - { - struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; - while (ctx != NULL) - { - splay_tree_node on - = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); - if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE - | GOVD_PRIVATE | GOVD_REDUCTION)) != 0) - break; - ctx = ctx->outer_context; - } - if (ctx == NULL) - return 0; - } + { + struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context; + while (ctx != NULL) + { + splay_tree_node on + = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); + if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE + | GOVD_PRIVATE | GOVD_REDUCTION)) != 0) + break; + ctx = ctx->outer_context; + } + if (ctx == NULL) + return 0; + } code = OMP_CLAUSE_SHARED; } else if (flags & GOVD_PRIVATE) @@ -6019,58 +6032,58 @@ bool remove = false; switch (OMP_CLAUSE_CODE (c)) - { - case OMP_CLAUSE_PRIVATE: - case OMP_CLAUSE_SHARED: - case OMP_CLAUSE_FIRSTPRIVATE: - decl = OMP_CLAUSE_DECL (c); - n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); - remove = !(n->value & GOVD_SEEN); - if (! remove) - { - bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED; - if ((n->value & GOVD_DEBUG_PRIVATE) - || lang_hooks.decls.omp_private_debug_clause (decl, shared)) - { - gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0 - || ((n->value & GOVD_DATA_SHARE_CLASS) - == GOVD_PRIVATE)); - OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE); - OMP_CLAUSE_PRIVATE_DEBUG (c) = 1; - } - } - break; - - case OMP_CLAUSE_LASTPRIVATE: - /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to - accurately reflect the presence of a FIRSTPRIVATE clause. */ - decl = OMP_CLAUSE_DECL (c); - n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); - OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) - = (n->value & GOVD_FIRSTPRIVATE) != 0; - break; - - case OMP_CLAUSE_REDUCTION: - case OMP_CLAUSE_COPYIN: - case OMP_CLAUSE_COPYPRIVATE: - case OMP_CLAUSE_IF: - case OMP_CLAUSE_NUM_THREADS: - case OMP_CLAUSE_SCHEDULE: - case OMP_CLAUSE_NOWAIT: - case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_DEFAULT: - case OMP_CLAUSE_UNTIED: - case OMP_CLAUSE_COLLAPSE: - break; - - default: - gcc_unreachable (); - } + { + case OMP_CLAUSE_PRIVATE: + case OMP_CLAUSE_SHARED: + case OMP_CLAUSE_FIRSTPRIVATE: + decl = OMP_CLAUSE_DECL (c); + n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); + remove = !(n->value & GOVD_SEEN); + if (! remove) + { + bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED; + if ((n->value & GOVD_DEBUG_PRIVATE) + || lang_hooks.decls.omp_private_debug_clause (decl, shared)) + { + gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0 + || ((n->value & GOVD_DATA_SHARE_CLASS) + == GOVD_PRIVATE)); + OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE); + OMP_CLAUSE_PRIVATE_DEBUG (c) = 1; + } + } + break; + + case OMP_CLAUSE_LASTPRIVATE: + /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to + accurately reflect the presence of a FIRSTPRIVATE clause. */ + decl = OMP_CLAUSE_DECL (c); + n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); + OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) + = (n->value & GOVD_FIRSTPRIVATE) != 0; + break; + + case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_COPYIN: + case OMP_CLAUSE_COPYPRIVATE: + case OMP_CLAUSE_IF: + case OMP_CLAUSE_NUM_THREADS: + case OMP_CLAUSE_SCHEDULE: + case OMP_CLAUSE_NOWAIT: + case OMP_CLAUSE_ORDERED: + case OMP_CLAUSE_DEFAULT: + case OMP_CLAUSE_UNTIED: + case OMP_CLAUSE_COLLAPSE: + break; + + default: + gcc_unreachable (); + } if (remove) - *list_p = OMP_CLAUSE_CHAIN (c); + *list_p = OMP_CLAUSE_CHAIN (c); else - list_p = &OMP_CLAUSE_CHAIN (c); + list_p = &OMP_CLAUSE_CHAIN (c); } /* Add in any implicit data sharing. */ @@ -6094,9 +6107,9 @@ struct gimplify_ctx gctx; gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, - OMP_PARALLEL_COMBINED (expr) - ? ORT_COMBINED_PARALLEL - : ORT_PARALLEL); + OMP_PARALLEL_COMBINED (expr) + ? ORT_COMBINED_PARALLEL + : ORT_PARALLEL); push_gimplify_context (&gctx); @@ -6109,8 +6122,8 @@ gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr)); g = gimple_build_omp_parallel (body, - OMP_PARALLEL_CLAUSES (expr), - NULL_TREE, NULL_TREE); + OMP_PARALLEL_CLAUSES (expr), + NULL_TREE, NULL_TREE); if (OMP_PARALLEL_COMBINED (expr)) gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED); gimplify_seq_add_stmt (pre_p, g); @@ -6146,9 +6159,9 @@ gimplify_adjust_omp_clauses (&OMP_TASK_CLAUSES (expr)); g = gimple_build_omp_task (body, - OMP_TASK_CLAUSES (expr), - NULL_TREE, NULL_TREE, - NULL_TREE, NULL_TREE, NULL_TREE); + OMP_TASK_CLAUSES (expr), + NULL_TREE, NULL_TREE, + NULL_TREE, NULL_TREE, NULL_TREE); gimplify_seq_add_stmt (pre_p, g); *expr_p = NULL_TREE; } @@ -6168,7 +6181,7 @@ for_stmt = *expr_p; gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, - ORT_WORKSHARE); + ORT_WORKSHARE); /* Handle OMP_FOR_INIT. */ for_pre_body = NULL; @@ -6177,9 +6190,9 @@ for_body = gimple_seq_alloc (); gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) - == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt))); + == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt))); gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) - == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt))); + == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt))); for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) { t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i); @@ -6187,34 +6200,34 @@ decl = TREE_OPERAND (t, 0); gcc_assert (DECL_P (decl)); gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)) - || POINTER_TYPE_P (TREE_TYPE (decl))); + || POINTER_TYPE_P (TREE_TYPE (decl))); /* Make sure the iteration variable is private. */ if (omp_is_private (gimplify_omp_ctxp, decl)) - omp_notice_variable (gimplify_omp_ctxp, decl, true); + omp_notice_variable (gimplify_omp_ctxp, decl, true); else - omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN); + omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN); /* If DECL is not a gimple register, create a temporary variable to act - as an iteration counter. This is valid, since DECL cannot be - modified in the body of the loop. */ + as an iteration counter. This is valid, since DECL cannot be + modified in the body of the loop. */ if (!is_gimple_reg (decl)) - { - var = create_tmp_var (TREE_TYPE (decl), get_name (decl)); - TREE_OPERAND (t, 0) = var; - - gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var)); - - omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN); - } + { + var = create_tmp_var (TREE_TYPE (decl), get_name (decl)); + TREE_OPERAND (t, 0) = var; + + gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var)); + + omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN); + } else - var = decl; + var = decl; tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); ret = MIN (ret, tret); if (ret == GS_ERROR) - return ret; + return ret; /* Handle OMP_FOR_COND. */ t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i); @@ -6222,85 +6235,85 @@ gcc_assert (TREE_OPERAND (t, 0) == decl); tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); ret = MIN (ret, tret); /* Handle OMP_FOR_INCR. */ t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); switch (TREE_CODE (t)) - { - case PREINCREMENT_EXPR: - case POSTINCREMENT_EXPR: - t = build_int_cst (TREE_TYPE (decl), 1); - t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); - t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); - TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; - break; - - case PREDECREMENT_EXPR: - case POSTDECREMENT_EXPR: - t = build_int_cst (TREE_TYPE (decl), -1); - t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); - t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); - TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; - break; - - case MODIFY_EXPR: - gcc_assert (TREE_OPERAND (t, 0) == decl); - TREE_OPERAND (t, 0) = var; - - t = TREE_OPERAND (t, 1); - switch (TREE_CODE (t)) - { - case PLUS_EXPR: - if (TREE_OPERAND (t, 1) == decl) - { - TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0); - TREE_OPERAND (t, 0) = var; - break; - } - - /* Fallthru. */ - case MINUS_EXPR: - case POINTER_PLUS_EXPR: - gcc_assert (TREE_OPERAND (t, 0) == decl); - TREE_OPERAND (t, 0) = var; - break; - default: - gcc_unreachable (); - } - - tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, - is_gimple_val, fb_rvalue); - ret = MIN (ret, tret); - break; - - default: - gcc_unreachable (); - } + { + case PREINCREMENT_EXPR: + case POSTINCREMENT_EXPR: + t = build_int_cst (TREE_TYPE (decl), 1); + t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); + t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); + TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; + break; + + case PREDECREMENT_EXPR: + case POSTDECREMENT_EXPR: + t = build_int_cst (TREE_TYPE (decl), -1); + t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t); + t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t); + TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t; + break; + + case MODIFY_EXPR: + gcc_assert (TREE_OPERAND (t, 0) == decl); + TREE_OPERAND (t, 0) = var; + + t = TREE_OPERAND (t, 1); + switch (TREE_CODE (t)) + { + case PLUS_EXPR: + if (TREE_OPERAND (t, 1) == decl) + { + TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0); + TREE_OPERAND (t, 0) = var; + break; + } + + /* Fallthru. */ + case MINUS_EXPR: + case POINTER_PLUS_EXPR: + gcc_assert (TREE_OPERAND (t, 0) == decl); + TREE_OPERAND (t, 0) = var; + break; + default: + gcc_unreachable (); + } + + tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL, + is_gimple_val, fb_rvalue); + ret = MIN (ret, tret); + break; + + default: + gcc_unreachable (); + } if (var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1) - { - tree c; - for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c)) - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE - && OMP_CLAUSE_DECL (c) == decl - && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL) - { - t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); - gcc_assert (TREE_CODE (t) == MODIFY_EXPR); - gcc_assert (TREE_OPERAND (t, 0) == var); - t = TREE_OPERAND (t, 1); - gcc_assert (TREE_CODE (t) == PLUS_EXPR - || TREE_CODE (t) == MINUS_EXPR - || TREE_CODE (t) == POINTER_PLUS_EXPR); - gcc_assert (TREE_OPERAND (t, 0) == var); - t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl, - TREE_OPERAND (t, 1)); - gimplify_assign (decl, t, - &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)); - } - } + { + tree c; + for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE + && OMP_CLAUSE_DECL (c) == decl + && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL) + { + t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i); + gcc_assert (TREE_CODE (t) == MODIFY_EXPR); + gcc_assert (TREE_OPERAND (t, 0) == var); + t = TREE_OPERAND (t, 1); + gcc_assert (TREE_CODE (t) == PLUS_EXPR + || TREE_CODE (t) == MINUS_EXPR + || TREE_CODE (t) == POINTER_PLUS_EXPR); + gcc_assert (TREE_OPERAND (t, 0) == var); + t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl, + TREE_OPERAND (t, 1)); + gimplify_assign (decl, t, + &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)); + } + } } gimplify_and_add (OMP_FOR_BODY (for_stmt), &for_body); @@ -6308,8 +6321,8 @@ gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt)); gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt), - TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), - for_pre_body); + TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), + for_pre_body); for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) { @@ -6367,19 +6380,19 @@ { expr = TREE_OPERAND (expr, 0); while (expr != addr - && (CONVERT_EXPR_P (expr) - || TREE_CODE (expr) == NON_LVALUE_EXPR) - && TREE_CODE (expr) == TREE_CODE (addr) - && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr))) - { - expr = TREE_OPERAND (expr, 0); - addr = TREE_OPERAND (addr, 0); - } + && (CONVERT_EXPR_P (expr) + || TREE_CODE (expr) == NON_LVALUE_EXPR) + && TREE_CODE (expr) == TREE_CODE (addr) + && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr))) + { + expr = TREE_OPERAND (expr, 0); + addr = TREE_OPERAND (addr, 0); + } if (expr == addr) - return true; + return true; return (TREE_CODE (addr) == ADDR_EXPR - && TREE_CODE (expr) == ADDR_EXPR - && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0)); + && TREE_CODE (expr) == ADDR_EXPR + && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0)); } if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0)) return true; @@ -6393,7 +6406,7 @@ static int goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr, - tree lhs_var) + tree lhs_var) { tree expr = *expr_p; int saw_lhs; @@ -6412,10 +6425,10 @@ case tcc_binary: case tcc_comparison: saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr, - lhs_var); + lhs_var); case tcc_unary: saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr, - lhs_var); + lhs_var); break; case tcc_expression: switch (TREE_CODE (expr)) @@ -6438,13 +6451,17 @@ default: break; } + break; + default: + break; + } if (saw_lhs == 0) { enum gimplify_status gs; gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue); if (gs != GS_ALL_DONE) - saw_lhs = -1; + saw_lhs = -1; } return saw_lhs; @@ -6520,19 +6537,19 @@ the inner expression, so if a separate POST sequence was not used, the resulting sequence would be: - 1 t.1 = *p - 2 p = p - 1 - 3 t.2 = t.1 + 1 - 4 *p = t.2 + 1 t.1 = *p + 2 p = p - 1 + 3 t.2 = t.1 + 1 + 4 *p = t.2 However, the post-decrement operation in line #2 must not be evaluated until after the store to *p at line #4, so the correct sequence should be: - 1 t.1 = *p - 2 t.2 = t.1 + 1 - 3 *p = t.2 - 4 p = p - 1 + 1 t.1 = *p + 2 t.2 = t.1 + 1 + 3 *p = t.2 + 4 p = p - 1 So, by specifying a separate post queue, it is possible to emit the post side-effects in the correct order. @@ -6561,7 +6578,7 @@ enum gimplify_status gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, - bool (*gimple_test_f) (tree), fallback_t fallback) + bool (*gimple_test_f) (tree), fallback_t fallback) { tree tmp; gimple_seq internal_pre = NULL; @@ -6595,7 +6612,7 @@ || gimple_test_f == is_gimple_mem_ref_addr) gcc_assert (fallback & fb_rvalue); else if (gimple_test_f == is_gimple_min_lval - || gimple_test_f == is_gimple_lvalue) + || gimple_test_f == is_gimple_lvalue) gcc_assert (fallback & fb_lvalue); else if (gimple_test_f == is_gimple_addressable) gcc_assert (fallback & fb_either); @@ -6604,8 +6621,8 @@ else { /* We should have recognized the GIMPLE_TEST_F predicate to - know what kind of fallback to use in case a temporary is - needed to hold the value or address of *EXPR_P. */ + know what kind of fallback to use in case a temporary is + needed to hold the value or address of *EXPR_P. */ gcc_unreachable (); } @@ -6640,7 +6657,7 @@ do { /* Strip away as many useless type conversions as possible - at the toplevel. */ + at the toplevel. */ STRIP_USELESS_TYPE_CONVERSION (*expr_p); /* Remember the expr. */ @@ -6648,25 +6665,25 @@ /* Die, die, die, my darling. */ if (save_expr == error_mark_node - || (TREE_TYPE (save_expr) - && TREE_TYPE (save_expr) == error_mark_node)) - { - ret = GS_ERROR; - break; - } + || (TREE_TYPE (save_expr) + && TREE_TYPE (save_expr) == error_mark_node)) + { + ret = GS_ERROR; + break; + } /* Do any language-specific gimplification. */ ret = ((enum gimplify_status) - lang_hooks.gimplify_expr (expr_p, pre_p, post_p)); + lang_hooks.gimplify_expr (expr_p, pre_p, post_p)); if (ret == GS_OK) - { - if (*expr_p == NULL_TREE) - break; - if (*expr_p != save_expr) - continue; - } + { + if (*expr_p == NULL_TREE) + break; + if (*expr_p != save_expr) + continue; + } else if (ret != GS_UNHANDLED) - break; + break; /* Make sure that all the cases set 'ret' appropriately. */ ret = GS_UNHANDLED; @@ -7307,7 +7324,7 @@ if (ret == GS_ERROR) { if (is_statement) - *expr_p = NULL; + *expr_p = NULL; goto out; } @@ -7318,67 +7335,67 @@ if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p)) { /* We aren't looking for a value, and we don't have a valid - statement. If it doesn't have side-effects, throw it away. */ + statement. If it doesn't have side-effects, throw it away. */ if (!TREE_SIDE_EFFECTS (*expr_p)) - *expr_p = NULL; + *expr_p = NULL; else if (!TREE_THIS_VOLATILE (*expr_p)) - { - /* This is probably a _REF that contains something nested that - has side effects. Recurse through the operands to find it. */ - enum tree_code code = TREE_CODE (*expr_p); - - switch (code) - { - case COMPONENT_REF: - case REALPART_EXPR: - case IMAGPART_EXPR: - case VIEW_CONVERT_EXPR: - gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, - gimple_test_f, fallback); - break; - - case ARRAY_REF: - case ARRAY_RANGE_REF: - gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, - gimple_test_f, fallback); - gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, - gimple_test_f, fallback); - break; - - default: - /* Anything else with side-effects must be converted to - a valid statement before we get here. */ - gcc_unreachable (); - } - - *expr_p = NULL; - } + { + /* This is probably a _REF that contains something nested that + has side effects. Recurse through the operands to find it. */ + enum tree_code code = TREE_CODE (*expr_p); + + switch (code) + { + case COMPONENT_REF: + case REALPART_EXPR: + case IMAGPART_EXPR: + case VIEW_CONVERT_EXPR: + gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, + gimple_test_f, fallback); + break; + + case ARRAY_REF: + case ARRAY_RANGE_REF: + gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, + gimple_test_f, fallback); + gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, + gimple_test_f, fallback); + break; + + default: + /* Anything else with side-effects must be converted to + a valid statement before we get here. */ + gcc_unreachable (); + } + + *expr_p = NULL; + } else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)) - && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode) - { - /* Historically, the compiler has treated a bare reference - to a non-BLKmode volatile lvalue as forcing a load. */ - tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p)); - - /* Normally, we do not want to create a temporary for a - TREE_ADDRESSABLE type because such a type should not be - copied by bitwise-assignment. However, we make an - exception here, as all we are doing here is ensuring that - we read the bytes that make up the type. We use - create_tmp_var_raw because create_tmp_var will abort when - given a TREE_ADDRESSABLE type. */ - tree tmp = create_tmp_var_raw (type, "vol"); - gimple_add_tmp_var (tmp); - gimplify_assign (tmp, *expr_p, pre_p); - *expr_p = NULL; - } + && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode) + { + /* Historically, the compiler has treated a bare reference + to a non-BLKmode volatile lvalue as forcing a load. */ + tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p)); + + /* Normally, we do not want to create a temporary for a + TREE_ADDRESSABLE type because such a type should not be + copied by bitwise-assignment. However, we make an + exception here, as all we are doing here is ensuring that + we read the bytes that make up the type. We use + create_tmp_var_raw because create_tmp_var will abort when + given a TREE_ADDRESSABLE type. */ + tree tmp = create_tmp_var_raw (type, "vol"); + gimple_add_tmp_var (tmp); + gimplify_assign (tmp, *expr_p, pre_p); + *expr_p = NULL; + } else - /* We can't do anything useful with a volatile reference to - an incomplete type, so just throw it away. Likewise for - a BLKmode type, since any implicit inner load should - already have been turned into an explicit one by the - gimplification process. */ - *expr_p = NULL; + /* We can't do anything useful with a volatile reference to + an incomplete type, so just throw it away. Likewise for + a BLKmode type, since any implicit inner load should + already have been turned into an explicit one by the + gimplification process. */ + *expr_p = NULL; } /* If we are gimplifying at the statement level, we're done. Tack @@ -7390,22 +7407,22 @@ *expr_p = NULL_TREE; if (!gimple_seq_empty_p (internal_pre) - || !gimple_seq_empty_p (internal_post)) - { - gimplify_seq_add_seq (&internal_pre, internal_post); - gimplify_seq_add_seq (pre_p, internal_pre); - } + || !gimple_seq_empty_p (internal_post)) + { + gimplify_seq_add_seq (&internal_pre, internal_post); + gimplify_seq_add_seq (pre_p, internal_pre); + } /* The result of gimplifying *EXPR_P is going to be the last few - statements in *PRE_P and *POST_P. Add location information - to all the statements that were added by the gimplification - helpers. */ + statements in *PRE_P and *POST_P. Add location information + to all the statements that were added by the gimplification + helpers. */ if (!gimple_seq_empty_p (*pre_p)) - annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location); + annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location); if (!gimple_seq_empty_p (*post_p)) - annotate_all_with_location_after (*post_p, post_last_gsi, - input_location); + annotate_all_with_location_after (*post_p, post_last_gsi, + input_location); goto out; } @@ -7416,24 +7433,24 @@ enum tree_code code = TREE_CODE (*expr_p); /* These expressions should already be in gimple IR form. */ gcc_assert (code != MODIFY_EXPR - && code != ASM_EXPR - && code != BIND_EXPR - && code != CATCH_EXPR - && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr) - && code != EH_FILTER_EXPR - && code != GOTO_EXPR - && code != LABEL_EXPR - && code != LOOP_EXPR - && code != SWITCH_EXPR - && code != TRY_FINALLY_EXPR - && code != OMP_CRITICAL - && code != OMP_FOR - && code != OMP_MASTER - && code != OMP_ORDERED - && code != OMP_PARALLEL - && code != OMP_SECTIONS - && code != OMP_SECTION - && code != OMP_SINGLE); + && code != ASM_EXPR + && code != BIND_EXPR + && code != CATCH_EXPR + && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr) + && code != EH_FILTER_EXPR + && code != GOTO_EXPR + && code != LABEL_EXPR + && code != LOOP_EXPR + && code != SWITCH_EXPR + && code != TRY_FINALLY_EXPR + && code != OMP_CRITICAL + && code != OMP_FOR + && code != OMP_MASTER + && code != OMP_ORDERED + && code != OMP_PARALLEL + && code != OMP_SECTIONS + && code != OMP_SECTION + && code != OMP_SINGLE); } #endif @@ -7457,8 +7474,8 @@ && is_gimple_addressable (*expr_p)) { /* An lvalue will do. Take the address of the expression, store it - in a temporary, and replace the expression with an INDIRECT_REF of - that temporary. */ + in a temporary, and replace the expression with an INDIRECT_REF of + that temporary. */ tmp = build_fold_addr_expr_loc (input_location, *expr_p); gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); *expr_p = build_simple_mem_ref (tmp); @@ -7466,40 +7483,40 @@ else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p)) { /* An rvalue will do. Assign the gimplified expression into a - new temporary TMP and replace the original expression with - TMP. First, make sure that the expression has a type so that - it can be assigned into a temporary. */ + new temporary TMP and replace the original expression with + TMP. First, make sure that the expression has a type so that + it can be assigned into a temporary. */ gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p))); if (!gimple_seq_empty_p (internal_post) || (fallback & fb_lvalue)) - /* The postqueue might change the value of the expression between - the initialization and use of the temporary, so we can't use a - formal temp. FIXME do we care? */ - { - *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); - if (TREE_CODE (TREE_TYPE (*expr_p)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (*expr_p)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (*expr_p) = 1; - } + /* The postqueue might change the value of the expression between + the initialization and use of the temporary, so we can't use a + formal temp. FIXME do we care? */ + { + *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); + if (TREE_CODE (TREE_TYPE (*expr_p)) == COMPLEX_TYPE + || TREE_CODE (TREE_TYPE (*expr_p)) == VECTOR_TYPE) + DECL_GIMPLE_REG_P (*expr_p) = 1; + } else - *expr_p = get_formal_tmp_var (*expr_p, pre_p); + *expr_p = get_formal_tmp_var (*expr_p, pre_p); } else { #ifdef ENABLE_GIMPLE_CHECKING if (!(fallback & fb_mayfail)) - { - fprintf (stderr, "gimplification failed:\n"); - print_generic_expr (stderr, *expr_p, 0); - debug_tree (*expr_p); - internal_error ("gimplification failed"); - } + { + fprintf (stderr, "gimplification failed:\n"); + print_generic_expr (stderr, *expr_p, 0); + debug_tree (*expr_p); + internal_error ("gimplification failed"); + } #endif gcc_assert (fallback & fb_mayfail); /* If this is an asm statement, and the user asked for the - impossible, don't die. Fail and let gimplify_asm_expr - issue an error. */ + impossible, don't die. Fail and let gimplify_asm_expr + issue an error. */ ret = GS_ERROR; goto out; } @@ -7549,10 +7566,10 @@ gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p); for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - { - TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type); - TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type); - } + { + TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type); + TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type); + } break; case ARRAY_TYPE: @@ -7592,18 +7609,18 @@ case POINTER_TYPE: case REFERENCE_TYPE: - /* We used to recurse on the pointed-to type here, which turned out to - be incorrect because its definition might refer to variables not - yet initialized at this point if a forward declaration is involved. - - It was actually useful for anonymous pointed-to types to ensure - that the sizes evaluation dominates every possible later use of the - values. Restricting to such types here would be safe since there - is no possible forward declaration around, but would introduce an - undesirable middle-end semantic to anonymity. We then defer to - front-ends the responsibility of ensuring that the sizes are - evaluated both early and late enough, e.g. by attaching artificial - type declarations to the tree. */ + /* We used to recurse on the pointed-to type here, which turned out to + be incorrect because its definition might refer to variables not + yet initialized at this point if a forward declaration is involved. + + It was actually useful for anonymous pointed-to types to ensure + that the sizes evaluation dominates every possible later use of the + values. Restricting to such types here would be safe since there + is no possible forward declaration around, but would introduce an + undesirable middle-end semantic to anonymity. We then defer to + front-ends the responsibility of ensuring that the sizes are + evaluated both early and late enough, e.g. by attaching artificial + type declarations to the tree. */ break; default: @@ -7832,7 +7849,7 @@ for promotion to gimple registers. We'll transform their uses as we find them. */ if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE) + || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE) && !TREE_THIS_VOLATILE (parm) && !needs_to_live_in_memory (parm)) DECL_GIMPLE_REG_P (parm) = 1; @@ -7931,94 +7948,95 @@ { case GIMPLE_COND: gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); break; case GIMPLE_SWITCH: gimplify_expr (gimple_switch_index_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); break; case GIMPLE_OMP_ATOMIC_LOAD: gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL, - is_gimple_val, fb_rvalue); + is_gimple_val, fb_rvalue); break; case GIMPLE_ASM: { - size_t i, noutputs = gimple_asm_noutputs (stmt); - const char *constraint, **oconstraints; - bool allows_mem, allows_reg, is_inout; - - oconstraints - = (const char **) alloca ((noutputs) * sizeof (const char *)); - for (i = 0; i < noutputs; i++) - { - tree op = gimple_asm_output_op (stmt, i); - constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); - oconstraints[i] = constraint; - parse_output_constraint (&constraint, i, 0, 0, &allows_mem, - &allows_reg, &is_inout); - gimplify_expr (&TREE_VALUE (op), &pre, NULL, - is_inout ? is_gimple_min_lval : is_gimple_lvalue, - fb_lvalue | fb_mayfail); - } - for (i = 0; i < gimple_asm_ninputs (stmt); i++) - { - tree op = gimple_asm_input_op (stmt, i); - constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); - parse_input_constraint (&constraint, 0, 0, noutputs, 0, - oconstraints, &allows_mem, &allows_reg); - if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem) - allows_reg = 0; - if (!allows_reg && allows_mem) - gimplify_expr (&TREE_VALUE (op), &pre, NULL, - is_gimple_lvalue, fb_lvalue | fb_mayfail); - else - gimplify_expr (&TREE_VALUE (op), &pre, NULL, - is_gimple_asm_val, fb_rvalue); - } + size_t i, noutputs = gimple_asm_noutputs (stmt); + const char *constraint, **oconstraints; + bool allows_mem, allows_reg, is_inout; + + oconstraints + = (const char **) alloca ((noutputs) * sizeof (const char *)); + for (i = 0; i < noutputs; i++) + { + tree op = gimple_asm_output_op (stmt, i); + constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); + oconstraints[i] = constraint; + parse_output_constraint (&constraint, i, 0, 0, &allows_mem, + &allows_reg, &is_inout); + gimplify_expr (&TREE_VALUE (op), &pre, NULL, + is_inout ? is_gimple_min_lval : is_gimple_lvalue, + fb_lvalue | fb_mayfail); + } + for (i = 0; i < gimple_asm_ninputs (stmt); i++) + { + tree op = gimple_asm_input_op (stmt, i); + constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op))); + parse_input_constraint (&constraint, 0, 0, noutputs, 0, + oconstraints, &allows_mem, &allows_reg); + if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem) + allows_reg = 0; + if (!allows_reg && allows_mem) + gimplify_expr (&TREE_VALUE (op), &pre, NULL, + is_gimple_lvalue, fb_lvalue | fb_mayfail); + else + gimplify_expr (&TREE_VALUE (op), &pre, NULL, + is_gimple_asm_val, fb_rvalue); + } } break; default: /* NOTE: We start gimplifying operands from last to first to - make sure that side-effects on the RHS of calls, assignments - and ASMs are executed before the LHS. The ordering is not - important for other statements. */ + make sure that side-effects on the RHS of calls, assignments + and ASMs are executed before the LHS. The ordering is not + important for other statements. */ num_ops = gimple_num_ops (stmt); orig_lhs = gimple_get_lhs (stmt); for (i = num_ops; i > 0; i--) - { - tree op = gimple_op (stmt, i - 1); - if (op == NULL_TREE) - continue; - if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt))) - gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue); - else if (i == 2 - && is_gimple_assign (stmt) - && num_ops == 2 - && get_gimple_rhs_class (gimple_expr_code (stmt)) - == GIMPLE_SINGLE_RHS) - gimplify_expr (&op, &pre, NULL, - rhs_predicate_for (gimple_assign_lhs (stmt)), - fb_rvalue); - else if (i == 2 && is_gimple_call (stmt)) - { - if (TREE_CODE (op) == FUNCTION_DECL) - continue; - gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue); - } - else - gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue); - gimple_set_op (stmt, i - 1, op); - } + { + tree op = gimple_op (stmt, i - 1); + if (op == NULL_TREE) + continue; + if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt))) + gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue); + else if (i == 2 + && is_gimple_assign (stmt) + && num_ops == 2 + && get_gimple_rhs_class (gimple_expr_code (stmt)) + == GIMPLE_SINGLE_RHS) + gimplify_expr (&op, &pre, NULL, + rhs_predicate_for (gimple_assign_lhs (stmt)), + fb_rvalue); + else if (i == 2 && is_gimple_call (stmt)) + { + if (TREE_CODE (op) == FUNCTION_DECL) + continue; + gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue); + } + else + gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue); + gimple_set_op (stmt, i - 1, op); + } lhs = gimple_get_lhs (stmt); /* If the LHS changed it in a way that requires a simple RHS, - create temporary. */ + create temporary. */ if (lhs && !is_gimple_reg (lhs)) { bool need_temp = false; + if (is_gimple_assign (stmt) && num_ops == 2 && get_gimple_rhs_class (gimple_expr_code (stmt)) @@ -8085,12 +8103,12 @@ if (!gimple_seq_empty_p (pre)) { if (gimple_in_ssa_p (cfun)) - { - gimple_stmt_iterator i; - - for (i = gsi_start (pre); !gsi_end_p (i); gsi_next (&i)) - mark_symbols_for_renaming (gsi_stmt (i)); - } + { + gimple_stmt_iterator i; + + for (i = gsi_start (pre); !gsi_end_p (i); gsi_next (&i)) + mark_symbols_for_renaming (gsi_stmt (i)); + } gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT); } if (post_stmt) @@ -8207,8 +8225,8 @@ tree force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr, - bool simple_p, tree var, bool before, - enum gsi_iterator_update m) + bool simple_p, tree var, bool before, + enum gsi_iterator_update m) { return force_gimple_operand_gsi_1 (gsi, expr, simple_p diff -r 561a7518be6b -r 1b10fe6932e1 gcc/passes.c --- a/gcc/passes.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/passes.c Sun Aug 21 07:53:12 2011 +0900 @@ -727,7 +727,12 @@ NEXT_PASS (pass_refactor_eh); NEXT_PASS (pass_lower_eh); NEXT_PASS (pass_build_cfg); + +#ifndef noCbC + //NEXT_PASS (pass_warn_function_return); +#else NEXT_PASS (pass_warn_function_return); +#endif NEXT_PASS (pass_build_cgraph_edges); *p = NULL; diff -r 561a7518be6b -r 1b10fe6932e1 gcc/tree-ssa-operands.c --- a/gcc/tree-ssa-operands.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/tree-ssa-operands.c Sun Aug 21 07:53:12 2011 +0900 @@ -34,6 +34,9 @@ #include "timevar.h" #include "langhooks.h" #include "ipa-reference.h" +#ifndef noCbC + #include "cbc-tree.h" +#endif /* This file contains the code required to manage the operands cache of the SSA optimizer. For every stmt, we maintain an operand cache in the stmt diff -r 561a7518be6b -r 1b10fe6932e1 gcc/tree.c --- a/gcc/tree.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/tree.c Sun Aug 21 07:53:12 2011 +0900 @@ -99,6 +99,10 @@ #undef DEFTREECODE #undef END_OF_BASE_TREE_CODES +#ifndef noCbC +#include "cbc-tree.h" +#endif + /* Each tree code class has an associated string representation. These must correspond to the tree_code_class entries. */ @@ -7328,6 +7332,28 @@ return type; } +#ifndef noCbC +tree +build_code_segment_type (tree value_type, tree arg_types) +{ + tree t; + hashval_t hashcode = 0; + + gcc_assert (TREE_CODE (value_type) == VOID_TYPE); + + /* Make a node of the sort we want. */ + t = make_node (FUNCTION_TYPE); + TREE_TYPE (t) = value_type; + TYPE_ARG_TYPES (t) = arg_types; + + CbC_IS_CODE_SEGMENT (t) = 1; + + if (!COMPLETE_TYPE_P (t)) + layout_type (t); + return t; +} +#endif + /* Computes the canonical argument types from the argument type list ARGTYPES. diff -r 561a7518be6b -r 1b10fe6932e1 gcc/tree.h --- a/gcc/tree.h Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/tree.h Sun Aug 21 07:53:12 2011 +0900 @@ -4210,6 +4210,9 @@ extern bool vec_member (const_tree, VEC(tree,gc) *); extern tree chain_index (int, tree); +#ifndef noCbC +extern tree build_code_segment_type (tree, tree); +#endif extern int attribute_list_equal (const_tree, const_tree); extern int attribute_list_contained (const_tree, const_tree); extern int tree_int_cst_equal (const_tree, const_tree);