diff options
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/config/darwin.h | 828 | ||||
-rw-r--r-- | gcc/config/slashify.c | 56 | ||||
-rw-r--r-- | gcc/config/t-darwin | 14 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 27 | ||||
-rw-r--r-- | gcc/cp/lex.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2038 | ||||
-rw-r--r-- | gcc/objcp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/objcp/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/objcp/plugin/lex.h | 32 | ||||
-rw-r--r-- | gcc/objcp/plugin/parser.c | 1902 | ||||
-rw-r--r-- | gcc/objcp/plugin/parser.h | 227 |
13 files changed, 2441 insertions, 2737 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d2c69fe33f..de8e127fdb6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,24 +1,7 @@ -2011-02-13 Mike Stump <mikestump@comcast.net> - - * config/t-darwin (build/slashify1): Harden against rebuilds. - (config/darwin.h.rebuild): Harden against parallel builds. - * config/slashify.c: Nix parms to quite the build. - 2011-02-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure: Regenerate. -2011-02-12 Mike Stump <mikestump@comcast.net> - - * config/t-darwin (build/slashify): Allow others to reuse easier. - -2011-02-12 Mike Stump <mikestump@comcast.net> - - * config/darwin.h: Make pretty. - * config/t-darwin (config/darwin.h.rebuild): Add. - (build/slashify): Add. - * config/slashify.c: Add. - 2011-02-12 Joseph Myers <joseph@codesourcery.com> PR driver/45731 @@ -67,7 +50,7 @@ 2011-02-12 Iain Sandoe <iains@gcc.gnu.org> * config/darwin.c (darwin_override_options): Add a hunk missed - from the commit of r168571. Trim comment line lengths and + from the commit of r168571. Trim comment line lengths and correct indents of the preceding block. 2011-02-12 Iain Sandoe <iains@gcc.gnu.org> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 4bcb88abc36..778ff1e3023 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -123,47 +123,46 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* True if pragma ms_struct is in effect. */ extern GTY(()) int darwin_ms_struct; -#define DRIVER_SELF_SPECS @( - "%{gfull:-g -fno-eliminate-unused-debug-symbols} %<gfull", - "%{gused:-g -feliminate-unused-debug-symbols} %<gused", - "%{fapple-kext|mkernel:-static}", - "%{shared:-Zdynamiclib} %<shared"@) - -#define DARWIN_CC1_SPEC @( - "%{findirect-virtual-calls: -fapple-kext} %<findirect-virtual-calls " - "%{fterminated-vtables: -fapple-kext} %<fterminated-vtables " - "%<filelist* %<framework*"@) - -#define SUBSUBTARGET_OVERRIDE_OPTIONS @( - do { - darwin_override_options (); - } while (0)@) - -#define SUBTARGET_C_COMMON_OVERRIDE_OPTIONS @( - do { - /* Sort out ObjC exceptions: If the runtime is NeXT we default to - sjlj for m32 only. */ - if (!global_options_set.x_flag_objc_sjlj_exceptions) - global_options.x_flag_objc_sjlj_exceptions - = flag_next_runtime && !TARGET_64BIT; - if (flag_mkernel || flag_apple_kext) - { - if (flag_use_cxa_atexit == 2) - flag_use_cxa_atexit = 0; - /* kexts should always be built without the coalesced sections - because the kernel loader doesn't grok such sections. */ - flag_weak = 0; - /* No RTTI in kexts. */ - flag_rtti = 0; - } - } while (0)@) +#define DRIVER_SELF_SPECS \ + "%{gfull:-g -fno-eliminate-unused-debug-symbols} %<gfull", \ + "%{gused:-g -feliminate-unused-debug-symbols} %<gused", \ + "%{fapple-kext|mkernel:-static}", \ + "%{shared:-Zdynamiclib} %<shared" + +#define DARWIN_CC1_SPEC \ + "%{findirect-virtual-calls: -fapple-kext} %<findirect-virtual-calls " \ + "%{fterminated-vtables: -fapple-kext} %<fterminated-vtables " \ + "%<filelist* %<framework*" + +#define SUBSUBTARGET_OVERRIDE_OPTIONS \ + do { \ + darwin_override_options (); \ + } while (0) + +#define SUBTARGET_C_COMMON_OVERRIDE_OPTIONS do { \ + /* Sort out ObjC exceptions: If the runtime is NeXT we default to \ + sjlj for m32 only. */ \ + if (!global_options_set.x_flag_objc_sjlj_exceptions) \ + global_options.x_flag_objc_sjlj_exceptions = \ + flag_next_runtime && !TARGET_64BIT; \ + if (flag_mkernel || flag_apple_kext) \ + { \ + if (flag_use_cxa_atexit == 2) \ + flag_use_cxa_atexit = 0; \ + /* kexts should always be built without the coalesced sections \ + because the kernel loader doesn't grok such sections. */ \ + flag_weak = 0; \ + /* No RTTI in kexts. */ \ + flag_rtti = 0; \ + } \ + } while (0) /* Machine dependent cpp options. Don't add more options here, add them to darwin_cpp_builtins in darwin-c.c. */ #undef CPP_SPEC -#define CPP_SPEC "%{static:%{!dynamic:-D__STATIC__}}%{!static:-D__DYNAMIC__}" @( - " %{pthread:-D_REENTRANT}"@) +#define CPP_SPEC "%{static:%{!dynamic:-D__STATIC__}}%{!static:-D__DYNAMIC__}" \ + " %{pthread:-D_REENTRANT}" /* This is mostly a clone of the standard LINK_COMMAND_SPEC, plus precomp, libtool, and fat build additions. @@ -173,31 +172,31 @@ extern GTY(()) int darwin_ms_struct; specifying the handling of options understood by generic Unix linkers, and for positional arguments like libraries. */ -#define LINK_COMMAND_SPEC_A @( - "%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: - %(linker) - %{flto*:%<fcompare-debug*} - %{flto*} - %l %X %{s} %{t} %{Z} %{u*} - %{e*} %{r} - %{o*}%{!o:-o a.out} - %{!nostdlib:%{!nostartfiles:%S}} - %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} - %{fopenmp|ftree-parallelize-loops=*: - %{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } - %{!nostdlib:%{!nodefaultlibs: - %(link_ssp) %(link_gcc_c_sequence) - }} - %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"@) +#define LINK_COMMAND_SPEC_A \ + "%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ + %(linker) \ + %{flto*:%<fcompare-debug*} \ + %{flto*} \ + %l %X %{s} %{t} %{Z} %{u*} \ + %{e*} %{r} \ + %{o*}%{!o:-o a.out} \ + %{!nostdlib:%{!nostartfiles:%S}} \ + %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \ + %{fopenmp|ftree-parallelize-loops=*: \ + %{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \ + %{!nostdlib:%{!nodefaultlibs:\ + %(link_ssp) %(link_gcc_c_sequence)\ + }}\ + %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}" #define DSYMUTIL "\ndsymutil" -#define DSYMUTIL_SPEC @( - "%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: - %{v} - %{gdwarf-2:%{!gstabs*:%{!g0: -idsym}}} - %{.c|.cc|.C|.cpp|.cp|.c++|.cxx|.CPP|.m|.mm: - %{gdwarf-2:%{!gstabs*:%{!g0: -dsym}}}}}}}}}}}"@) +#define DSYMUTIL_SPEC \ + "%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ + %{v} \ + %{gdwarf-2:%{!gstabs*:%{!g0: -idsym}}}\ + %{.c|.cc|.C|.cpp|.cp|.c++|.cxx|.CPP|.m|.mm: \ + %{gdwarf-2:%{!gstabs*:%{!g0: -dsym}}}}}}}}}}}" #define LINK_COMMAND_SPEC LINK_COMMAND_SPEC_A DSYMUTIL_SPEC @@ -210,8 +209,8 @@ extern GTY(()) int darwin_ms_struct; #define LINK_GCC_C_SEQUENCE_SPEC "%G %L" #ifdef TARGET_SYSTEM_ROOT -#define LINK_SYSROOT_SPEC @( - "%{isysroot*:-syslibroot %*;:-syslibroot " TARGET_SYSTEM_ROOT "}"@) +#define LINK_SYSROOT_SPEC \ + "%{isysroot*:-syslibroot %*;:-syslibroot " TARGET_SYSTEM_ROOT "}" #else #define LINK_SYSROOT_SPEC "%{isysroot*:-syslibroot %*}" #endif @@ -220,90 +219,90 @@ extern GTY(()) int darwin_ms_struct; 'Z' and 'no' prefixes). Note that options taking arguments may appear multiple times on a command line with different arguments each time, so put a * after their names so all of them get passed. */ -#define LINK_SPEC @( - "%{static}%{!static:-dynamic} - %:remove-outfile(-ldl) - %:remove-outfile(-lm) - %:remove-outfile(-lpthread) - %{fgnu-runtime: %{static|static-libgcc: - %:replace-outfile(-lobjc libobjc-gnu.a%s); - :%:replace-outfile(-lobjc -lobjc-gnu ) } } - %{static|static-libgcc|static-libgfortran:%:replace-outfile(-lgfortran libgfortran.a%s)} - %{static|static-libgcc|static-libstdc++|static-libgfortran:%:replace-outfile(-lgomp libgomp.a%s)} - %{static|static-libgcc|static-libstdc++:%:replace-outfile(-lstdc++ libstdc++.a%s)} - %{!Zdynamiclib: - %{Zforce_cpusubtype_ALL:-arch %(darwin_arch) -force_cpusubtype_ALL} - %{!Zforce_cpusubtype_ALL:-arch %(darwin_subarch)} - %{Zbundle:-bundle} - %{Zbundle_loader*:-bundle_loader %*} - %{client_name*} - %{compatibility_version*:%e-compatibility_version only allowed with -dynamiclib -} - %{current_version*:%e-current_version only allowed with -dynamiclib} - %{Zforce_flat_namespace:-force_flat_namespace} - %{Zinstall_name*:%e-install_name only allowed with -dynamiclib} - %{keep_private_externs} - %{private_bundle} - } - %{Zdynamiclib: -dylib - %{Zbundle:%e-bundle not allowed with -dynamiclib} - %{Zbundle_loader*:%e-bundle_loader not allowed with -dynamiclib} - %{client_name*:%e-client_name not allowed with -dynamiclib} - %{compatibility_version*:-dylib_compatibility_version %*} - %{current_version*:-dylib_current_version %*} - %{Zforce_cpusubtype_ALL:-arch %(darwin_arch)} - %{!Zforce_cpusubtype_ALL: -arch %(darwin_subarch)} - %{Zforce_flat_namespace:%e-force_flat_namespace not allowed with -dynamiclib} - %{Zinstall_name*:-dylib_install_name %*} - %{keep_private_externs:%e-keep_private_externs not allowed with -dynamiclib} - %{private_bundle:%e-private_bundle not allowed with -dynamiclib} - } - %{Zall_load:-all_load} - %{Zallowable_client*:-allowable_client %*} - %{Zbind_at_load:-bind_at_load} - %{Zarch_errors_fatal:-arch_errors_fatal} - %{Zdead_strip:-dead_strip} - %{Zno_dead_strip_inits_and_terms:-no_dead_strip_inits_and_terms} - %{Zdylib_file*:-dylib_file %*} - %{Zdynamic:-dynamic} - %{Zexported_symbols_list*:-exported_symbols_list %*} - %{Zflat_namespace:-flat_namespace} - %{headerpad_max_install_names} - %{Zimage_base*:-image_base %*} - %{Zinit*:-init %*} - %{!mmacosx-version-min=*:-macosx_version_min %(darwin_minversion)} - %{mmacosx-version-min=*:-macosx_version_min %*} - %{nomultidefs} - %{Zmulti_module:-multi_module} %{Zsingle_module:-single_module} - %{Zmultiply_defined*:-multiply_defined %*} - %{!Zmultiply_defined*:%{shared-libgcc: - %:version-compare(< 10.5 mmacosx-version-min= -multiply_defined) - %:version-compare(< 10.5 mmacosx-version-min= suppress)}} - %{Zmultiplydefinedunused*:-multiply_defined_unused %*} - %{fpie:-pie} - %{prebind} %{noprebind} %{nofixprebinding} %{prebind_all_twolevel_modules} - %{read_only_relocs} - %{sectcreate*} %{sectorder*} %{seg1addr*} %{segprot*} - %{Zsegaddr*:-segaddr %*} - %{Zsegs_read_only_addr*:-segs_read_only_addr %*} - %{Zsegs_read_write_addr*:-segs_read_write_addr %*} - %{Zseg_addr_table*: -seg_addr_table %*} - %{Zfn_seg_addr_table_filename*:-seg_addr_table_filename %*} - %{sub_library*} %{sub_umbrella*} - " LINK_SYSROOT_SPEC " - %{twolevel_namespace} %{twolevel_namespace_hints} - %{Zumbrella*: -umbrella %*} - %{undefined*} - %{Zunexported_symbols_list*:-unexported_symbols_list %*} - %{Zweak_reference_mismatches*:-weak_reference_mismatches %*} - %{!Zweak_reference_mismatches*:-weak_reference_mismatches non-weak} - %{X} - %{y*} - %{w} - %{pagezero_size*} %{segs_read_*} %{seglinkedit} %{noseglinkedit} - %{sectalign*} %{sectobjectsymbols*} %{segcreate*} %{whyload} - %{whatsloaded} %{dylinker_install_name*} - %{dylinker} %{Mach} "@) +#define LINK_SPEC \ + "%{static}%{!static:-dynamic} \ + %:remove-outfile(-ldl) \ + %:remove-outfile(-lm) \ + %:remove-outfile(-lpthread) \ + %{fgnu-runtime: %{static|static-libgcc: \ + %:replace-outfile(-lobjc libobjc-gnu.a%s); \ + :%:replace-outfile(-lobjc -lobjc-gnu ) } }\ + %{static|static-libgcc|static-libgfortran:%:replace-outfile(-lgfortran libgfortran.a%s)}\ + %{static|static-libgcc|static-libstdc++|static-libgfortran:%:replace-outfile(-lgomp libgomp.a%s)}\ + %{static|static-libgcc|static-libstdc++:%:replace-outfile(-lstdc++ libstdc++.a%s)}\ + %{!Zdynamiclib: \ + %{Zforce_cpusubtype_ALL:-arch %(darwin_arch) -force_cpusubtype_ALL} \ + %{!Zforce_cpusubtype_ALL:-arch %(darwin_subarch)} \ + %{Zbundle:-bundle} \ + %{Zbundle_loader*:-bundle_loader %*} \ + %{client_name*} \ + %{compatibility_version*:%e-compatibility_version only allowed with -dynamiclib\ +} \ + %{current_version*:%e-current_version only allowed with -dynamiclib} \ + %{Zforce_flat_namespace:-force_flat_namespace} \ + %{Zinstall_name*:%e-install_name only allowed with -dynamiclib} \ + %{keep_private_externs} \ + %{private_bundle} \ + } \ + %{Zdynamiclib: -dylib \ + %{Zbundle:%e-bundle not allowed with -dynamiclib} \ + %{Zbundle_loader*:%e-bundle_loader not allowed with -dynamiclib} \ + %{client_name*:%e-client_name not allowed with -dynamiclib} \ + %{compatibility_version*:-dylib_compatibility_version %*} \ + %{current_version*:-dylib_current_version %*} \ + %{Zforce_cpusubtype_ALL:-arch %(darwin_arch)} \ + %{!Zforce_cpusubtype_ALL: -arch %(darwin_subarch)} \ + %{Zforce_flat_namespace:%e-force_flat_namespace not allowed with -dynamiclib} \ + %{Zinstall_name*:-dylib_install_name %*} \ + %{keep_private_externs:%e-keep_private_externs not allowed with -dynamiclib} \ + %{private_bundle:%e-private_bundle not allowed with -dynamiclib} \ + } \ + %{Zall_load:-all_load} \ + %{Zallowable_client*:-allowable_client %*} \ + %{Zbind_at_load:-bind_at_load} \ + %{Zarch_errors_fatal:-arch_errors_fatal} \ + %{Zdead_strip:-dead_strip} \ + %{Zno_dead_strip_inits_and_terms:-no_dead_strip_inits_and_terms} \ + %{Zdylib_file*:-dylib_file %*} \ + %{Zdynamic:-dynamic}\ + %{Zexported_symbols_list*:-exported_symbols_list %*} \ + %{Zflat_namespace:-flat_namespace} \ + %{headerpad_max_install_names} \ + %{Zimage_base*:-image_base %*} \ + %{Zinit*:-init %*} \ + %{!mmacosx-version-min=*:-macosx_version_min %(darwin_minversion)} \ + %{mmacosx-version-min=*:-macosx_version_min %*} \ + %{nomultidefs} \ + %{Zmulti_module:-multi_module} %{Zsingle_module:-single_module} \ + %{Zmultiply_defined*:-multiply_defined %*} \ + %{!Zmultiply_defined*:%{shared-libgcc: \ + %:version-compare(< 10.5 mmacosx-version-min= -multiply_defined) \ + %:version-compare(< 10.5 mmacosx-version-min= suppress)}} \ + %{Zmultiplydefinedunused*:-multiply_defined_unused %*} \ + %{fpie:-pie} \ + %{prebind} %{noprebind} %{nofixprebinding} %{prebind_all_twolevel_modules} \ + %{read_only_relocs} \ + %{sectcreate*} %{sectorder*} %{seg1addr*} %{segprot*} \ + %{Zsegaddr*:-segaddr %*} \ + %{Zsegs_read_only_addr*:-segs_read_only_addr %*} \ + %{Zsegs_read_write_addr*:-segs_read_write_addr %*} \ + %{Zseg_addr_table*: -seg_addr_table %*} \ + %{Zfn_seg_addr_table_filename*:-seg_addr_table_filename %*} \ + %{sub_library*} %{sub_umbrella*} \ + " LINK_SYSROOT_SPEC " \ + %{twolevel_namespace} %{twolevel_namespace_hints} \ + %{Zumbrella*: -umbrella %*} \ + %{undefined*} \ + %{Zunexported_symbols_list*:-unexported_symbols_list %*} \ + %{Zweak_reference_mismatches*:-weak_reference_mismatches %*} \ + %{!Zweak_reference_mismatches*:-weak_reference_mismatches non-weak} \ + %{X} \ + %{y*} \ + %{w} \ + %{pagezero_size*} %{segs_read_*} %{seglinkedit} %{noseglinkedit} \ + %{sectalign*} %{sectobjectsymbols*} %{segcreate*} %{whyload} \ + %{whatsloaded} %{dylinker_install_name*} \ + %{dylinker} %{Mach} " /* Machine dependent libraries. */ @@ -324,19 +323,19 @@ extern GTY(()) int darwin_ms_struct; If it is linked against, it has to be before -lgcc, because it may need symbols from -lgcc. */ #undef REAL_LIBGCC_SPEC -#define REAL_LIBGCC_SPEC @( - "%{static-libgcc|static: -lgcc_eh -lgcc; - shared-libgcc|fexceptions|fgnu-runtime: - %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) - %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) - %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) - %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) - -lgcc ; - :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) - %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) - %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) - %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) - -lgcc }"@) +#define REAL_LIBGCC_SPEC \ + "%{static-libgcc|static: -lgcc_eh -lgcc; \ + shared-libgcc|fexceptions|fgnu-runtime: \ + %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) \ + %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \ + %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \ + %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \ + -lgcc ; \ + :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \ + %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \ + %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \ + %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \ + -lgcc }" /* We specify crt0.o as -lcrt0.o so that ld will search the library path. @@ -346,42 +345,42 @@ extern GTY(()) int darwin_ms_struct; powerpc program built. */ #undef STARTFILE_SPEC -#define STARTFILE_SPEC @( - "%{Zdynamiclib: %(darwin_dylib1) } - %{!Zdynamiclib:%{Zbundle:%{!static:-lbundle1.o}} - %{!Zbundle:%{pg:%{static:-lgcrt0.o} - %{!static:%{object:-lgcrt0.o} - %{!object:%{preload:-lgcrt0.o} - %{!preload:-lgcrt1.o %(darwin_crt2)}}}} - %{!pg:%{static:-lcrt0.o} - %{!static:%{object:-lcrt0.o} - %{!object:%{preload:-lcrt0.o} - %{!preload: %(darwin_crt1) - %(darwin_crt2)}}}}}} - %{shared-libgcc:%:version-compare(< 10.5 mmacosx-version-min= crt3.o%s)}"@) +#define STARTFILE_SPEC \ + "%{Zdynamiclib: %(darwin_dylib1) } \ + %{!Zdynamiclib:%{Zbundle:%{!static:-lbundle1.o}} \ + %{!Zbundle:%{pg:%{static:-lgcrt0.o} \ + %{!static:%{object:-lgcrt0.o} \ + %{!object:%{preload:-lgcrt0.o} \ + %{!preload:-lgcrt1.o %(darwin_crt2)}}}} \ + %{!pg:%{static:-lcrt0.o} \ + %{!static:%{object:-lcrt0.o} \ + %{!object:%{preload:-lcrt0.o} \ + %{!preload: %(darwin_crt1) \ + %(darwin_crt2)}}}}}} \ + %{shared-libgcc:%:version-compare(< 10.5 mmacosx-version-min= crt3.o%s)}" /* The native Darwin linker doesn't necessarily place files in the order that they're specified on the link line. Thus, it is pointless to put anything in ENDFILE_SPEC. */ /* #define ENDFILE_SPEC "" */ -#define DARWIN_EXTRA_SPECS @( - { "darwin_crt1", DARWIN_CRT1_SPEC }, - { "darwin_dylib1", DARWIN_DYLIB1_SPEC }, - { "darwin_minversion", DARWIN_MINVERSION_SPEC },@) +#define DARWIN_EXTRA_SPECS \ + { "darwin_crt1", DARWIN_CRT1_SPEC }, \ + { "darwin_dylib1", DARWIN_DYLIB1_SPEC }, \ + { "darwin_minversion", DARWIN_MINVERSION_SPEC }, -#define DARWIN_DYLIB1_SPEC @( - "%:version-compare(!> 10.5 mmacosx-version-min= -ldylib1.o) - %:version-compare(>= 10.5 mmacosx-version-min= -ldylib1.10.5.o)"@) +#define DARWIN_DYLIB1_SPEC \ + "%:version-compare(!> 10.5 mmacosx-version-min= -ldylib1.o) \ + %:version-compare(>= 10.5 mmacosx-version-min= -ldylib1.10.5.o)" -#define DARWIN_CRT1_SPEC @( - "%:version-compare(!> 10.5 mmacosx-version-min= -lcrt1.o) - %:version-compare(>= 10.5 mmacosx-version-min= -lcrt1.10.5.o)"@) +#define DARWIN_CRT1_SPEC \ + "%:version-compare(!> 10.5 mmacosx-version-min= -lcrt1.o) \ + %:version-compare(>= 10.5 mmacosx-version-min= -lcrt1.10.5.o)" /* Default Darwin ASM_SPEC, very simple. */ -#define ASM_SPEC "-arch %(darwin_arch) @( - %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} - %{static}"@) +#define ASM_SPEC "-arch %(darwin_arch) \ + %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \ + %{static}" /* We still allow output of STABS. */ @@ -424,27 +423,27 @@ extern GTY(()) int darwin_ms_struct; coalesced sections. Weak aliases (or any other kind of aliases) are not supported. Weak symbols that aren't visible outside the .s file are not supported. */ -#define ASM_WEAKEN_DECL(FILE, DECL, NAME, ALIAS) @( - do { - if (ALIAS) - { - warning (0, "alias definitions not supported in Mach-O; ignored"); - break; - } - - if (! DECL_EXTERNAL (DECL) && TREE_PUBLIC (DECL)) - targetm.asm_out.globalize_label (FILE, NAME); - if (DECL_EXTERNAL (DECL)) - fputs ("\t.weak_reference ", FILE); - else if (lookup_attribute ("weak_import", DECL_ATTRIBUTES (DECL))) - break; - else if (TREE_PUBLIC (DECL)) - fputs ("\t.weak_definition ", FILE); - else - break; - assemble_name (FILE, NAME); - fputc ('\n', FILE); - } while (0)@) +#define ASM_WEAKEN_DECL(FILE, DECL, NAME, ALIAS) \ + do { \ + if (ALIAS) \ + { \ + warning (0, "alias definitions not supported in Mach-O; ignored"); \ + break; \ + } \ + \ + if (! DECL_EXTERNAL (DECL) && TREE_PUBLIC (DECL)) \ + targetm.asm_out.globalize_label (FILE, NAME); \ + if (DECL_EXTERNAL (DECL)) \ + fputs ("\t.weak_reference ", FILE); \ + else if (lookup_attribute ("weak_import", DECL_ATTRIBUTES (DECL))) \ + break; \ + else if (TREE_PUBLIC (DECL)) \ + fputs ("\t.weak_definition ", FILE); \ + else \ + break; \ + assemble_name (FILE, NAME); \ + fputc ('\n', FILE); \ + } while (0) /* Darwin has the pthread routines in libSystem, which every program links to, so there's no need for weak-ness for that. */ @@ -525,24 +524,24 @@ extern GTY(()) int darwin_ms_struct; #undef TARGET_ASM_LTO_END #define TARGET_ASM_LTO_END darwin_asm_lto_end -#define ASM_OUTPUT_SKIP(FILE,SIZE) @( - fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", SIZE)@) +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", SIZE) /* Give ObjC methods pretty symbol names. */ #undef OBJC_GEN_METHOD_LABEL -#define OBJC_GEN_METHOD_LABEL(BUF,IS_INST,CLASS_NAME,CAT_NAME,SEL_NAME,NUM) @( - do { if (CAT_NAME) - sprintf (BUF, "%c[%s(%s) %s]", (IS_INST) ? '-' : '+', - (CLASS_NAME), (CAT_NAME), (SEL_NAME)); - else - sprintf (BUF, "%c[%s %s]", (IS_INST) ? '-' : '+', - (CLASS_NAME), (SEL_NAME)); - } while (0)@) +#define OBJC_GEN_METHOD_LABEL(BUF,IS_INST,CLASS_NAME,CAT_NAME,SEL_NAME,NUM) \ + do { if (CAT_NAME) \ + sprintf (BUF, "%c[%s(%s) %s]", (IS_INST) ? '-' : '+', \ + (CLASS_NAME), (CAT_NAME), (SEL_NAME)); \ + else \ + sprintf (BUF, "%c[%s %s]", (IS_INST) ? '-' : '+', \ + (CLASS_NAME), (SEL_NAME)); \ + } while (0) #undef ASM_DECLARE_OBJECT_NAME -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) @( - darwin_asm_declare_object_name ((FILE), (NAME), (DECL))@) +#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ + darwin_asm_declare_object_name ((FILE), (NAME), (DECL)) /* The RTTI data (e.g., __ti4name) is common and public (and static), but it does need to be referenced via indirect PIC data pointers. @@ -550,65 +549,65 @@ extern GTY(()) int darwin_ms_struct; that the name *is* defined in this module, so it doesn't need to make them indirect. */ -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) @( - do { - const char *xname = NAME; - if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) - xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); - if (! DECL_WEAK (DECL) - && ((TREE_STATIC (DECL) - && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) - || DECL_INITIAL (DECL))) - machopic_define_symbol (DECL_RTL (DECL)); - if ((TREE_STATIC (DECL) - && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) - || DECL_INITIAL (DECL)) - (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); - ASM_OUTPUT_FUNCTION_LABEL (FILE, xname, DECL); - } while (0)@) +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + do { \ + const char *xname = NAME; \ + if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \ + xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \ + if (! DECL_WEAK (DECL) \ + && ((TREE_STATIC (DECL) \ + && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \ + || DECL_INITIAL (DECL))) \ + machopic_define_symbol (DECL_RTL (DECL)); \ + if ((TREE_STATIC (DECL) \ + && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \ + || DECL_INITIAL (DECL)) \ + (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \ + ASM_OUTPUT_FUNCTION_LABEL (FILE, xname, DECL); \ + } while (0) #undef TARGET_ASM_DECLARE_CONSTANT_NAME #define TARGET_ASM_DECLARE_CONSTANT_NAME darwin_asm_declare_constant_name /* Wrap new method names in quotes so the assembler doesn't gag. - Make Objective-C internal symbols local and in doing this, we need + Make Objective-C internal symbols local and in doing this, we need to accommodate the name mangling done by c++ on file scope locals. */ int darwin_label_is_anonymous_local_objc_name (const char *name); #undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(FILE,NAME) @( - do { - const char *xname = (NAME); - if (! strcmp (xname, MACHOPIC_FUNCTION_BASE_NAME)) - machopic_output_function_base_name(FILE); - else if (xname[0] == '&' || xname[0] == '*') - { - int len = strlen (xname); - if (len > 6 && !strcmp ("$stub", xname + len - 5)) - machopic_validate_stub_or_non_lazy_ptr (xname); - else if (len > 7 && !strcmp ("$stub\"", xname + len - 6)) - machopic_validate_stub_or_non_lazy_ptr (xname); - else if (len > 14 && !strcmp ("$non_lazy_ptr", xname + len - 13)) - machopic_validate_stub_or_non_lazy_ptr (xname); - else if (len > 15 && !strcmp ("$non_lazy_ptr\"", xname + len - 14)) - machopic_validate_stub_or_non_lazy_ptr (xname); - if (xname[1] != '"' && name_needs_quotes (&xname[1])) - fprintf (FILE, "\"%s\"", &xname[1]); - else - fputs (&xname[1], FILE); - } - else if (xname[0] == '+' || xname[0] == '-') - fprintf (FILE, "\"%s\"", xname); - else if (darwin_label_is_anonymous_local_objc_name (xname)) - fprintf (FILE, "L%s", xname); - else if (!strncmp (xname, ".objc_class_name_", 17)) - fprintf (FILE, "%s", xname); - else if (xname[0] != '"' && name_needs_quotes (xname)) - fprintf (FILE, "\"%s\"", xname); - else - asm_fprintf (FILE, "%U%s", xname); - } while (0)@) +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ + do { \ + const char *xname = (NAME); \ + if (! strcmp (xname, MACHOPIC_FUNCTION_BASE_NAME)) \ + machopic_output_function_base_name(FILE); \ + else if (xname[0] == '&' || xname[0] == '*') \ + { \ + int len = strlen (xname); \ + if (len > 6 && !strcmp ("$stub", xname + len - 5)) \ + machopic_validate_stub_or_non_lazy_ptr (xname); \ + else if (len > 7 && !strcmp ("$stub\"", xname + len - 6)) \ + machopic_validate_stub_or_non_lazy_ptr (xname); \ + else if (len > 14 && !strcmp ("$non_lazy_ptr", xname + len - 13)) \ + machopic_validate_stub_or_non_lazy_ptr (xname); \ + else if (len > 15 && !strcmp ("$non_lazy_ptr\"", xname + len - 14)) \ + machopic_validate_stub_or_non_lazy_ptr (xname); \ + if (xname[1] != '"' && name_needs_quotes (&xname[1])) \ + fprintf (FILE, "\"%s\"", &xname[1]); \ + else \ + fputs (&xname[1], FILE); \ + } \ + else if (xname[0] == '+' || xname[0] == '-') \ + fprintf (FILE, "\"%s\"", xname); \ + else if (darwin_label_is_anonymous_local_objc_name (xname)) \ + fprintf (FILE, "L%s", xname); \ + else if (!strncmp (xname, ".objc_class_name_", 17)) \ + fprintf (FILE, "%s", xname); \ + else if (xname[0] != '"' && name_needs_quotes (xname)) \ + fprintf (FILE, "\"%s\"", xname); \ + else \ + asm_fprintf (FILE, "%U%s", xname); \ + } while (0) /* Output before executable code. */ #undef TEXT_SECTION_ASM_OP @@ -623,9 +622,9 @@ int darwin_label_is_anonymous_local_objc_name (const char *name); #define ALIGN_ASM_OP ".align" #undef ASM_OUTPUT_ALIGN -#define ASM_OUTPUT_ALIGN(FILE,LOG) @( - if ((LOG) != 0) - fprintf (FILE, "\t%s\t%d\n", ALIGN_ASM_OP, (LOG))@) +#define ASM_OUTPUT_ALIGN(FILE,LOG) \ + if ((LOG) != 0) \ + fprintf (FILE, "\t%s\t%d\n", ALIGN_ASM_OP, (LOG)) /* The maximum alignment which the object file format can support in bits. For Mach-O, this is 2^15 bytes. */ @@ -636,18 +635,18 @@ int darwin_label_is_anonymous_local_objc_name (const char *name); #define L2_MAX_OFILE_ALIGNMENT 15 /* These are the three variants that emit referenced blank space. */ -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) @( - darwin_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))@) +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ + darwin_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) #undef ASM_OUTPUT_ALIGNED_DECL_LOCAL -#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) @( - darwin_asm_output_aligned_decl_local - ((FILE), (DECL), (NAME), (SIZE), (ALIGN))@) +#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \ + darwin_asm_output_aligned_decl_local \ + ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) #undef ASM_OUTPUT_ALIGNED_DECL_COMMON -#define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN) @( - darwin_asm_output_aligned_decl_common - ((FILE), (DECL), (NAME), (SIZE), (ALIGN))@) +#define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN) \ + darwin_asm_output_aligned_decl_common \ + ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) /* The generic version, archs should over-ride where required. */ #define MACHOPIC_NL_SYMBOL_PTR_SECTION ".non_lazy_symbol_pointer" @@ -670,8 +669,8 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS]; #define TARGET_ASM_FUNCTION_SECTION darwin_function_section #undef TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS -#define TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS @( - darwin_function_switched_text_sections@) +#define TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS \ + darwin_function_switched_text_sections #undef TARGET_ASM_SELECT_RTX_SECTION #define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section @@ -683,27 +682,27 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS]; #define TARGET_ASM_RELOC_RW_MASK machopic_reloc_rw_mask -#define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) @( - do { - if (FILE) { - if (MACHOPIC_INDIRECT) - fprintf (FILE, "\t.lazy_reference "); - else - fprintf (FILE, "\t.reference "); - assemble_name (FILE, NAME); - fprintf (FILE, "\n"); - } - } while (0)@) - -#define ASM_DECLARE_CLASS_REFERENCE(FILE,NAME) @( - do { - if (FILE) { - fprintf (FILE, "\t"); - assemble_name (FILE, NAME); - fprintf (FILE, "=0\n"); - (*targetm.asm_out.globalize_label) (FILE, NAME); - } - } while (0)@) +#define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) \ + do { \ + if (FILE) { \ + if (MACHOPIC_INDIRECT) \ + fprintf (FILE, "\t.lazy_reference "); \ + else \ + fprintf (FILE, "\t.reference "); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } \ + } while (0) + +#define ASM_DECLARE_CLASS_REFERENCE(FILE,NAME) \ + do { \ + if (FILE) { \ + fprintf (FILE, "\t"); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "=0\n"); \ + (*targetm.asm_out.globalize_label) (FILE, NAME); \ + } \ + } while (0) /* Globalizing directive for a label. */ #define GLOBAL_ASM_OP "\t.globl " @@ -716,16 +715,16 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS]; #define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility /* Extra attributes for Darwin. */ -#define SUBTARGET_ATTRIBUTE_TABLE @( - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ - { "apple_kext_compatibility", 0, 0, false, true, false, - darwin_handle_kext_attribute }, - { "weak_import", 0, 0, true, false, false, - darwin_handle_weak_import_attribute }@) +#define SUBTARGET_ATTRIBUTE_TABLE \ + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ \ + { "apple_kext_compatibility", 0, 0, false, true, false, \ + darwin_handle_kext_attribute }, \ + { "weak_import", 0, 0, true, false, false, \ + darwin_handle_weak_import_attribute } #undef ASM_GENERATE_INTERNAL_LABEL -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) @( - sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))@) +#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ + sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM)) #undef TARGET_ASM_MARK_DECL_PRESERVED #define TARGET_ASM_MARK_DECL_PRESERVED darwin_mark_decl_preserved @@ -771,61 +770,61 @@ enum machopic_addr_class { #undef TARGET_STRIP_NAME_ENCODING #define TARGET_STRIP_NAME_ENCODING default_strip_name_encoding -#define GEN_BINDER_NAME_FOR_STUB(BUF,STUB,STUB_LENGTH) @( - do { - const char *const stub_ = (STUB); - char *buffer_ = (BUF); - strcpy (buffer_, stub_); - if (stub_[0] == '"') - { - strcpy (buffer_ + (STUB_LENGTH) - 1, "_binder\""); - } - else - { - strcpy (buffer_ + (STUB_LENGTH), "_binder"); - } - } while (0)@) - -#define GEN_SYMBOL_NAME_FOR_SYMBOL(BUF,SYMBOL,SYMBOL_LENGTH) @( - do { - const char *const symbol_ = (SYMBOL); - char *buffer_ = (BUF); - if (name_needs_quotes (symbol_) && symbol_[0] != '"') - { - sprintf (buffer_, "\"%s\"", symbol_); - } - else - { - strcpy (buffer_, symbol_); - } - } while (0)@) +#define GEN_BINDER_NAME_FOR_STUB(BUF,STUB,STUB_LENGTH) \ + do { \ + const char *const stub_ = (STUB); \ + char *buffer_ = (BUF); \ + strcpy (buffer_, stub_); \ + if (stub_[0] == '"') \ + { \ + strcpy (buffer_ + (STUB_LENGTH) - 1, "_binder\""); \ + } \ + else \ + { \ + strcpy (buffer_ + (STUB_LENGTH), "_binder"); \ + } \ + } while (0) + +#define GEN_SYMBOL_NAME_FOR_SYMBOL(BUF,SYMBOL,SYMBOL_LENGTH) \ + do { \ + const char *const symbol_ = (SYMBOL); \ + char *buffer_ = (BUF); \ + if (name_needs_quotes (symbol_) && symbol_[0] != '"') \ + { \ + sprintf (buffer_, "\"%s\"", symbol_); \ + } \ + else \ + { \ + strcpy (buffer_, symbol_); \ + } \ + } while (0) /* Given a symbol name string, create the lazy pointer version of the symbol name. */ -#define GEN_LAZY_PTR_NAME_FOR_SYMBOL(BUF,SYMBOL,SYMBOL_LENGTH) @( - do { - const char *symbol_ = (SYMBOL); - char *buffer_ = (BUF); - if (symbol_[0] == '"') - { - strcpy (buffer_, "\"L"); - strcpy (buffer_ + 2, symbol_ + 1); - strcpy (buffer_ + (SYMBOL_LENGTH), "$lazy_ptr\""); - } - else if (name_needs_quotes (symbol_)) - { - strcpy (buffer_, "\"L"); - strcpy (buffer_ + 2, symbol_); - strcpy (buffer_ + (SYMBOL_LENGTH) + 2, "$lazy_ptr\""); - } - else - { - strcpy (buffer_, "L"); - strcpy (buffer_ + 1, symbol_); - strcpy (buffer_ + (SYMBOL_LENGTH) + 1, "$lazy_ptr"); - } - } while (0)@) +#define GEN_LAZY_PTR_NAME_FOR_SYMBOL(BUF,SYMBOL,SYMBOL_LENGTH) \ + do { \ + const char *symbol_ = (SYMBOL); \ + char *buffer_ = (BUF); \ + if (symbol_[0] == '"') \ + { \ + strcpy (buffer_, "\"L"); \ + strcpy (buffer_ + 2, symbol_ + 1); \ + strcpy (buffer_ + (SYMBOL_LENGTH), "$lazy_ptr\""); \ + } \ + else if (name_needs_quotes (symbol_)) \ + { \ + strcpy (buffer_, "\"L"); \ + strcpy (buffer_ + 2, symbol_); \ + strcpy (buffer_ + (SYMBOL_LENGTH) + 2, "$lazy_ptr\""); \ + } \ + else \ + { \ + strcpy (buffer_, "L"); \ + strcpy (buffer_ + 1, symbol_); \ + strcpy (buffer_ + (SYMBOL_LENGTH) + 1, "$lazy_ptr"); \ + } \ + } while (0) #define EH_FRAME_SECTION_NAME "__TEXT" #define EH_FRAME_SECTION_ATTR ",coalesced,no_toc+strip_static_syms+live_support" @@ -834,22 +833,22 @@ enum machopic_addr_class { #define JCR_SECTION_NAME "__DATA,jcr,regular,no_dead_strip" #undef ASM_PREFERRED_EH_DATA_FORMAT -#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) @( - (((CODE) == 2 && (GLOBAL) == 1) - ? (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4) : - ((CODE) == 1 || (GLOBAL) == 0) ? DW_EH_PE_pcrel : DW_EH_PE_absptr)@) +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ + (((CODE) == 2 && (GLOBAL) == 1) \ + ? (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4) : \ + ((CODE) == 1 || (GLOBAL) == 0) ? DW_EH_PE_pcrel : DW_EH_PE_absptr) -#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2) @( - darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)@) +#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2) \ + darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2) -#define ASM_OUTPUT_DWARF_OFFSET(FILE,SIZE,LABEL,BASE) @( - darwin_asm_output_dwarf_offset (FILE, SIZE, LABEL, BASE)@) +#define ASM_OUTPUT_DWARF_OFFSET(FILE,SIZE,LABEL,BASE) \ + darwin_asm_output_dwarf_offset (FILE, SIZE, LABEL, BASE) -#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE) @( - if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) { - darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR); - goto DONE; - }@) +#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE) \ + if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) { \ + darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR); \ + goto DONE; \ + } /* Experimentally, putting jump tables in text is faster on SPEC. Also this is needed for correctness for coalesced functions. */ @@ -864,16 +863,16 @@ enum machopic_addr_class { #undef TARGET_ASM_NAMED_SECTION #define TARGET_ASM_NAMED_SECTION darwin_asm_named_section -#define DARWIN_REGISTER_TARGET_PRAGMAS() @( - do { - if (!flag_preprocess_only) - cpp_register_pragma (parse_in, NULL, "mark", - darwin_pragma_ignore, false); - c_register_pragma (0, "options", darwin_pragma_options); - c_register_pragma (0, "segment", darwin_pragma_ignore); - c_register_pragma (0, "unused", darwin_pragma_unused); - c_register_pragma (0, "ms_struct", darwin_pragma_ms_struct); - } while (0)@) +#define DARWIN_REGISTER_TARGET_PRAGMAS() \ + do { \ + if (!flag_preprocess_only) \ + cpp_register_pragma (parse_in, NULL, "mark", \ + darwin_pragma_ignore, false); \ + c_register_pragma (0, "options", darwin_pragma_options); \ + c_register_pragma (0, "segment", darwin_pragma_ignore); \ + c_register_pragma (0, "unused", darwin_pragma_unused); \ + c_register_pragma (0, "ms_struct", darwin_pragma_ms_struct); \ + } while (0) #undef ASM_APP_ON #define ASM_APP_ON "" @@ -903,7 +902,7 @@ void add_framework_path (char *); #undef GOMP_SELF_SPECS #define GOMP_SELF_SPECS "" -/* Darwin disables section anchors by default. +/* Darwin disables section anchors by default. They should be enabled per arch where support exists in that arch. */ #define TARGET_ASM_OUTPUT_ANCHOR NULL #define DARWIN_SECTION_ANCHORS 0 @@ -921,31 +920,30 @@ void add_framework_path (char *); considered dangerous for library calls to send messages to stdout/stderr. */ -#define ENABLE_EXECUTE_STACK @( - extern void __enable_execute_stack (void *); - - void - __enable_execute_stack (void *addr) - { - extern int mprotect (void *, size_t, int); - extern int getpagesize (void); - static int size; - static long mask; - - char *page, *end; - - if (size == 0) - { - size = getpagesize(); - mask = ~((long) size - 1); - } - - page = (char *) (((long) addr) & mask); - end = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); - - /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */ - (void) mprotect (page, end - page, 7); - }@) +#define ENABLE_EXECUTE_STACK \ +extern void __enable_execute_stack (void *); \ +void \ +__enable_execute_stack (void *addr) \ +{ \ + extern int mprotect (void *, size_t, int); \ + extern int getpagesize (void); \ + static int size; \ + static long mask; \ + \ + char *page, *end; \ + \ + if (size == 0) \ + { \ + size = getpagesize(); \ + mask = ~((long) size - 1); \ + } \ + \ + page = (char *) (((long) addr) & mask); \ + end = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \ + \ + /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */ \ + (void) mprotect (page, end - page, 7); \ +} /* For Apple KEXTs, we make the constructors return this to match gcc 2.95. */ @@ -955,24 +953,24 @@ void add_framework_path (char *); /* We have target-specific builtins. */ #define TARGET_FOLD_BUILTIN darwin_fold_builtin -#define TARGET_OBJC_CONSTRUCT_STRING_OBJECT @( - darwin_objc_construct_string@) +#define TARGET_OBJC_CONSTRUCT_STRING_OBJECT \ + darwin_objc_construct_string -#define TARGET_STRING_OBJECT_REF_TYPE_P @( - darwin_cfstring_ref_p@) +#define TARGET_STRING_OBJECT_REF_TYPE_P \ + darwin_cfstring_ref_p #define TARGET_N_FORMAT_TYPES 1 #define TARGET_FORMAT_TYPES darwin_additional_format_types -#define TARGET_CHECK_STRING_OBJECT_FORMAT_ARG @( - darwin_check_cfstring_format_arg@) +#define TARGET_CHECK_STRING_OBJECT_FORMAT_ARG \ + darwin_check_cfstring_format_arg #define TARGET_HAS_TARGETCM 1 #ifndef USED_FOR_TARGET extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **); -#define GCC_DRIVER_HOST_INITIALIZATION @( - darwin_driver_init (&decoded_options_count, &decoded_options)@) +#define GCC_DRIVER_HOST_INITIALIZATION \ + darwin_driver_init (&decoded_options_count, &decoded_options) #endif /* The Apple assembler and linker do not support constructor priorities. */ diff --git a/gcc/config/slashify.c b/gcc/config/slashify.c deleted file mode 100644 index 555bf8831c3..00000000000 --- a/gcc/config/slashify.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Generate a slashified version of the input - Copyright (C) 2011 - Free Software Foundation, Inc. - Contributed by Mike Stump <mikestump@comcast.net> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - - -/* This is a small utility to slashify a source file so that one never - needs to stare at backslashes. */ - -#include <stdio.h> - -extern int main (void); - -int main (void) { - int c,c1; - int saw_start = 0; - while ((c=getchar ()) != EOF) { - if (c != '@') { - if (saw_start && c == '\n') { - putchar ('\\'); - } - putchar (c); - continue; - } - c1=getchar(); - if (c1 == EOF) { - putchar (c); - return 0; - } - if (!saw_start && c1 == '(') { - saw_start = 1; - } else if (saw_start && c1 == ')') { - saw_start = 0; - } else { - putchar (c); - putchar (c1); - } - } - return 0; -} diff --git a/gcc/config/t-darwin b/gcc/config/t-darwin index b8b872e73ea..24a7b90c3e2 100644 --- a/gcc/config/t-darwin +++ b/gcc/config/t-darwin @@ -17,20 +17,6 @@ # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. -build/slashify1: $(srcdir)/config/slashify.c - $(COMPILER_FOR_BUILD) $(BUILD_COMPILERFLAGS) $(BUILD_CPPFLAGS) $(srcdir)/config/slashify.c -o $@ - -$(srcdir)/config/darwin.h: config/darwin.h.rebuild - -config/darwin.h.rebuild: build/slashify1 - @$(mkinstalldirs) config - @if [ ! -e $(srcdir)/config/darwin.h \ - -o $(srcdir)/config/darwin.h -nt config/darwin.h ]; then \ - cp $(srcdir)/config/darwin-sections.def \ - config/darwin-sections.def && \ - build/slashify1 < $(srcdir)/config/darwin.h >config/darwin.h; \ - fi - darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(REAL_H) insn-config.h \ conditions.h insn-flags.h output.h insn-attr.h flags.h $(TREE_H) expr.h \ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 34f23dafd95..c3f780abe04 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,21 +1,3 @@ -2011-02-13 Mike Stump <mikestump@comcast.net> - - * parser.c (cp_parser_primary_expression): Add arguments to all the plugins. - * lex.c: Plugify. - * Make-lang.in (objcp/plugin/lex.h): Likewise. - (build/slashify): Harden against rebuilds. - (objcp/plugin/parser.h): Harden against parallel builds. - - * Make-lang.in (cp/parser.o): Move c-family/c-objc.h dependancy - down. - -2011-02-12 Mike Stump <mikestump@comcast.net> - - * Make-lang.in (build/slashify): Plugify Objective-C++. - (cp/parser.o): Likewise. - (objcp/plugin/parser.h): Likewise. - * parser.c (cp_parser_token_starts_cast_expression): Likewise. - 2011-02-09 Jason Merrill <jason@redhat.com> * decl.c (cp_make_fname_decl): Set DECL_THIS_STATIC at toplevel. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 6ec4dda7d55..373471448a4 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -247,7 +247,8 @@ CXX_TREE_H = $(TREE_H) cp/name-lookup.h cp/cp-tree.h $(C_COMMON_H) \ CXX_PRETTY_PRINT_H = cp/cxx-pretty-print.h $(C_PRETTY_PRINT_H) cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ - $(C_PRAGMA_H) output.h input.h cp/operators.def $(TM_P_H) + $(C_PRAGMA_H) output.h input.h cp/operators.def $(TM_P_H) \ + c-family/c-objc.h cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) debug.h langhooks.h \ $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h gt-cp-cp-lang.h \ cp/cp-objcp-common.h $(EXPR_H) $(TARGET_H) @@ -314,7 +315,8 @@ cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) \ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) $(REAL_H) \ gt-cp-mangle.h $(TARGET_H) $(TM_P_H) $(CGRAPH_H) cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \ - gt-cp-parser.h output.h $(TARGET_H) $(PLUGIN_H) intl.h + gt-cp-parser.h output.h $(TARGET_H) $(PLUGIN_H) intl.h \ + c-family/c-objc.h cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \ $(TM_H) coretypes.h pointer-set.h tree-iterator.h @@ -324,24 +326,3 @@ cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \ $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) tree-pretty-print.h - - -# Objective-C++ related rules: - -cp/parser.o: $(objdir)/objcp/plugin/parser.h $(srcdir)/objcp/plugin/parser.c \ - c-family/c-objc.h - -cp/lex.o: $(objdir)/objcp/plugin/lex.h c-family/c-objc.h - -# Would like to get rid of the #, but we always rebuild the checksum -# if we do -build/slashify: # $(srcdir)/config/slashify.c - $(COMPILER_FOR_BUILD) $(BUILD_COMPILERFLAGS) $(BUILD_CPPFLAGS) $(srcdir)/config/slashify.c -o $@ - -$(objdir)/objcp/plugin/parser.h: $(srcdir)/objcp/plugin/parser.h build/slashify - $(mkinstalldirs) objcp/plugin - build/slashify < $< > $@ - -$(objdir)/objcp/plugin/lex.h: $(srcdir)/objcp/plugin/lex.h build/slashify - $(mkinstalldirs) objcp/plugin - build/slashify < $< > $@ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index c8c49f1011b..852c3a2867a 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "cpplib.h" #include "flags.h" #include "c-family/c-pragma.h" -#include "objcp/plugin/lex.h" +#include "c-family/c-objc.h" #include "output.h" #include "tm_p.h" #include "timevar.h" @@ -449,7 +449,7 @@ unqualified_name_lookup_error (tree name) } else { - if (!PLUGIN_UNQUALIFIED_NAME_LOOKUP_ERROR (name)) + if (!objc_diagnose_private_ivar (name)) { error ("%qD was not declared in this scope", name); suggest_alternatives_for (location_of (name), name); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b6541cb4c93..11039b899cc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "c-family/c-common.h" +#include "c-family/c-objc.h" #include "plugin.h" @@ -2098,7 +2099,44 @@ enum pragma_context { pragma_external, pragma_stmt, pragma_compound }; static bool cp_parser_pragma (cp_parser *, enum pragma_context); -#include "objcp/plugin/parser.h" +/* Objective-C++ Productions */ + +static tree cp_parser_objc_message_receiver + (cp_parser *); +static tree cp_parser_objc_message_args + (cp_parser *); +static tree cp_parser_objc_message_expression + (cp_parser *); +static tree cp_parser_objc_encode_expression + (cp_parser *); +static tree cp_parser_objc_defs_expression + (cp_parser *); +static tree cp_parser_objc_protocol_expression + (cp_parser *); +static tree cp_parser_objc_selector_expression + (cp_parser *); +static tree cp_parser_objc_expression + (cp_parser *); +static bool cp_parser_objc_selector_p + (enum cpp_ttype); +static tree cp_parser_objc_selector + (cp_parser *); +static tree cp_parser_objc_protocol_refs_opt + (cp_parser *); +static void cp_parser_objc_declaration + (cp_parser *, tree); +static tree cp_parser_objc_statement + (cp_parser *); +static bool cp_parser_objc_valid_prefix_attributes + (cp_parser *, tree *); +static void cp_parser_objc_at_property_declaration + (cp_parser *) ; +static void cp_parser_objc_at_synthesize_declaration + (cp_parser *) ; +static void cp_parser_objc_at_dynamic_declaration + (cp_parser *) ; +static tree cp_parser_objc_struct_declaration + (cp_parser *) ; /* Utility Routines */ @@ -3671,11 +3709,18 @@ cp_parser_primary_expression (cp_parser *parser, } case CPP_OPEN_SQUARE: - PLUGIN_PRIMARY_EXPRESSION_3 (parser); + if (c_dialect_objc ()) + /* We have an Objective-C++ message. */ + return cp_parser_objc_expression (parser); maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR); return cp_parser_lambda_expression (parser); - PLUGIN_PRIMARY_EXPRESSION_2 (parser, cp_parser_error) + case CPP_OBJC_STRING: + if (c_dialect_objc ()) + /* We have an Objective-C++ string literal. */ + return cp_parser_objc_expression (parser); + cp_parser_error (parser, "expected primary-expression"); + return error_mark_node; case CPP_KEYWORD: switch (token->keyword) @@ -3806,7 +3851,11 @@ cp_parser_primary_expression (cp_parser *parser, case RID_IS_LITERAL_TYPE: return cp_parser_trait_expr (parser, token->keyword); - PLUGIN_PRIMARY_EXPRESSION_1 (parser) + /* Objective-C++ expressions. */ + case RID_AT_ENCODE: + case RID_AT_PROTOCOL: + case RID_AT_SELECTOR: + return cp_parser_objc_expression (parser); case RID_TEMPLATE: if (parser->in_function_body @@ -3890,8 +3939,25 @@ cp_parser_primary_expression (cp_parser *parser, if (ambiguous_decls) return error_mark_node; - PLUGIN_PRIMARY_EXPRESSION (parser, decl, cp_lexer_consume_token, - cp_lexer_peek_token); + /* In Objective-C++, we may have an Objective-C 2.0 + dot-syntax for classes here. */ + if (c_dialect_objc () + && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT + && TREE_CODE (decl) == TYPE_DECL + && objc_is_class_name (decl)) + { + tree component; + cp_lexer_consume_token (parser->lexer); + component = cp_parser_identifier (parser); + if (component == error_mark_node) + return error_mark_node; + + return objc_build_class_component_ref (id_expression, component); + } + + /* In Objective-C++, an instance variable (ivar) may be preferred + to whatever cp_parser_lookup_name() found. */ + decl = objc_lookup_ivar (decl, id_expression); /* If name lookup gives us a SCOPE_REF, then the qualifying scope was dependent. */ @@ -6529,9 +6595,9 @@ cp_parser_token_starts_cast_expression (cp_token *token) case CPP_EOF: return false; + /* '[' may start a primary-expression in obj-c++. */ case CPP_OPEN_SQUARE: - PLUGIN_TOKEN_STARTS_CAST_EXPR; - return false; + return c_dialect_objc (); default: return true; @@ -8016,7 +8082,14 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, statement = cp_parser_jump_statement (parser); break; - PLUGIN_STATEMENT + /* Objective-C++ exception-handling constructs. */ + case RID_AT_TRY: + case RID_AT_CATCH: + case RID_AT_FINALLY: + case RID_AT_SYNCHRONIZED: + case RID_AT_THROW: + statement = cp_parser_objc_statement (parser); + break; case RID_TRY: statement = cp_parser_try_block (parser); @@ -9401,7 +9474,13 @@ cp_parser_declaration (cp_parser* parser) else if (token1.keyword == RID_INLINE && token2.keyword == RID_NAMESPACE) cp_parser_namespace_definition (parser); - PLUGIN_DECLARATION (token1, attributes) + /* Objective-C++ declaration/definition. */ + else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword)) + cp_parser_objc_declaration (parser, NULL_TREE); + else if (c_dialect_objc () + && token1.keyword == RID_ATTRIBUTE + && cp_parser_objc_valid_prefix_attributes (parser, &attributes)) + cp_parser_objc_declaration (parser, attributes); /* We must have either a block declaration or a function definition. */ else @@ -12800,7 +12879,25 @@ cp_parser_simple_type_specifier (cp_parser* parser, if (type && type != error_mark_node) { - PLUGIN_SIMPLE_TYPE_SPECIFIER (parser, type, decl_specs); + /* See if TYPE is an Objective-C type, and if so, parse and + accept any protocol references following it. Do this before + the cp_parser_check_for_invalid_template_id() call, because + Objective-C types can be followed by '<...>' which would + enclose protocol names rather than template arguments, and so + everything is fine. */ + if (c_dialect_objc () && !parser->scope + && (objc_is_id (type) || objc_is_class_name (type))) + { + tree protos = cp_parser_objc_protocol_refs_opt (parser); + tree qual_type = objc_get_protocol_qualified_type (type, protos); + + /* Clobber the "unqualified" type previously entered into + DECL_SPECS with the new, improved protocol-qualified version. */ + if (decl_specs) + decl_specs->type = qual_type; + + return qual_type; + } /* There is no valid C++ program where a non-template type is followed by a "<". That usually indicates that the user @@ -12876,11 +12973,26 @@ cp_parser_nonclass_name (cp_parser* parser) /* Look up the type-name. */ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location); - PLUGIN_NONCLASS_NAME1 (parser, type_decl, identifier); + if (TREE_CODE (type_decl) != TYPE_DECL + && (objc_is_id (identifier) || objc_is_class_name (identifier))) + { + /* See if this is an Objective-C type. */ + tree protos = cp_parser_objc_protocol_refs_opt (parser); + tree type = objc_get_protocol_qualified_type (identifier, protos); + if (type) + type_decl = TYPE_NAME (type); + } /* Issue an error if we did not find a type-name. */ if (TREE_CODE (type_decl) != TYPE_DECL - PLUGIN_NONCLASS_NAME (parser, type_decl, cp_lexer_peek_token)) + /* In Objective-C, we have the complication that class names are + normally type names and start declarations (eg, the + "NSObject" in "NSObject *object;"), but can be used in an + Objective-C 2.0 dot-syntax (as in "NSObject.version") which + is an expression. So, a classname followed by a dot is not a + valid type-name. */ + || (objc_is_class_name (TREE_TYPE (type_decl)) + && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT)) { if (!cp_parser_simulate_error (parser)) cp_parser_name_lookup_error (parser, identifier, type_decl, @@ -16724,7 +16836,11 @@ cp_parser_class_name (cp_parser *parser, else if (TREE_CODE (decl) != TYPE_DECL || TREE_TYPE (decl) == error_mark_node || !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)) - PLUGIN_CLASS_NAME (parser, cp_lexer_peek_token, CPP_DOT)) + /* In Objective-C 2.0, a classname followed by '.' starts a + dot-syntax expression, and it's not a type-name. */ + || (c_dialect_objc () + && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT + && objc_is_class_name (decl))) decl = error_mark_node; if (decl == error_mark_node) @@ -17585,8 +17701,21 @@ cp_parser_member_declaration (cp_parser* parser) return; } - PLUGIN_MEMBER_DECLARATION (parser, cp_lexer_next_token_is_keyword, - finish_member_declaration); + /* Check for @defs. */ + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_DEFS)) + { + tree ivar, member; + tree ivar_chains = cp_parser_objc_defs_expression (parser); + ivar = ivar_chains; + while (ivar) + { + member = ivar; + ivar = TREE_CHAIN (member); + TREE_CHAIN (member) = NULL_TREE; + finish_member_declaration (member); + } + return; + } /* If the next token is `static_assert' we have a static assertion. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC_ASSERT)) @@ -21302,11 +21431,1884 @@ cp_parser_allow_gnu_extensions_p (cp_parser* parser) { return parser->allow_gnu_extensions_p; } - /* Objective-C++ Productions */ -#include "../objcp/plugin/parser.c" + +/* Parse an Objective-C expression, which feeds into a primary-expression + above. + + objc-expression: + objc-message-expression + objc-string-literal + objc-encode-expression + objc-protocol-expression + objc-selector-expression + + Returns a tree representation of the expression. */ + +static tree +cp_parser_objc_expression (cp_parser* parser) +{ + /* Try to figure out what kind of declaration is present. */ + cp_token *kwd = cp_lexer_peek_token (parser->lexer); + + switch (kwd->type) + { + case CPP_OPEN_SQUARE: + return cp_parser_objc_message_expression (parser); + + case CPP_OBJC_STRING: + kwd = cp_lexer_consume_token (parser->lexer); + return objc_build_string_object (kwd->u.value); + + case CPP_KEYWORD: + switch (kwd->keyword) + { + case RID_AT_ENCODE: + return cp_parser_objc_encode_expression (parser); + + case RID_AT_PROTOCOL: + return cp_parser_objc_protocol_expression (parser); + + case RID_AT_SELECTOR: + return cp_parser_objc_selector_expression (parser); + + default: + break; + } + default: + error_at (kwd->location, + "misplaced %<@%D%> Objective-C++ construct", + kwd->u.value); + cp_parser_skip_to_end_of_block_or_statement (parser); + } + + return error_mark_node; +} + +/* Parse an Objective-C message expression. + + objc-message-expression: + [ objc-message-receiver objc-message-args ] + + Returns a representation of an Objective-C message. */ + +static tree +cp_parser_objc_message_expression (cp_parser* parser) +{ + tree receiver, messageargs; + + cp_lexer_consume_token (parser->lexer); /* Eat '['. */ + receiver = cp_parser_objc_message_receiver (parser); + messageargs = cp_parser_objc_message_args (parser); + cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); + + return objc_build_message_expr (build_tree_list (receiver, messageargs)); +} + +/* Parse an objc-message-receiver. + + objc-message-receiver: + expression + simple-type-specifier + + Returns a representation of the type or expression. */ + +static tree +cp_parser_objc_message_receiver (cp_parser* parser) +{ + tree rcv; + + /* An Objective-C message receiver may be either (1) a type + or (2) an expression. */ + cp_parser_parse_tentatively (parser); + rcv = cp_parser_expression (parser, false, NULL); + + if (cp_parser_parse_definitely (parser)) + return rcv; + + rcv = cp_parser_simple_type_specifier (parser, + /*decl_specs=*/NULL, + CP_PARSER_FLAGS_NONE); + + return objc_get_class_reference (rcv); +} + +/* Parse the arguments and selectors comprising an Objective-C message. + + objc-message-args: + objc-selector + objc-selector-args + objc-selector-args , objc-comma-args + + objc-selector-args: + objc-selector [opt] : assignment-expression + objc-selector-args objc-selector [opt] : assignment-expression + + objc-comma-args: + assignment-expression + objc-comma-args , assignment-expression + + Returns a TREE_LIST, with TREE_PURPOSE containing a list of + selector arguments and TREE_VALUE containing a list of comma + arguments. */ + +static tree +cp_parser_objc_message_args (cp_parser* parser) +{ + tree sel_args = NULL_TREE, addl_args = NULL_TREE; + bool maybe_unary_selector_p = true; + cp_token *token = cp_lexer_peek_token (parser->lexer); + + while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON) + { + tree selector = NULL_TREE, arg; + + if (token->type != CPP_COLON) + selector = cp_parser_objc_selector (parser); + + /* Detect if we have a unary selector. */ + if (maybe_unary_selector_p + && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + return build_tree_list (selector, NULL_TREE); + + maybe_unary_selector_p = false; + cp_parser_require (parser, CPP_COLON, RT_COLON); + arg = cp_parser_assignment_expression (parser, false, NULL); + + sel_args + = chainon (sel_args, + build_tree_list (selector, arg)); + + token = cp_lexer_peek_token (parser->lexer); + } + + /* Handle non-selector arguments, if any. */ + while (token->type == CPP_COMMA) + { + tree arg; + + cp_lexer_consume_token (parser->lexer); + arg = cp_parser_assignment_expression (parser, false, NULL); + + addl_args + = chainon (addl_args, + build_tree_list (NULL_TREE, arg)); + + token = cp_lexer_peek_token (parser->lexer); + } + + if (sel_args == NULL_TREE && addl_args == NULL_TREE) + { + cp_parser_error (parser, "objective-c++ message argument(s) are expected"); + return build_tree_list (error_mark_node, error_mark_node); + } + + return build_tree_list (sel_args, addl_args); +} + +/* Parse an Objective-C encode expression. + + objc-encode-expression: + @encode objc-typename + + Returns an encoded representation of the type argument. */ + +static tree +cp_parser_objc_encode_expression (cp_parser* parser) +{ + tree type; + cp_token *token; + + cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */ + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + token = cp_lexer_peek_token (parser->lexer); + type = complete_type (cp_parser_type_id (parser)); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + + if (!type) + { + error_at (token->location, + "%<@encode%> must specify a type as an argument"); + return error_mark_node; + } + + /* This happens if we find @encode(T) (where T is a template + typename or something dependent on a template typename) when + parsing a template. In that case, we can't compile it + immediately, but we rather create an AT_ENCODE_EXPR which will + need to be instantiated when the template is used. + */ + if (dependent_type_p (type)) + { + tree value = build_min (AT_ENCODE_EXPR, size_type_node, type); + TREE_READONLY (value) = 1; + return value; + } + + return objc_build_encode_expr (type); +} + +/* Parse an Objective-C @defs expression. */ + +static tree +cp_parser_objc_defs_expression (cp_parser *parser) +{ + tree name; + + cp_lexer_consume_token (parser->lexer); /* Eat '@defs'. */ + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + name = cp_parser_identifier (parser); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + + return objc_get_class_ivars (name); +} + +/* Parse an Objective-C protocol expression. + + objc-protocol-expression: + @protocol ( identifier ) + + Returns a representation of the protocol expression. */ + +static tree +cp_parser_objc_protocol_expression (cp_parser* parser) +{ + tree proto; + + cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + proto = cp_parser_identifier (parser); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + + return objc_build_protocol_expr (proto); +} + +/* Parse an Objective-C selector expression. + + objc-selector-expression: + @selector ( objc-method-signature ) + + objc-method-signature: + objc-selector + objc-selector-seq + + objc-selector-seq: + objc-selector : + objc-selector-seq objc-selector : + + Returns a representation of the method selector. */ + +static tree +cp_parser_objc_selector_expression (cp_parser* parser) +{ + tree sel_seq = NULL_TREE; + bool maybe_unary_selector_p = true; + cp_token *token; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_lexer_consume_token (parser->lexer); /* Eat '@selector'. */ + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + token = cp_lexer_peek_token (parser->lexer); + + while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON + || token->type == CPP_SCOPE) + { + tree selector = NULL_TREE; + + if (token->type != CPP_COLON + || token->type == CPP_SCOPE) + selector = cp_parser_objc_selector (parser); + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON) + && cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE)) + { + /* Detect if we have a unary selector. */ + if (maybe_unary_selector_p) + { + sel_seq = selector; + goto finish_selector; + } + else + { + cp_parser_error (parser, "expected %<:%>"); + } + } + maybe_unary_selector_p = false; + token = cp_lexer_consume_token (parser->lexer); + + if (token->type == CPP_SCOPE) + { + sel_seq + = chainon (sel_seq, + build_tree_list (selector, NULL_TREE)); + sel_seq + = chainon (sel_seq, + build_tree_list (NULL_TREE, NULL_TREE)); + } + else + sel_seq + = chainon (sel_seq, + build_tree_list (selector, NULL_TREE)); + + token = cp_lexer_peek_token (parser->lexer); + } + + finish_selector: + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + + return objc_build_selector_expr (loc, sel_seq); +} + +/* Parse a list of identifiers. + + objc-identifier-list: + identifier + objc-identifier-list , identifier + + Returns a TREE_LIST of identifier nodes. */ + +static tree +cp_parser_objc_identifier_list (cp_parser* parser) +{ + tree identifier; + tree list; + cp_token *sep; + + identifier = cp_parser_identifier (parser); + if (identifier == error_mark_node) + return error_mark_node; + + list = build_tree_list (NULL_TREE, identifier); + sep = cp_lexer_peek_token (parser->lexer); + + while (sep->type == CPP_COMMA) + { + cp_lexer_consume_token (parser->lexer); /* Eat ','. */ + identifier = cp_parser_identifier (parser); + if (identifier == error_mark_node) + return list; + + list = chainon (list, build_tree_list (NULL_TREE, + identifier)); + sep = cp_lexer_peek_token (parser->lexer); + } + + return list; +} + +/* Parse an Objective-C alias declaration. + + objc-alias-declaration: + @compatibility_alias identifier identifier ; + + This function registers the alias mapping with the Objective-C front end. + It returns nothing. */ + +static void +cp_parser_objc_alias_declaration (cp_parser* parser) +{ + tree alias, orig; + + cp_lexer_consume_token (parser->lexer); /* Eat '@compatibility_alias'. */ + alias = cp_parser_identifier (parser); + orig = cp_parser_identifier (parser); + objc_declare_alias (alias, orig); + cp_parser_consume_semicolon_at_end_of_statement (parser); +} + +/* Parse an Objective-C class forward-declaration. + + objc-class-declaration: + @class objc-identifier-list ; + + The function registers the forward declarations with the Objective-C + front end. It returns nothing. */ + +static void +cp_parser_objc_class_declaration (cp_parser* parser) +{ + cp_lexer_consume_token (parser->lexer); /* Eat '@class'. */ + objc_declare_class (cp_parser_objc_identifier_list (parser)); + cp_parser_consume_semicolon_at_end_of_statement (parser); +} + +/* Parse a list of Objective-C protocol references. + + objc-protocol-refs-opt: + objc-protocol-refs [opt] + + objc-protocol-refs: + < objc-identifier-list > + + Returns a TREE_LIST of identifiers, if any. */ + +static tree +cp_parser_objc_protocol_refs_opt (cp_parser* parser) +{ + tree protorefs = NULL_TREE; + + if(cp_lexer_next_token_is (parser->lexer, CPP_LESS)) + { + cp_lexer_consume_token (parser->lexer); /* Eat '<'. */ + protorefs = cp_parser_objc_identifier_list (parser); + cp_parser_require (parser, CPP_GREATER, RT_GREATER); + } + + return protorefs; +} + +/* Parse a Objective-C visibility specification. */ + +static void +cp_parser_objc_visibility_spec (cp_parser* parser) +{ + cp_token *vis = cp_lexer_peek_token (parser->lexer); + + switch (vis->keyword) + { + case RID_AT_PRIVATE: + objc_set_visibility (OBJC_IVAR_VIS_PRIVATE); + break; + case RID_AT_PROTECTED: + objc_set_visibility (OBJC_IVAR_VIS_PROTECTED); + break; + case RID_AT_PUBLIC: + objc_set_visibility (OBJC_IVAR_VIS_PUBLIC); + break; + case RID_AT_PACKAGE: + objc_set_visibility (OBJC_IVAR_VIS_PACKAGE); + break; + default: + return; + } + + /* Eat '@private'/'@protected'/'@public'. */ + cp_lexer_consume_token (parser->lexer); +} + +/* Parse an Objective-C method type. Return 'true' if it is a class + (+) method, and 'false' if it is an instance (-) method. */ + +static inline bool +cp_parser_objc_method_type (cp_parser* parser) +{ + if (cp_lexer_consume_token (parser->lexer)->type == CPP_PLUS) + return true; + else + return false; +} + +/* Parse an Objective-C protocol qualifier. */ + +static tree +cp_parser_objc_protocol_qualifiers (cp_parser* parser) +{ + tree quals = NULL_TREE, node; + cp_token *token = cp_lexer_peek_token (parser->lexer); + + node = token->u.value; + + while (node && TREE_CODE (node) == IDENTIFIER_NODE + && (node == ridpointers [(int) RID_IN] + || node == ridpointers [(int) RID_OUT] + || node == ridpointers [(int) RID_INOUT] + || node == ridpointers [(int) RID_BYCOPY] + || node == ridpointers [(int) RID_BYREF] + || node == ridpointers [(int) RID_ONEWAY])) + { + quals = tree_cons (NULL_TREE, node, quals); + cp_lexer_consume_token (parser->lexer); + token = cp_lexer_peek_token (parser->lexer); + node = token->u.value; + } + + return quals; +} + +/* Parse an Objective-C typename. */ + +static tree +cp_parser_objc_typename (cp_parser* parser) +{ + tree type_name = NULL_TREE; + + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + { + tree proto_quals, cp_type = NULL_TREE; + + cp_lexer_consume_token (parser->lexer); /* Eat '('. */ + proto_quals = cp_parser_objc_protocol_qualifiers (parser); + + /* An ObjC type name may consist of just protocol qualifiers, in which + case the type shall default to 'id'. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + { + cp_type = cp_parser_type_id (parser); + + /* If the type could not be parsed, an error has already + been produced. For error recovery, behave as if it had + not been specified, which will use the default type + 'id'. */ + if (cp_type == error_mark_node) + { + cp_type = NULL_TREE; + /* We need to skip to the closing parenthesis as + cp_parser_type_id() does not seem to do it for + us. */ + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/false); + } + } + + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + type_name = build_tree_list (proto_quals, cp_type); + } + + return type_name; +} + +/* Check to see if TYPE refers to an Objective-C selector name. */ + +static bool +cp_parser_objc_selector_p (enum cpp_ttype type) +{ + return (type == CPP_NAME || type == CPP_KEYWORD + || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND + || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT + || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ + || type == CPP_XOR || type == CPP_XOR_EQ); +} + +/* Parse an Objective-C selector. */ + +static tree +cp_parser_objc_selector (cp_parser* parser) +{ + cp_token *token = cp_lexer_consume_token (parser->lexer); + + if (!cp_parser_objc_selector_p (token->type)) + { + error_at (token->location, "invalid Objective-C++ selector name"); + return error_mark_node; + } + + /* C++ operator names are allowed to appear in ObjC selectors. */ + switch (token->type) + { + case CPP_AND_AND: return get_identifier ("and"); + case CPP_AND_EQ: return get_identifier ("and_eq"); + case CPP_AND: return get_identifier ("bitand"); + case CPP_OR: return get_identifier ("bitor"); + case CPP_COMPL: return get_identifier ("compl"); + case CPP_NOT: return get_identifier ("not"); + case CPP_NOT_EQ: return get_identifier ("not_eq"); + case CPP_OR_OR: return get_identifier ("or"); + case CPP_OR_EQ: return get_identifier ("or_eq"); + case CPP_XOR: return get_identifier ("xor"); + case CPP_XOR_EQ: return get_identifier ("xor_eq"); + default: return token->u.value; + } +} + +/* Parse an Objective-C params list. */ + +static tree +cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes) +{ + tree params = NULL_TREE; + bool maybe_unary_selector_p = true; + cp_token *token = cp_lexer_peek_token (parser->lexer); + + while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON) + { + tree selector = NULL_TREE, type_name, identifier; + tree parm_attr = NULL_TREE; + + if (token->keyword == RID_ATTRIBUTE) + break; + + if (token->type != CPP_COLON) + selector = cp_parser_objc_selector (parser); + + /* Detect if we have a unary selector. */ + if (maybe_unary_selector_p + && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + { + params = selector; /* Might be followed by attributes. */ + break; + } + + maybe_unary_selector_p = false; + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) + { + /* Something went quite wrong. There should be a colon + here, but there is not. Stop parsing parameters. */ + break; + } + type_name = cp_parser_objc_typename (parser); + /* New ObjC allows attributes on parameters too. */ + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)) + parm_attr = cp_parser_attributes_opt (parser); + identifier = cp_parser_identifier (parser); + + params + = chainon (params, + objc_build_keyword_decl (selector, + type_name, + identifier, + parm_attr)); + + token = cp_lexer_peek_token (parser->lexer); + } + + if (params == NULL_TREE) + { + cp_parser_error (parser, "objective-c++ method declaration is expected"); + return error_mark_node; + } + + /* We allow tail attributes for the method. */ + if (token->keyword == RID_ATTRIBUTE) + { + *attributes = cp_parser_attributes_opt (parser); + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + return params; + cp_parser_error (parser, + "method attributes must be specified at the end"); + return error_mark_node; + } + + if (params == NULL_TREE) + { + cp_parser_error (parser, "objective-c++ method declaration is expected"); + return error_mark_node; + } + return params; +} + +/* Parse the non-keyword Objective-C params. */ + +static tree +cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp, + tree* attributes) +{ + tree params = make_node (TREE_LIST); + cp_token *token = cp_lexer_peek_token (parser->lexer); + *ellipsisp = false; /* Initially, assume no ellipsis. */ + + while (token->type == CPP_COMMA) + { + cp_parameter_declarator *parmdecl; + tree parm; + + cp_lexer_consume_token (parser->lexer); /* Eat ','. */ + token = cp_lexer_peek_token (parser->lexer); + + if (token->type == CPP_ELLIPSIS) + { + cp_lexer_consume_token (parser->lexer); /* Eat '...'. */ + *ellipsisp = true; + token = cp_lexer_peek_token (parser->lexer); + break; + } + + /* TODO: parse attributes for tail parameters. */ + parmdecl = cp_parser_parameter_declaration (parser, false, NULL); + parm = grokdeclarator (parmdecl->declarator, + &parmdecl->decl_specifiers, + PARM, /*initialized=*/0, + /*attrlist=*/NULL); + + chainon (params, build_tree_list (NULL_TREE, parm)); + token = cp_lexer_peek_token (parser->lexer); + } + + /* We allow tail attributes for the method. */ + if (token->keyword == RID_ATTRIBUTE) + { + if (*attributes == NULL_TREE) + { + *attributes = cp_parser_attributes_opt (parser); + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + return params; + } + else + /* We have an error, but parse the attributes, so that we can + carry on. */ + *attributes = cp_parser_attributes_opt (parser); + + cp_parser_error (parser, + "method attributes must be specified at the end"); + return error_mark_node; + } + + return params; +} + +/* Parse a linkage specification, a pragma, an extra semicolon or a block. */ + +static void +cp_parser_objc_interstitial_code (cp_parser* parser) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + /* If the next token is `extern' and the following token is a string + literal, then we have a linkage specification. */ + if (token->keyword == RID_EXTERN + && cp_parser_is_string_literal (cp_lexer_peek_nth_token (parser->lexer, 2))) + cp_parser_linkage_specification (parser); + /* Handle #pragma, if any. */ + else if (token->type == CPP_PRAGMA) + cp_parser_pragma (parser, pragma_external); + /* Allow stray semicolons. */ + else if (token->type == CPP_SEMICOLON) + cp_lexer_consume_token (parser->lexer); + /* Mark methods as optional or required, when building protocols. */ + else if (token->keyword == RID_AT_OPTIONAL) + { + cp_lexer_consume_token (parser->lexer); + objc_set_method_opt (true); + } + else if (token->keyword == RID_AT_REQUIRED) + { + cp_lexer_consume_token (parser->lexer); + objc_set_method_opt (false); + } + else if (token->keyword == RID_NAMESPACE) + cp_parser_namespace_definition (parser); + /* Other stray characters must generate errors. */ + else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE) + { + cp_lexer_consume_token (parser->lexer); + error ("stray %qs between Objective-C++ methods", + token->type == CPP_OPEN_BRACE ? "{" : "}"); + } + /* Finally, try to parse a block-declaration, or a function-definition. */ + else + cp_parser_block_declaration (parser, /*statement_p=*/false); +} + +/* Parse a method signature. */ + +static tree +cp_parser_objc_method_signature (cp_parser* parser, tree* attributes) +{ + tree rettype, kwdparms, optparms; + bool ellipsis = false; + bool is_class_method; + + is_class_method = cp_parser_objc_method_type (parser); + rettype = cp_parser_objc_typename (parser); + *attributes = NULL_TREE; + kwdparms = cp_parser_objc_method_keyword_params (parser, attributes); + if (kwdparms == error_mark_node) + return error_mark_node; + optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes); + if (optparms == error_mark_node) + return error_mark_node; + + return objc_build_method_signature (is_class_method, rettype, kwdparms, optparms, ellipsis); +} + +static bool +cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser) +{ + tree tattr; + cp_lexer_save_tokens (parser->lexer); + tattr = cp_parser_attributes_opt (parser); + gcc_assert (tattr) ; + + /* If the attributes are followed by a method introducer, this is not allowed. + Dump the attributes and flag the situation. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS) + || cp_lexer_next_token_is (parser->lexer, CPP_MINUS)) + return true; + + /* Otherwise, the attributes introduce some interstitial code, possibly so + rewind to allow that check. */ + cp_lexer_rollback_tokens (parser->lexer); + return false; +} + +/* Parse an Objective-C method prototype list. */ + +static void +cp_parser_objc_method_prototype_list (cp_parser* parser) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + while (token->keyword != RID_AT_END && token->type != CPP_EOF) + { + if (token->type == CPP_PLUS || token->type == CPP_MINUS) + { + tree attributes, sig; + bool is_class_method; + if (token->type == CPP_PLUS) + is_class_method = true; + else + is_class_method = false; + sig = cp_parser_objc_method_signature (parser, &attributes); + if (sig == error_mark_node) + { + cp_parser_skip_to_end_of_block_or_statement (parser); + token = cp_lexer_peek_token (parser->lexer); + continue; + } + objc_add_method_declaration (is_class_method, sig, attributes); + cp_parser_consume_semicolon_at_end_of_statement (parser); + } + else if (token->keyword == RID_AT_PROPERTY) + cp_parser_objc_at_property_declaration (parser); + else if (token->keyword == RID_ATTRIBUTE + && cp_parser_objc_method_maybe_bad_prefix_attributes(parser)) + warning_at (cp_lexer_peek_token (parser->lexer)->location, + OPT_Wattributes, + "prefix attributes are ignored for methods"); + else + /* Allow for interspersed non-ObjC++ code. */ + cp_parser_objc_interstitial_code (parser); + + token = cp_lexer_peek_token (parser->lexer); + } + + if (token->type != CPP_EOF) + cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */ + else + cp_parser_error (parser, "expected %<@end%>"); + + objc_finish_interface (); +} + +/* Parse an Objective-C method definition list. */ + +static void +cp_parser_objc_method_definition_list (cp_parser* parser) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + while (token->keyword != RID_AT_END && token->type != CPP_EOF) + { + tree meth; + + if (token->type == CPP_PLUS || token->type == CPP_MINUS) + { + cp_token *ptk; + tree sig, attribute; + bool is_class_method; + if (token->type == CPP_PLUS) + is_class_method = true; + else + is_class_method = false; + push_deferring_access_checks (dk_deferred); + sig = cp_parser_objc_method_signature (parser, &attribute); + if (sig == error_mark_node) + { + cp_parser_skip_to_end_of_block_or_statement (parser); + token = cp_lexer_peek_token (parser->lexer); + continue; + } + objc_start_method_definition (is_class_method, sig, attribute); + + /* For historical reasons, we accept an optional semicolon. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + cp_lexer_consume_token (parser->lexer); + + ptk = cp_lexer_peek_token (parser->lexer); + if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS + || ptk->type == CPP_EOF || ptk->keyword == RID_AT_END)) + { + perform_deferred_access_checks (); + stop_deferring_access_checks (); + meth = cp_parser_function_definition_after_declarator (parser, + false); + pop_deferring_access_checks (); + objc_finish_method_definition (meth); + } + } + /* The following case will be removed once @synthesize is + completely implemented. */ + else if (token->keyword == RID_AT_PROPERTY) + cp_parser_objc_at_property_declaration (parser); + else if (token->keyword == RID_AT_SYNTHESIZE) + cp_parser_objc_at_synthesize_declaration (parser); + else if (token->keyword == RID_AT_DYNAMIC) + cp_parser_objc_at_dynamic_declaration (parser); + else if (token->keyword == RID_ATTRIBUTE + && cp_parser_objc_method_maybe_bad_prefix_attributes(parser)) + warning_at (token->location, OPT_Wattributes, + "prefix attributes are ignored for methods"); + else + /* Allow for interspersed non-ObjC++ code. */ + cp_parser_objc_interstitial_code (parser); + + token = cp_lexer_peek_token (parser->lexer); + } + + if (token->type != CPP_EOF) + cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */ + else + cp_parser_error (parser, "expected %<@end%>"); + + objc_finish_implementation (); +} + +/* Parse Objective-C ivars. */ + +static void +cp_parser_objc_class_ivars (cp_parser* parser) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + if (token->type != CPP_OPEN_BRACE) + return; /* No ivars specified. */ + + cp_lexer_consume_token (parser->lexer); /* Eat '{'. */ + token = cp_lexer_peek_token (parser->lexer); + + while (token->type != CPP_CLOSE_BRACE + && token->keyword != RID_AT_END && token->type != CPP_EOF) + { + cp_decl_specifier_seq declspecs; + int decl_class_or_enum_p; + tree prefix_attributes; + + cp_parser_objc_visibility_spec (parser); + + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE)) + break; + + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_OPTIONAL, + &declspecs, + &decl_class_or_enum_p); + + /* auto, register, static, extern, mutable. */ + if (declspecs.storage_class != sc_none) + { + cp_parser_error (parser, "invalid type for instance variable"); + declspecs.storage_class = sc_none; + } + + /* __thread. */ + if (declspecs.specs[(int) ds_thread]) + { + cp_parser_error (parser, "invalid type for instance variable"); + declspecs.specs[(int) ds_thread] = 0; + } + + /* typedef. */ + if (declspecs.specs[(int) ds_typedef]) + { + cp_parser_error (parser, "invalid type for instance variable"); + declspecs.specs[(int) ds_typedef] = 0; + } + + prefix_attributes = declspecs.attributes; + declspecs.attributes = NULL_TREE; + + /* Keep going until we hit the `;' at the end of the + declaration. */ + while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) + { + tree width = NULL_TREE, attributes, first_attribute, decl; + cp_declarator *declarator = NULL; + int ctor_dtor_or_conv_p; + + /* Check for a (possibly unnamed) bitfield declaration. */ + token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_COLON) + goto eat_colon; + + if (token->type == CPP_NAME + && (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_COLON)) + { + /* Get the name of the bitfield. */ + declarator = make_id_declarator (NULL_TREE, + cp_parser_identifier (parser), + sfk_none); + + eat_colon: + cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ + /* Get the width of the bitfield. */ + width + = cp_parser_constant_expression (parser, + /*allow_non_constant=*/false, + NULL); + } + else + { + /* Parse the declarator. */ + declarator + = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, + &ctor_dtor_or_conv_p, + /*parenthesized_p=*/NULL, + /*member_p=*/false); + } + + /* Look for attributes that apply to the ivar. */ + attributes = cp_parser_attributes_opt (parser); + /* Remember which attributes are prefix attributes and + which are not. */ + first_attribute = attributes; + /* Combine the attributes. */ + attributes = chainon (prefix_attributes, attributes); + + if (width) + /* Create the bitfield declaration. */ + decl = grokbitfield (declarator, &declspecs, + width, + attributes); + else + decl = grokfield (declarator, &declspecs, + NULL_TREE, /*init_const_expr_p=*/false, + NULL_TREE, attributes); + + /* Add the instance variable. */ + objc_add_instance_variable (decl); + + /* Reset PREFIX_ATTRIBUTES. */ + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + + token = cp_lexer_peek_token (parser->lexer); + + if (token->type == CPP_COMMA) + { + cp_lexer_consume_token (parser->lexer); /* Eat ','. */ + continue; + } + break; + } + + cp_parser_consume_semicolon_at_end_of_statement (parser); + token = cp_lexer_peek_token (parser->lexer); + } + + if (token->keyword == RID_AT_END) + cp_parser_error (parser, "expected %<}%>"); + + /* Do not consume the RID_AT_END, so it will be read again as terminating + the @interface of @implementation. */ + if (token->keyword != RID_AT_END && token->type != CPP_EOF) + cp_lexer_consume_token (parser->lexer); /* Eat '}'. */ + + /* For historical reasons, we accept an optional semicolon. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + cp_lexer_consume_token (parser->lexer); +} + +/* Parse an Objective-C protocol declaration. */ + +static void +cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes) +{ + tree proto, protorefs; + cp_token *tok; + + cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + tok = cp_lexer_peek_token (parser->lexer); + error_at (tok->location, "identifier expected after %<@protocol%>"); + goto finish; + } + + /* See if we have a forward declaration or a definition. */ + tok = cp_lexer_peek_nth_token (parser->lexer, 2); + + /* Try a forward declaration first. */ + if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON) + { + objc_declare_protocols (cp_parser_objc_identifier_list (parser), + attributes); + finish: + cp_parser_consume_semicolon_at_end_of_statement (parser); + } + + /* Ok, we got a full-fledged definition (or at least should). */ + else + { + proto = cp_parser_identifier (parser); + protorefs = cp_parser_objc_protocol_refs_opt (parser); + objc_start_protocol (proto, protorefs, attributes); + cp_parser_objc_method_prototype_list (parser); + } +} + +/* Parse an Objective-C superclass or category. */ + +static void +cp_parser_objc_superclass_or_category (cp_parser *parser, + bool iface_p, + tree *super, + tree *categ, bool *is_class_extension) +{ + cp_token *next = cp_lexer_peek_token (parser->lexer); + + *super = *categ = NULL_TREE; + *is_class_extension = false; + if (next->type == CPP_COLON) + { + cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ + *super = cp_parser_identifier (parser); + } + else if (next->type == CPP_OPEN_PAREN) + { + cp_lexer_consume_token (parser->lexer); /* Eat '('. */ + + /* If there is no category name, and this is an @interface, we + have a class extension. */ + if (iface_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + { + *categ = NULL_TREE; + *is_class_extension = true; + } + else + *categ = cp_parser_identifier (parser); + + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + } +} + +/* Parse an Objective-C class interface. */ + +static void +cp_parser_objc_class_interface (cp_parser* parser, tree attributes) +{ + tree name, super, categ, protos; + bool is_class_extension; + + cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */ + name = cp_parser_identifier (parser); + if (name == error_mark_node) + { + /* It's hard to recover because even if valid @interface stuff + is to follow, we can't compile it (or validate it) if we + don't even know which class it refers to. Let's assume this + was a stray '@interface' token in the stream and skip it. + */ + return; + } + cp_parser_objc_superclass_or_category (parser, true, &super, &categ, + &is_class_extension); + protos = cp_parser_objc_protocol_refs_opt (parser); + + /* We have either a class or a category on our hands. */ + if (categ || is_class_extension) + objc_start_category_interface (name, categ, protos, attributes); + else + { + objc_start_class_interface (name, super, protos, attributes); + /* Handle instance variable declarations, if any. */ + cp_parser_objc_class_ivars (parser); + objc_continue_interface (); + } + + cp_parser_objc_method_prototype_list (parser); +} + +/* Parse an Objective-C class implementation. */ + +static void +cp_parser_objc_class_implementation (cp_parser* parser) +{ + tree name, super, categ; + bool is_class_extension; + + cp_lexer_consume_token (parser->lexer); /* Eat '@implementation'. */ + name = cp_parser_identifier (parser); + if (name == error_mark_node) + { + /* It's hard to recover because even if valid @implementation + stuff is to follow, we can't compile it (or validate it) if + we don't even know which class it refers to. Let's assume + this was a stray '@implementation' token in the stream and + skip it. + */ + return; + } + cp_parser_objc_superclass_or_category (parser, false, &super, &categ, + &is_class_extension); + + /* We have either a class or a category on our hands. */ + if (categ) + objc_start_category_implementation (name, categ); + else + { + objc_start_class_implementation (name, super); + /* Handle instance variable declarations, if any. */ + cp_parser_objc_class_ivars (parser); + objc_continue_implementation (); + } + + cp_parser_objc_method_definition_list (parser); +} + +/* Consume the @end token and finish off the implementation. */ + +static void +cp_parser_objc_end_implementation (cp_parser* parser) +{ + cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */ + objc_finish_implementation (); +} + +/* Parse an Objective-C declaration. */ + +static void +cp_parser_objc_declaration (cp_parser* parser, tree attributes) +{ + /* Try to figure out what kind of declaration is present. */ + cp_token *kwd = cp_lexer_peek_token (parser->lexer); + + if (attributes) + switch (kwd->keyword) + { + case RID_AT_ALIAS: + case RID_AT_CLASS: + case RID_AT_END: + error_at (kwd->location, "attributes may not be specified before" + " the %<@%D%> Objective-C++ keyword", + kwd->u.value); + attributes = NULL; + break; + case RID_AT_IMPLEMENTATION: + warning_at (kwd->location, OPT_Wattributes, + "prefix attributes are ignored before %<@%D%>", + kwd->u.value); + attributes = NULL; + default: + break; + } + + switch (kwd->keyword) + { + case RID_AT_ALIAS: + cp_parser_objc_alias_declaration (parser); + break; + case RID_AT_CLASS: + cp_parser_objc_class_declaration (parser); + break; + case RID_AT_PROTOCOL: + cp_parser_objc_protocol_declaration (parser, attributes); + break; + case RID_AT_INTERFACE: + cp_parser_objc_class_interface (parser, attributes); + break; + case RID_AT_IMPLEMENTATION: + cp_parser_objc_class_implementation (parser); + break; + case RID_AT_END: + cp_parser_objc_end_implementation (parser); + break; + default: + error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct", + kwd->u.value); + cp_parser_skip_to_end_of_block_or_statement (parser); + } +} + +/* Parse an Objective-C try-catch-finally statement. + + objc-try-catch-finally-stmt: + @try compound-statement objc-catch-clause-seq [opt] + objc-finally-clause [opt] + + objc-catch-clause-seq: + objc-catch-clause objc-catch-clause-seq [opt] + + objc-catch-clause: + @catch ( objc-exception-declaration ) compound-statement + + objc-finally-clause: + @finally compound-statement + + objc-exception-declaration: + parameter-declaration + '...' + + where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS. + + Returns NULL_TREE. + + PS: This function is identical to c_parser_objc_try_catch_finally_statement + for C. Keep them in sync. */ + +static tree +cp_parser_objc_try_catch_finally_statement (cp_parser *parser) +{ + location_t location; + tree stmt; + + cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY); + location = cp_lexer_peek_token (parser->lexer)->location; + objc_maybe_warn_exceptions (location); + /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST + node, lest it get absorbed into the surrounding block. */ + stmt = push_stmt_list (); + cp_parser_compound_statement (parser, NULL, false); + objc_begin_try_stmt (location, pop_stmt_list (stmt)); + + while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH)) + { + cp_parameter_declarator *parm; + tree parameter_declaration = error_mark_node; + bool seen_open_paren = false; + + cp_lexer_consume_token (parser->lexer); + if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + seen_open_paren = true; + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) + { + /* We have "@catch (...)" (where the '...' are literally + what is in the code). Skip the '...'. + parameter_declaration is set to NULL_TREE, and + objc_being_catch_clauses() knows that that means + '...'. */ + cp_lexer_consume_token (parser->lexer); + parameter_declaration = NULL_TREE; + } + else + { + /* We have "@catch (NSException *exception)" or something + like that. Parse the parameter declaration. */ + parm = cp_parser_parameter_declaration (parser, false, NULL); + if (parm == NULL) + parameter_declaration = error_mark_node; + else + parameter_declaration = grokdeclarator (parm->declarator, + &parm->decl_specifiers, + PARM, /*initialized=*/0, + /*attrlist=*/NULL); + } + if (seen_open_paren) + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + else + { + /* If there was no open parenthesis, we are recovering from + an error, and we are trying to figure out what mistake + the user has made. */ + + /* If there is an immediate closing parenthesis, the user + probably forgot the opening one (ie, they typed "@catch + NSException *e)". Parse the closing parenthesis and keep + going. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) + cp_lexer_consume_token (parser->lexer); + + /* If these is no immediate closing parenthesis, the user + probably doesn't know that parenthesis are required at + all (ie, they typed "@catch NSException *e"). So, just + forget about the closing parenthesis and keep going. */ + } + objc_begin_catch_clause (parameter_declaration); + cp_parser_compound_statement (parser, NULL, false); + objc_finish_catch_clause (); + } + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY)) + { + cp_lexer_consume_token (parser->lexer); + location = cp_lexer_peek_token (parser->lexer)->location; + /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST + node, lest it get absorbed into the surrounding block. */ + stmt = push_stmt_list (); + cp_parser_compound_statement (parser, NULL, false); + objc_build_finally_clause (location, pop_stmt_list (stmt)); + } + + return objc_finish_try_stmt (); +} + +/* Parse an Objective-C synchronized statement. + + objc-synchronized-stmt: + @synchronized ( expression ) compound-statement + + Returns NULL_TREE. */ + +static tree +cp_parser_objc_synchronized_statement (cp_parser *parser) +{ + location_t location; + tree lock, stmt; + + cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED); + + location = cp_lexer_peek_token (parser->lexer)->location; + objc_maybe_warn_exceptions (location); + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + lock = cp_parser_expression (parser, false, NULL); + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + + /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST + node, lest it get absorbed into the surrounding block. */ + stmt = push_stmt_list (); + cp_parser_compound_statement (parser, NULL, false); + + return objc_build_synchronized (location, lock, pop_stmt_list (stmt)); +} + +/* Parse an Objective-C throw statement. + + objc-throw-stmt: + @throw assignment-expression [opt] ; + + Returns a constructed '@throw' statement. */ + +static tree +cp_parser_objc_throw_statement (cp_parser *parser) +{ + tree expr = NULL_TREE; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW); + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) + expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); + + cp_parser_consume_semicolon_at_end_of_statement (parser); + + return objc_build_throw_stmt (loc, expr); +} + +/* Parse an Objective-C statement. */ + +static tree +cp_parser_objc_statement (cp_parser * parser) +{ + /* Try to figure out what kind of declaration is present. */ + cp_token *kwd = cp_lexer_peek_token (parser->lexer); + + switch (kwd->keyword) + { + case RID_AT_TRY: + return cp_parser_objc_try_catch_finally_statement (parser); + case RID_AT_SYNCHRONIZED: + return cp_parser_objc_synchronized_statement (parser); + case RID_AT_THROW: + return cp_parser_objc_throw_statement (parser); + default: + error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct", + kwd->u.value); + cp_parser_skip_to_end_of_block_or_statement (parser); + } + + return error_mark_node; +} + +/* If we are compiling ObjC++ and we see an __attribute__ we neeed to + look ahead to see if an objc keyword follows the attributes. This + is to detect the use of prefix attributes on ObjC @interface and + @protocol. */ + +static bool +cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib) +{ + cp_lexer_save_tokens (parser->lexer); + *attrib = cp_parser_attributes_opt (parser); + gcc_assert (*attrib); + if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword)) + { + cp_lexer_commit_tokens (parser->lexer); + return true; + } + cp_lexer_rollback_tokens (parser->lexer); + return false; +} + +/* This routine is a minimal replacement for + c_parser_struct_declaration () used when parsing the list of + types/names or ObjC++ properties. For example, when parsing the + code + + @property (readonly) int a, b, c; + + this function is responsible for parsing "int a, int b, int c" and + returning the declarations as CHAIN of DECLs. + + TODO: Share this code with cp_parser_objc_class_ivars. It's very + similar parsing. */ +static tree +cp_parser_objc_struct_declaration (cp_parser *parser) +{ + tree decls = NULL_TREE; + cp_decl_specifier_seq declspecs; + int decl_class_or_enum_p; + tree prefix_attributes; + + cp_parser_decl_specifier_seq (parser, + CP_PARSER_FLAGS_NONE, + &declspecs, + &decl_class_or_enum_p); + + if (declspecs.type == error_mark_node) + return error_mark_node; + + /* auto, register, static, extern, mutable. */ + if (declspecs.storage_class != sc_none) + { + cp_parser_error (parser, "invalid type for property"); + declspecs.storage_class = sc_none; + } + + /* __thread. */ + if (declspecs.specs[(int) ds_thread]) + { + cp_parser_error (parser, "invalid type for property"); + declspecs.specs[(int) ds_thread] = 0; + } + + /* typedef. */ + if (declspecs.specs[(int) ds_typedef]) + { + cp_parser_error (parser, "invalid type for property"); + declspecs.specs[(int) ds_typedef] = 0; + } + + prefix_attributes = declspecs.attributes; + declspecs.attributes = NULL_TREE; + + /* Keep going until we hit the `;' at the end of the declaration. */ + while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) + { + tree attributes, first_attribute, decl; + cp_declarator *declarator; + cp_token *token; + + /* Parse the declarator. */ + declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, + NULL, NULL, false); + + /* Look for attributes that apply to the ivar. */ + attributes = cp_parser_attributes_opt (parser); + /* Remember which attributes are prefix attributes and + which are not. */ + first_attribute = attributes; + /* Combine the attributes. */ + attributes = chainon (prefix_attributes, attributes); + + decl = grokfield (declarator, &declspecs, + NULL_TREE, /*init_const_expr_p=*/false, + NULL_TREE, attributes); + + if (decl == error_mark_node || decl == NULL_TREE) + return error_mark_node; + + /* Reset PREFIX_ATTRIBUTES. */ + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + + DECL_CHAIN (decl) = decls; + decls = decl; + + token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_COMMA) + { + cp_lexer_consume_token (parser->lexer); /* Eat ','. */ + continue; + } + else + break; + } + return decls; +} + +/* Parse an Objective-C @property declaration. The syntax is: + + objc-property-declaration: + '@property' objc-property-attributes[opt] struct-declaration ; + + objc-property-attributes: + '(' objc-property-attribute-list ')' + + objc-property-attribute-list: + objc-property-attribute + objc-property-attribute-list, objc-property-attribute + + objc-property-attribute + 'getter' = identifier + 'setter' = identifier + 'readonly' + 'readwrite' + 'assign' + 'retain' + 'copy' + 'nonatomic' + + For example: + @property NSString *name; + @property (readonly) id object; + @property (retain, nonatomic, getter=getTheName) id name; + @property int a, b, c; + + PS: This function is identical to + c_parser_objc_at_property_declaration for C. Keep them in sync. */ +static void +cp_parser_objc_at_property_declaration (cp_parser *parser) +{ + /* The following variables hold the attributes of the properties as + parsed. They are 'false' or 'NULL_TREE' if the attribute was not + seen. When we see an attribute, we set them to 'true' (if they + are boolean properties) or to the identifier (if they have an + argument, ie, for getter and setter). Note that here we only + parse the list of attributes, check the syntax and accumulate the + attributes that we find. objc_add_property_declaration() will + then process the information. */ + bool property_assign = false; + bool property_copy = false; + tree property_getter_ident = NULL_TREE; + bool property_nonatomic = false; + bool property_readonly = false; + bool property_readwrite = false; + bool property_retain = false; + tree property_setter_ident = NULL_TREE; + + /* 'properties' is the list of properties that we read. Usually a + single one, but maybe more (eg, in "@property int a, b, c;" there + are three). */ + tree properties; + location_t loc; + + loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_lexer_consume_token (parser->lexer); /* Eat '@property'. */ + + /* Parse the optional attribute list... */ + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + { + /* Eat the '('. */ + cp_lexer_consume_token (parser->lexer); + + while (true) + { + bool syntax_error = false; + cp_token *token = cp_lexer_peek_token (parser->lexer); + enum rid keyword; + + if (token->type != CPP_NAME) + { + cp_parser_error (parser, "expected identifier"); + break; + } + keyword = C_RID_CODE (token->u.value); + cp_lexer_consume_token (parser->lexer); + switch (keyword) + { + case RID_ASSIGN: property_assign = true; break; + case RID_COPY: property_copy = true; break; + case RID_NONATOMIC: property_nonatomic = true; break; + case RID_READONLY: property_readonly = true; break; + case RID_READWRITE: property_readwrite = true; break; + case RID_RETAIN: property_retain = true; break; + + case RID_GETTER: + case RID_SETTER: + if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)) + { + if (keyword == RID_GETTER) + cp_parser_error (parser, + "missing %<=%> (after %<getter%> attribute)"); + else + cp_parser_error (parser, + "missing %<=%> (after %<setter%> attribute)"); + syntax_error = true; + break; + } + cp_lexer_consume_token (parser->lexer); /* eat the = */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, "expected identifier"); + syntax_error = true; + break; + } + if (keyword == RID_SETTER) + { + if (property_setter_ident != NULL_TREE) + cp_parser_error (parser, "the %<setter%> attribute may only be specified once"); + else + property_setter_ident = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) + cp_parser_error (parser, "setter name must terminate with %<:%>"); + else + cp_lexer_consume_token (parser->lexer); + } + else + { + if (property_getter_ident != NULL_TREE) + cp_parser_error (parser, "the %<getter%> attribute may only be specified once"); + else + property_getter_ident = cp_lexer_peek_token (parser->lexer)->u.value; + cp_lexer_consume_token (parser->lexer); + } + break; + default: + cp_parser_error (parser, "unknown property attribute"); + syntax_error = true; + break; + } + + if (syntax_error) + break; + + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + else + break; + } + + /* FIXME: "@property (setter, assign);" will generate a spurious + "error: expected ‘)’ before ‘,’ token". This is because + cp_parser_require, unlike the C counterpart, will produce an + error even if we are in error recovery. */ + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + { + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + } + } + + /* ... and the property declaration(s). */ + properties = cp_parser_objc_struct_declaration (parser); + + if (properties == error_mark_node) + { + cp_parser_skip_to_end_of_statement (parser); + /* If the next token is now a `;', consume it. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + cp_lexer_consume_token (parser->lexer); + return; + } + + if (properties == NULL_TREE) + cp_parser_error (parser, "expected identifier"); + else + { + /* Comma-separated properties are chained together in + reverse order; add them one by one. */ + properties = nreverse (properties); + + for (; properties; properties = TREE_CHAIN (properties)) + objc_add_property_declaration (loc, copy_node (properties), + property_readonly, property_readwrite, + property_assign, property_retain, + property_copy, property_nonatomic, + property_getter_ident, property_setter_ident); + } + + cp_parser_consume_semicolon_at_end_of_statement (parser); +} + +/* Parse an Objective-C++ @synthesize declaration. The syntax is: + + objc-synthesize-declaration: + @synthesize objc-synthesize-identifier-list ; + + objc-synthesize-identifier-list: + objc-synthesize-identifier + objc-synthesize-identifier-list, objc-synthesize-identifier + + objc-synthesize-identifier + identifier + identifier = identifier + + For example: + @synthesize MyProperty; + @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty; + + PS: This function is identical to c_parser_objc_at_synthesize_declaration + for C. Keep them in sync. +*/ +static void +cp_parser_objc_at_synthesize_declaration (cp_parser *parser) +{ + tree list = NULL_TREE; + location_t loc; + loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_lexer_consume_token (parser->lexer); /* Eat '@synthesize'. */ + while (true) + { + tree property, ivar; + property = cp_parser_identifier (parser); + if (property == error_mark_node) + { + cp_parser_consume_semicolon_at_end_of_statement (parser); + return; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) + { + cp_lexer_consume_token (parser->lexer); + ivar = cp_parser_identifier (parser); + if (ivar == error_mark_node) + { + cp_parser_consume_semicolon_at_end_of_statement (parser); + return; + } + } + else + ivar = NULL_TREE; + list = chainon (list, build_tree_list (ivar, property)); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + else + break; + } + cp_parser_consume_semicolon_at_end_of_statement (parser); + objc_add_synthesize_declaration (loc, list); +} + +/* Parse an Objective-C++ @dynamic declaration. The syntax is: + + objc-dynamic-declaration: + @dynamic identifier-list ; + + For example: + @dynamic MyProperty; + @dynamic MyProperty, AnotherProperty; + + PS: This function is identical to c_parser_objc_at_dynamic_declaration + for C. Keep them in sync. +*/ +static void +cp_parser_objc_at_dynamic_declaration (cp_parser *parser) +{ + tree list = NULL_TREE; + location_t loc; + loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_lexer_consume_token (parser->lexer); /* Eat '@dynamic'. */ + while (true) + { + tree property; + property = cp_parser_identifier (parser); + if (property == error_mark_node) + { + cp_parser_consume_semicolon_at_end_of_statement (parser); + return; + } + list = chainon (list, build_tree_list (NULL, property)); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + else + break; + } + cp_parser_consume_semicolon_at_end_of_statement (parser); + objc_add_dynamic_declaration (loc, list); +} /* OpenMP 2.5 parsing routines. */ diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog index 1100daabaf2..83999f7f310 100644 --- a/gcc/objcp/ChangeLog +++ b/gcc/objcp/ChangeLog @@ -1,14 +1,3 @@ -2011-02-13 Mike Stump <mikestump@comcast.net> - - * plugin/parser.h: Add arguments to all plugins. - * plugin/lex.h: Plugify. - -2011-02-12 Mike Stump <mikestump@comcast.net> - - * Make-lang.in (obj-c++.tags): Plugify Objective-C++. - * plugin/parser.h: Likewise. - * plugin/parser.c: Likewise. - 2011-02-07 Mike Stump <mikestump@comcast.net> * Make-lang.in (obj-c++.tags): Don't include *.y. diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in index 41950defe9d..2122d2df7e6 100644 --- a/gcc/objcp/Make-lang.in +++ b/gcc/objcp/Make-lang.in @@ -110,7 +110,7 @@ obj-c++.man: obj-c++.install-plugin: obj-c++.tags: force - cd $(srcdir)/objcp; etags -o TAGS.sub *.c *.h plugin/*.h plugin/*.c; \ + cd $(srcdir)/objcp; etags -o TAGS.sub *.c *.h; \ etags --include TAGS.sub --include ../TAGS.sub lang_checks += check-obj-c++ diff --git a/gcc/objcp/plugin/lex.h b/gcc/objcp/plugin/lex.h deleted file mode 100644 index a13024a5b2d..00000000000 --- a/gcc/objcp/plugin/lex.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Objective-C++ Parser plugin - Copyright (C) 2011 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - GCC is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - - -#ifndef HIDE_OBJC - -#include "c-family/c-objc.h" - -#define PLUGIN_UNQUALIFIED_NAME_LOOKUP_ERROR(name) @( - objc_diagnose_private_ivar (name)@) - -#else - -#define PLUGIN_UNQUALIFIED_NAME_LOOKUP_ERROR(name) 0 - -#endif diff --git a/gcc/objcp/plugin/parser.c b/gcc/objcp/plugin/parser.c deleted file mode 100644 index a2481f1859c..00000000000 --- a/gcc/objcp/plugin/parser.c +++ /dev/null @@ -1,1902 +0,0 @@ -/* Objective-C++ Parser plugin - Copyright (C) 2000, 2001, 2002, 2003, 2004, - 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - GCC is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - - -#ifndef HIDE_OBJC - -/* Objective-C++ Productions */ - - -/* Parse an Objective-C expression, which feeds into a primary-expression - above. - - objc-expression: - objc-message-expression - objc-string-literal - objc-encode-expression - objc-protocol-expression - objc-selector-expression - - Returns a tree representation of the expression. */ - -static tree -cp_parser_objc_expression (cp_parser* parser) -{ - /* Try to figure out what kind of declaration is present. */ - cp_token *kwd = cp_lexer_peek_token (parser->lexer); - - switch (kwd->type) - { - case CPP_OPEN_SQUARE: - return cp_parser_objc_message_expression (parser); - - case CPP_OBJC_STRING: - kwd = cp_lexer_consume_token (parser->lexer); - return objc_build_string_object (kwd->u.value); - - case CPP_KEYWORD: - switch (kwd->keyword) - { - case RID_AT_ENCODE: - return cp_parser_objc_encode_expression (parser); - - case RID_AT_PROTOCOL: - return cp_parser_objc_protocol_expression (parser); - - case RID_AT_SELECTOR: - return cp_parser_objc_selector_expression (parser); - - default: - break; - } - default: - error_at (kwd->location, - "misplaced %<@%D%> Objective-C++ construct", - kwd->u.value); - cp_parser_skip_to_end_of_block_or_statement (parser); - } - - return error_mark_node; -} - -/* Parse an Objective-C message expression. - - objc-message-expression: - [ objc-message-receiver objc-message-args ] - - Returns a representation of an Objective-C message. */ - -static tree -cp_parser_objc_message_expression (cp_parser* parser) -{ - tree receiver, messageargs; - - cp_lexer_consume_token (parser->lexer); /* Eat '['. */ - receiver = cp_parser_objc_message_receiver (parser); - messageargs = cp_parser_objc_message_args (parser); - cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); - - return objc_build_message_expr (build_tree_list (receiver, messageargs)); -} - -/* Parse an objc-message-receiver. - - objc-message-receiver: - expression - simple-type-specifier - - Returns a representation of the type or expression. */ - -static tree -cp_parser_objc_message_receiver (cp_parser* parser) -{ - tree rcv; - - /* An Objective-C message receiver may be either (1) a type - or (2) an expression. */ - cp_parser_parse_tentatively (parser); - rcv = cp_parser_expression (parser, false, NULL); - - if (cp_parser_parse_definitely (parser)) - return rcv; - - rcv = cp_parser_simple_type_specifier (parser, - /*decl_specs=*/NULL, - CP_PARSER_FLAGS_NONE); - - return objc_get_class_reference (rcv); -} - -/* Parse the arguments and selectors comprising an Objective-C message. - - objc-message-args: - objc-selector - objc-selector-args - objc-selector-args , objc-comma-args - - objc-selector-args: - objc-selector [opt] : assignment-expression - objc-selector-args objc-selector [opt] : assignment-expression - - objc-comma-args: - assignment-expression - objc-comma-args , assignment-expression - - Returns a TREE_LIST, with TREE_PURPOSE containing a list of - selector arguments and TREE_VALUE containing a list of comma - arguments. */ - -static tree -cp_parser_objc_message_args (cp_parser* parser) -{ - tree sel_args = NULL_TREE, addl_args = NULL_TREE; - bool maybe_unary_selector_p = true; - cp_token *token = cp_lexer_peek_token (parser->lexer); - - while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON) - { - tree selector = NULL_TREE, arg; - - if (token->type != CPP_COLON) - selector = cp_parser_objc_selector (parser); - - /* Detect if we have a unary selector. */ - if (maybe_unary_selector_p - && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) - return build_tree_list (selector, NULL_TREE); - - maybe_unary_selector_p = false; - cp_parser_require (parser, CPP_COLON, RT_COLON); - arg = cp_parser_assignment_expression (parser, false, NULL); - - sel_args - = chainon (sel_args, - build_tree_list (selector, arg)); - - token = cp_lexer_peek_token (parser->lexer); - } - - /* Handle non-selector arguments, if any. */ - while (token->type == CPP_COMMA) - { - tree arg; - - cp_lexer_consume_token (parser->lexer); - arg = cp_parser_assignment_expression (parser, false, NULL); - - addl_args - = chainon (addl_args, - build_tree_list (NULL_TREE, arg)); - - token = cp_lexer_peek_token (parser->lexer); - } - - if (sel_args == NULL_TREE && addl_args == NULL_TREE) - { - cp_parser_error (parser, "objective-c++ message argument(s) are expected"); - return build_tree_list (error_mark_node, error_mark_node); - } - - return build_tree_list (sel_args, addl_args); -} - -/* Parse an Objective-C encode expression. - - objc-encode-expression: - @encode objc-typename - - Returns an encoded representation of the type argument. */ - -static tree -cp_parser_objc_encode_expression (cp_parser* parser) -{ - tree type; - cp_token *token; - - cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); - token = cp_lexer_peek_token (parser->lexer); - type = complete_type (cp_parser_type_id (parser)); - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - - if (!type) - { - error_at (token->location, - "%<@encode%> must specify a type as an argument"); - return error_mark_node; - } - - /* This happens if we find @encode(T) (where T is a template - typename or something dependent on a template typename) when - parsing a template. In that case, we can't compile it - immediately, but we rather create an AT_ENCODE_EXPR which will - need to be instantiated when the template is used. - */ - if (dependent_type_p (type)) - { - tree value = build_min (AT_ENCODE_EXPR, size_type_node, type); - TREE_READONLY (value) = 1; - return value; - } - - return objc_build_encode_expr (type); -} - -/* Parse an Objective-C @defs expression. */ - -static tree -cp_parser_objc_defs_expression (cp_parser *parser) -{ - tree name; - - cp_lexer_consume_token (parser->lexer); /* Eat '@defs'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); - name = cp_parser_identifier (parser); - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - - return objc_get_class_ivars (name); -} - -/* Parse an Objective-C protocol expression. - - objc-protocol-expression: - @protocol ( identifier ) - - Returns a representation of the protocol expression. */ - -static tree -cp_parser_objc_protocol_expression (cp_parser* parser) -{ - tree proto; - - cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); - proto = cp_parser_identifier (parser); - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - - return objc_build_protocol_expr (proto); -} - -/* Parse an Objective-C selector expression. - - objc-selector-expression: - @selector ( objc-method-signature ) - - objc-method-signature: - objc-selector - objc-selector-seq - - objc-selector-seq: - objc-selector : - objc-selector-seq objc-selector : - - Returns a representation of the method selector. */ - -static tree -cp_parser_objc_selector_expression (cp_parser* parser) -{ - tree sel_seq = NULL_TREE; - bool maybe_unary_selector_p = true; - cp_token *token; - location_t loc = cp_lexer_peek_token (parser->lexer)->location; - - cp_lexer_consume_token (parser->lexer); /* Eat '@selector'. */ - cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); - token = cp_lexer_peek_token (parser->lexer); - - while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON - || token->type == CPP_SCOPE) - { - tree selector = NULL_TREE; - - if (token->type != CPP_COLON - || token->type == CPP_SCOPE) - selector = cp_parser_objc_selector (parser); - - if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON) - && cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE)) - { - /* Detect if we have a unary selector. */ - if (maybe_unary_selector_p) - { - sel_seq = selector; - goto finish_selector; - } - else - { - cp_parser_error (parser, "expected %<:%>"); - } - } - maybe_unary_selector_p = false; - token = cp_lexer_consume_token (parser->lexer); - - if (token->type == CPP_SCOPE) - { - sel_seq - = chainon (sel_seq, - build_tree_list (selector, NULL_TREE)); - sel_seq - = chainon (sel_seq, - build_tree_list (NULL_TREE, NULL_TREE)); - } - else - sel_seq - = chainon (sel_seq, - build_tree_list (selector, NULL_TREE)); - - token = cp_lexer_peek_token (parser->lexer); - } - - finish_selector: - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - - return objc_build_selector_expr (loc, sel_seq); -} - -/* Parse a list of identifiers. - - objc-identifier-list: - identifier - objc-identifier-list , identifier - - Returns a TREE_LIST of identifier nodes. */ - -static tree -cp_parser_objc_identifier_list (cp_parser* parser) -{ - tree identifier; - tree list; - cp_token *sep; - - identifier = cp_parser_identifier (parser); - if (identifier == error_mark_node) - return error_mark_node; - - list = build_tree_list (NULL_TREE, identifier); - sep = cp_lexer_peek_token (parser->lexer); - - while (sep->type == CPP_COMMA) - { - cp_lexer_consume_token (parser->lexer); /* Eat ','. */ - identifier = cp_parser_identifier (parser); - if (identifier == error_mark_node) - return list; - - list = chainon (list, build_tree_list (NULL_TREE, - identifier)); - sep = cp_lexer_peek_token (parser->lexer); - } - - return list; -} - -/* Parse an Objective-C alias declaration. - - objc-alias-declaration: - @compatibility_alias identifier identifier ; - - This function registers the alias mapping with the Objective-C front end. - It returns nothing. */ - -static void -cp_parser_objc_alias_declaration (cp_parser* parser) -{ - tree alias, orig; - - cp_lexer_consume_token (parser->lexer); /* Eat '@compatibility_alias'. */ - alias = cp_parser_identifier (parser); - orig = cp_parser_identifier (parser); - objc_declare_alias (alias, orig); - cp_parser_consume_semicolon_at_end_of_statement (parser); -} - -/* Parse an Objective-C class forward-declaration. - - objc-class-declaration: - @class objc-identifier-list ; - - The function registers the forward declarations with the Objective-C - front end. It returns nothing. */ - -static void -cp_parser_objc_class_declaration (cp_parser* parser) -{ - cp_lexer_consume_token (parser->lexer); /* Eat '@class'. */ - objc_declare_class (cp_parser_objc_identifier_list (parser)); - cp_parser_consume_semicolon_at_end_of_statement (parser); -} - -/* Parse a list of Objective-C protocol references. - - objc-protocol-refs-opt: - objc-protocol-refs [opt] - - objc-protocol-refs: - < objc-identifier-list > - - Returns a TREE_LIST of identifiers, if any. */ - -static tree -cp_parser_objc_protocol_refs_opt (cp_parser* parser) -{ - tree protorefs = NULL_TREE; - - if(cp_lexer_next_token_is (parser->lexer, CPP_LESS)) - { - cp_lexer_consume_token (parser->lexer); /* Eat '<'. */ - protorefs = cp_parser_objc_identifier_list (parser); - cp_parser_require (parser, CPP_GREATER, RT_GREATER); - } - - return protorefs; -} - -/* Parse a Objective-C visibility specification. */ - -static void -cp_parser_objc_visibility_spec (cp_parser* parser) -{ - cp_token *vis = cp_lexer_peek_token (parser->lexer); - - switch (vis->keyword) - { - case RID_AT_PRIVATE: - objc_set_visibility (OBJC_IVAR_VIS_PRIVATE); - break; - case RID_AT_PROTECTED: - objc_set_visibility (OBJC_IVAR_VIS_PROTECTED); - break; - case RID_AT_PUBLIC: - objc_set_visibility (OBJC_IVAR_VIS_PUBLIC); - break; - case RID_AT_PACKAGE: - objc_set_visibility (OBJC_IVAR_VIS_PACKAGE); - break; - default: - return; - } - - /* Eat '@private'/'@protected'/'@public'. */ - cp_lexer_consume_token (parser->lexer); -} - -/* Parse an Objective-C method type. Return 'true' if it is a class - (+) method, and 'false' if it is an instance (-) method. */ - -static inline bool -cp_parser_objc_method_type (cp_parser* parser) -{ - if (cp_lexer_consume_token (parser->lexer)->type == CPP_PLUS) - return true; - else - return false; -} - -/* Parse an Objective-C protocol qualifier. */ - -static tree -cp_parser_objc_protocol_qualifiers (cp_parser* parser) -{ - tree quals = NULL_TREE, node; - cp_token *token = cp_lexer_peek_token (parser->lexer); - - node = token->u.value; - - while (node && TREE_CODE (node) == IDENTIFIER_NODE - && (node == ridpointers [(int) RID_IN] - || node == ridpointers [(int) RID_OUT] - || node == ridpointers [(int) RID_INOUT] - || node == ridpointers [(int) RID_BYCOPY] - || node == ridpointers [(int) RID_BYREF] - || node == ridpointers [(int) RID_ONEWAY])) - { - quals = tree_cons (NULL_TREE, node, quals); - cp_lexer_consume_token (parser->lexer); - token = cp_lexer_peek_token (parser->lexer); - node = token->u.value; - } - - return quals; -} - -/* Parse an Objective-C typename. */ - -static tree -cp_parser_objc_typename (cp_parser* parser) -{ - tree type_name = NULL_TREE; - - if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) - { - tree proto_quals, cp_type = NULL_TREE; - - cp_lexer_consume_token (parser->lexer); /* Eat '('. */ - proto_quals = cp_parser_objc_protocol_qualifiers (parser); - - /* An ObjC type name may consist of just protocol qualifiers, in which - case the type shall default to 'id'. */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) - { - cp_type = cp_parser_type_id (parser); - - /* If the type could not be parsed, an error has already - been produced. For error recovery, behave as if it had - not been specified, which will use the default type - 'id'. */ - if (cp_type == error_mark_node) - { - cp_type = NULL_TREE; - /* We need to skip to the closing parenthesis as - cp_parser_type_id() does not seem to do it for - us. */ - cp_parser_skip_to_closing_parenthesis (parser, - /*recovering=*/true, - /*or_comma=*/false, - /*consume_paren=*/false); - } - } - - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - type_name = build_tree_list (proto_quals, cp_type); - } - - return type_name; -} - -/* Check to see if TYPE refers to an Objective-C selector name. */ - -static bool -cp_parser_objc_selector_p (enum cpp_ttype type) -{ - return (type == CPP_NAME || type == CPP_KEYWORD - || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND - || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT - || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ - || type == CPP_XOR || type == CPP_XOR_EQ); -} - -/* Parse an Objective-C selector. */ - -static tree -cp_parser_objc_selector (cp_parser* parser) -{ - cp_token *token = cp_lexer_consume_token (parser->lexer); - - if (!cp_parser_objc_selector_p (token->type)) - { - error_at (token->location, "invalid Objective-C++ selector name"); - return error_mark_node; - } - - /* C++ operator names are allowed to appear in ObjC selectors. */ - switch (token->type) - { - case CPP_AND_AND: return get_identifier ("and"); - case CPP_AND_EQ: return get_identifier ("and_eq"); - case CPP_AND: return get_identifier ("bitand"); - case CPP_OR: return get_identifier ("bitor"); - case CPP_COMPL: return get_identifier ("compl"); - case CPP_NOT: return get_identifier ("not"); - case CPP_NOT_EQ: return get_identifier ("not_eq"); - case CPP_OR_OR: return get_identifier ("or"); - case CPP_OR_EQ: return get_identifier ("or_eq"); - case CPP_XOR: return get_identifier ("xor"); - case CPP_XOR_EQ: return get_identifier ("xor_eq"); - default: return token->u.value; - } -} - -/* Parse an Objective-C params list. */ - -static tree -cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes) -{ - tree params = NULL_TREE; - bool maybe_unary_selector_p = true; - cp_token *token = cp_lexer_peek_token (parser->lexer); - - while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON) - { - tree selector = NULL_TREE, type_name, identifier; - tree parm_attr = NULL_TREE; - - if (token->keyword == RID_ATTRIBUTE) - break; - - if (token->type != CPP_COLON) - selector = cp_parser_objc_selector (parser); - - /* Detect if we have a unary selector. */ - if (maybe_unary_selector_p - && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) - { - params = selector; /* Might be followed by attributes. */ - break; - } - - maybe_unary_selector_p = false; - if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) - { - /* Something went quite wrong. There should be a colon - here, but there is not. Stop parsing parameters. */ - break; - } - type_name = cp_parser_objc_typename (parser); - /* New ObjC allows attributes on parameters too. */ - if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)) - parm_attr = cp_parser_attributes_opt (parser); - identifier = cp_parser_identifier (parser); - - params - = chainon (params, - objc_build_keyword_decl (selector, - type_name, - identifier, - parm_attr)); - - token = cp_lexer_peek_token (parser->lexer); - } - - if (params == NULL_TREE) - { - cp_parser_error (parser, "objective-c++ method declaration is expected"); - return error_mark_node; - } - - /* We allow tail attributes for the method. */ - if (token->keyword == RID_ATTRIBUTE) - { - *attributes = cp_parser_attributes_opt (parser); - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) - || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) - return params; - cp_parser_error (parser, - "method attributes must be specified at the end"); - return error_mark_node; - } - - if (params == NULL_TREE) - { - cp_parser_error (parser, "objective-c++ method declaration is expected"); - return error_mark_node; - } - return params; -} - -/* Parse the non-keyword Objective-C params. */ - -static tree -cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp, - tree* attributes) -{ - tree params = make_node (TREE_LIST); - cp_token *token = cp_lexer_peek_token (parser->lexer); - *ellipsisp = false; /* Initially, assume no ellipsis. */ - - while (token->type == CPP_COMMA) - { - cp_parameter_declarator *parmdecl; - tree parm; - - cp_lexer_consume_token (parser->lexer); /* Eat ','. */ - token = cp_lexer_peek_token (parser->lexer); - - if (token->type == CPP_ELLIPSIS) - { - cp_lexer_consume_token (parser->lexer); /* Eat '...'. */ - *ellipsisp = true; - token = cp_lexer_peek_token (parser->lexer); - break; - } - - /* TODO: parse attributes for tail parameters. */ - parmdecl = cp_parser_parameter_declaration (parser, false, NULL); - parm = grokdeclarator (parmdecl->declarator, - &parmdecl->decl_specifiers, - PARM, /*initialized=*/0, - /*attrlist=*/NULL); - - chainon (params, build_tree_list (NULL_TREE, parm)); - token = cp_lexer_peek_token (parser->lexer); - } - - /* We allow tail attributes for the method. */ - if (token->keyword == RID_ATTRIBUTE) - { - if (*attributes == NULL_TREE) - { - *attributes = cp_parser_attributes_opt (parser); - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) - || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) - return params; - } - else - /* We have an error, but parse the attributes, so that we can - carry on. */ - *attributes = cp_parser_attributes_opt (parser); - - cp_parser_error (parser, - "method attributes must be specified at the end"); - return error_mark_node; - } - - return params; -} - -/* Parse a linkage specification, a pragma, an extra semicolon or a block. */ - -static void -cp_parser_objc_interstitial_code (cp_parser* parser) -{ - cp_token *token = cp_lexer_peek_token (parser->lexer); - - /* If the next token is `extern' and the following token is a string - literal, then we have a linkage specification. */ - if (token->keyword == RID_EXTERN - && cp_parser_is_string_literal (cp_lexer_peek_nth_token (parser->lexer, 2))) - cp_parser_linkage_specification (parser); - /* Handle #pragma, if any. */ - else if (token->type == CPP_PRAGMA) - cp_parser_pragma (parser, pragma_external); - /* Allow stray semicolons. */ - else if (token->type == CPP_SEMICOLON) - cp_lexer_consume_token (parser->lexer); - /* Mark methods as optional or required, when building protocols. */ - else if (token->keyword == RID_AT_OPTIONAL) - { - cp_lexer_consume_token (parser->lexer); - objc_set_method_opt (true); - } - else if (token->keyword == RID_AT_REQUIRED) - { - cp_lexer_consume_token (parser->lexer); - objc_set_method_opt (false); - } - else if (token->keyword == RID_NAMESPACE) - cp_parser_namespace_definition (parser); - /* Other stray characters must generate errors. */ - else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE) - { - cp_lexer_consume_token (parser->lexer); - error ("stray %qs between Objective-C++ methods", - token->type == CPP_OPEN_BRACE ? "{" : "}"); - } - /* Finally, try to parse a block-declaration, or a function-definition. */ - else - cp_parser_block_declaration (parser, /*statement_p=*/false); -} - -/* Parse a method signature. */ - -static tree -cp_parser_objc_method_signature (cp_parser* parser, tree* attributes) -{ - tree rettype, kwdparms, optparms; - bool ellipsis = false; - bool is_class_method; - - is_class_method = cp_parser_objc_method_type (parser); - rettype = cp_parser_objc_typename (parser); - *attributes = NULL_TREE; - kwdparms = cp_parser_objc_method_keyword_params (parser, attributes); - if (kwdparms == error_mark_node) - return error_mark_node; - optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes); - if (optparms == error_mark_node) - return error_mark_node; - - return objc_build_method_signature (is_class_method, rettype, kwdparms, optparms, ellipsis); -} - -static bool -cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser) -{ - tree tattr; - cp_lexer_save_tokens (parser->lexer); - tattr = cp_parser_attributes_opt (parser); - gcc_assert (tattr) ; - - /* If the attributes are followed by a method introducer, this is not allowed. - Dump the attributes and flag the situation. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS) - || cp_lexer_next_token_is (parser->lexer, CPP_MINUS)) - return true; - - /* Otherwise, the attributes introduce some interstitial code, possibly so - rewind to allow that check. */ - cp_lexer_rollback_tokens (parser->lexer); - return false; -} - -/* Parse an Objective-C method prototype list. */ - -static void -cp_parser_objc_method_prototype_list (cp_parser* parser) -{ - cp_token *token = cp_lexer_peek_token (parser->lexer); - - while (token->keyword != RID_AT_END && token->type != CPP_EOF) - { - if (token->type == CPP_PLUS || token->type == CPP_MINUS) - { - tree attributes, sig; - bool is_class_method; - if (token->type == CPP_PLUS) - is_class_method = true; - else - is_class_method = false; - sig = cp_parser_objc_method_signature (parser, &attributes); - if (sig == error_mark_node) - { - cp_parser_skip_to_end_of_block_or_statement (parser); - token = cp_lexer_peek_token (parser->lexer); - continue; - } - objc_add_method_declaration (is_class_method, sig, attributes); - cp_parser_consume_semicolon_at_end_of_statement (parser); - } - else if (token->keyword == RID_AT_PROPERTY) - cp_parser_objc_at_property_declaration (parser); - else if (token->keyword == RID_ATTRIBUTE - && cp_parser_objc_method_maybe_bad_prefix_attributes(parser)) - warning_at (cp_lexer_peek_token (parser->lexer)->location, - OPT_Wattributes, - "prefix attributes are ignored for methods"); - else - /* Allow for interspersed non-ObjC++ code. */ - cp_parser_objc_interstitial_code (parser); - - token = cp_lexer_peek_token (parser->lexer); - } - - if (token->type != CPP_EOF) - cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */ - else - cp_parser_error (parser, "expected %<@end%>"); - - objc_finish_interface (); -} - -/* Parse an Objective-C method definition list. */ - -static void -cp_parser_objc_method_definition_list (cp_parser* parser) -{ - cp_token *token = cp_lexer_peek_token (parser->lexer); - - while (token->keyword != RID_AT_END && token->type != CPP_EOF) - { - tree meth; - - if (token->type == CPP_PLUS || token->type == CPP_MINUS) - { - cp_token *ptk; - tree sig, attribute; - bool is_class_method; - if (token->type == CPP_PLUS) - is_class_method = true; - else - is_class_method = false; - push_deferring_access_checks (dk_deferred); - sig = cp_parser_objc_method_signature (parser, &attribute); - if (sig == error_mark_node) - { - cp_parser_skip_to_end_of_block_or_statement (parser); - token = cp_lexer_peek_token (parser->lexer); - continue; - } - objc_start_method_definition (is_class_method, sig, attribute); - - /* For historical reasons, we accept an optional semicolon. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) - cp_lexer_consume_token (parser->lexer); - - ptk = cp_lexer_peek_token (parser->lexer); - if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS - || ptk->type == CPP_EOF || ptk->keyword == RID_AT_END)) - { - perform_deferred_access_checks (); - stop_deferring_access_checks (); - meth = cp_parser_function_definition_after_declarator (parser, - false); - pop_deferring_access_checks (); - objc_finish_method_definition (meth); - } - } - /* The following case will be removed once @synthesize is - completely implemented. */ - else if (token->keyword == RID_AT_PROPERTY) - cp_parser_objc_at_property_declaration (parser); - else if (token->keyword == RID_AT_SYNTHESIZE) - cp_parser_objc_at_synthesize_declaration (parser); - else if (token->keyword == RID_AT_DYNAMIC) - cp_parser_objc_at_dynamic_declaration (parser); - else if (token->keyword == RID_ATTRIBUTE - && cp_parser_objc_method_maybe_bad_prefix_attributes(parser)) - warning_at (token->location, OPT_Wattributes, - "prefix attributes are ignored for methods"); - else - /* Allow for interspersed non-ObjC++ code. */ - cp_parser_objc_interstitial_code (parser); - - token = cp_lexer_peek_token (parser->lexer); - } - - if (token->type != CPP_EOF) - cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */ - else - cp_parser_error (parser, "expected %<@end%>"); - - objc_finish_implementation (); -} - -/* Parse Objective-C ivars. */ - -static void -cp_parser_objc_class_ivars (cp_parser* parser) -{ - cp_token *token = cp_lexer_peek_token (parser->lexer); - - if (token->type != CPP_OPEN_BRACE) - return; /* No ivars specified. */ - - cp_lexer_consume_token (parser->lexer); /* Eat '{'. */ - token = cp_lexer_peek_token (parser->lexer); - - while (token->type != CPP_CLOSE_BRACE - && token->keyword != RID_AT_END && token->type != CPP_EOF) - { - cp_decl_specifier_seq declspecs; - int decl_class_or_enum_p; - tree prefix_attributes; - - cp_parser_objc_visibility_spec (parser); - - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE)) - break; - - cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_OPTIONAL, - &declspecs, - &decl_class_or_enum_p); - - /* auto, register, static, extern, mutable. */ - if (declspecs.storage_class != sc_none) - { - cp_parser_error (parser, "invalid type for instance variable"); - declspecs.storage_class = sc_none; - } - - /* __thread. */ - if (declspecs.specs[(int) ds_thread]) - { - cp_parser_error (parser, "invalid type for instance variable"); - declspecs.specs[(int) ds_thread] = 0; - } - - /* typedef. */ - if (declspecs.specs[(int) ds_typedef]) - { - cp_parser_error (parser, "invalid type for instance variable"); - declspecs.specs[(int) ds_typedef] = 0; - } - - prefix_attributes = declspecs.attributes; - declspecs.attributes = NULL_TREE; - - /* Keep going until we hit the `;' at the end of the - declaration. */ - while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - tree width = NULL_TREE, attributes, first_attribute, decl; - cp_declarator *declarator = NULL; - int ctor_dtor_or_conv_p; - - /* Check for a (possibly unnamed) bitfield declaration. */ - token = cp_lexer_peek_token (parser->lexer); - if (token->type == CPP_COLON) - goto eat_colon; - - if (token->type == CPP_NAME - && (cp_lexer_peek_nth_token (parser->lexer, 2)->type - == CPP_COLON)) - { - /* Get the name of the bitfield. */ - declarator = make_id_declarator (NULL_TREE, - cp_parser_identifier (parser), - sfk_none); - - eat_colon: - cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ - /* Get the width of the bitfield. */ - width - = cp_parser_constant_expression (parser, - /*allow_non_constant=*/false, - NULL); - } - else - { - /* Parse the declarator. */ - declarator - = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, - &ctor_dtor_or_conv_p, - /*parenthesized_p=*/NULL, - /*member_p=*/false); - } - - /* Look for attributes that apply to the ivar. */ - attributes = cp_parser_attributes_opt (parser); - /* Remember which attributes are prefix attributes and - which are not. */ - first_attribute = attributes; - /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); - - if (width) - /* Create the bitfield declaration. */ - decl = grokbitfield (declarator, &declspecs, - width, - attributes); - else - decl = grokfield (declarator, &declspecs, - NULL_TREE, /*init_const_expr_p=*/false, - NULL_TREE, attributes); - - /* Add the instance variable. */ - objc_add_instance_variable (decl); - - /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; - - token = cp_lexer_peek_token (parser->lexer); - - if (token->type == CPP_COMMA) - { - cp_lexer_consume_token (parser->lexer); /* Eat ','. */ - continue; - } - break; - } - - cp_parser_consume_semicolon_at_end_of_statement (parser); - token = cp_lexer_peek_token (parser->lexer); - } - - if (token->keyword == RID_AT_END) - cp_parser_error (parser, "expected %<}%>"); - - /* Do not consume the RID_AT_END, so it will be read again as terminating - the @interface of @implementation. */ - if (token->keyword != RID_AT_END && token->type != CPP_EOF) - cp_lexer_consume_token (parser->lexer); /* Eat '}'. */ - - /* For historical reasons, we accept an optional semicolon. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) - cp_lexer_consume_token (parser->lexer); -} - -/* Parse an Objective-C protocol declaration. */ - -static void -cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes) -{ - tree proto, protorefs; - cp_token *tok; - - cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) - { - tok = cp_lexer_peek_token (parser->lexer); - error_at (tok->location, "identifier expected after %<@protocol%>"); - goto finish; - } - - /* See if we have a forward declaration or a definition. */ - tok = cp_lexer_peek_nth_token (parser->lexer, 2); - - /* Try a forward declaration first. */ - if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON) - { - objc_declare_protocols (cp_parser_objc_identifier_list (parser), - attributes); - finish: - cp_parser_consume_semicolon_at_end_of_statement (parser); - } - - /* Ok, we got a full-fledged definition (or at least should). */ - else - { - proto = cp_parser_identifier (parser); - protorefs = cp_parser_objc_protocol_refs_opt (parser); - objc_start_protocol (proto, protorefs, attributes); - cp_parser_objc_method_prototype_list (parser); - } -} - -/* Parse an Objective-C superclass or category. */ - -static void -cp_parser_objc_superclass_or_category (cp_parser *parser, - bool iface_p, - tree *super, - tree *categ, bool *is_class_extension) -{ - cp_token *next = cp_lexer_peek_token (parser->lexer); - - *super = *categ = NULL_TREE; - *is_class_extension = false; - if (next->type == CPP_COLON) - { - cp_lexer_consume_token (parser->lexer); /* Eat ':'. */ - *super = cp_parser_identifier (parser); - } - else if (next->type == CPP_OPEN_PAREN) - { - cp_lexer_consume_token (parser->lexer); /* Eat '('. */ - - /* If there is no category name, and this is an @interface, we - have a class extension. */ - if (iface_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - { - *categ = NULL_TREE; - *is_class_extension = true; - } - else - *categ = cp_parser_identifier (parser); - - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - } -} - -/* Parse an Objective-C class interface. */ - -static void -cp_parser_objc_class_interface (cp_parser* parser, tree attributes) -{ - tree name, super, categ, protos; - bool is_class_extension; - - cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */ - name = cp_parser_identifier (parser); - if (name == error_mark_node) - { - /* It's hard to recover because even if valid @interface stuff - is to follow, we can't compile it (or validate it) if we - don't even know which class it refers to. Let's assume this - was a stray '@interface' token in the stream and skip it. - */ - return; - } - cp_parser_objc_superclass_or_category (parser, true, &super, &categ, - &is_class_extension); - protos = cp_parser_objc_protocol_refs_opt (parser); - - /* We have either a class or a category on our hands. */ - if (categ || is_class_extension) - objc_start_category_interface (name, categ, protos, attributes); - else - { - objc_start_class_interface (name, super, protos, attributes); - /* Handle instance variable declarations, if any. */ - cp_parser_objc_class_ivars (parser); - objc_continue_interface (); - } - - cp_parser_objc_method_prototype_list (parser); -} - -/* Parse an Objective-C class implementation. */ - -static void -cp_parser_objc_class_implementation (cp_parser* parser) -{ - tree name, super, categ; - bool is_class_extension; - - cp_lexer_consume_token (parser->lexer); /* Eat '@implementation'. */ - name = cp_parser_identifier (parser); - if (name == error_mark_node) - { - /* It's hard to recover because even if valid @implementation - stuff is to follow, we can't compile it (or validate it) if - we don't even know which class it refers to. Let's assume - this was a stray '@implementation' token in the stream and - skip it. - */ - return; - } - cp_parser_objc_superclass_or_category (parser, false, &super, &categ, - &is_class_extension); - - /* We have either a class or a category on our hands. */ - if (categ) - objc_start_category_implementation (name, categ); - else - { - objc_start_class_implementation (name, super); - /* Handle instance variable declarations, if any. */ - cp_parser_objc_class_ivars (parser); - objc_continue_implementation (); - } - - cp_parser_objc_method_definition_list (parser); -} - -/* Consume the @end token and finish off the implementation. */ - -static void -cp_parser_objc_end_implementation (cp_parser* parser) -{ - cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */ - objc_finish_implementation (); -} - -/* Parse an Objective-C declaration. */ - -static void -cp_parser_objc_declaration (cp_parser* parser, tree attributes) -{ - /* Try to figure out what kind of declaration is present. */ - cp_token *kwd = cp_lexer_peek_token (parser->lexer); - - if (attributes) - switch (kwd->keyword) - { - case RID_AT_ALIAS: - case RID_AT_CLASS: - case RID_AT_END: - error_at (kwd->location, "attributes may not be specified before" - " the %<@%D%> Objective-C++ keyword", - kwd->u.value); - attributes = NULL; - break; - case RID_AT_IMPLEMENTATION: - warning_at (kwd->location, OPT_Wattributes, - "prefix attributes are ignored before %<@%D%>", - kwd->u.value); - attributes = NULL; - default: - break; - } - - switch (kwd->keyword) - { - case RID_AT_ALIAS: - cp_parser_objc_alias_declaration (parser); - break; - case RID_AT_CLASS: - cp_parser_objc_class_declaration (parser); - break; - case RID_AT_PROTOCOL: - cp_parser_objc_protocol_declaration (parser, attributes); - break; - case RID_AT_INTERFACE: - cp_parser_objc_class_interface (parser, attributes); - break; - case RID_AT_IMPLEMENTATION: - cp_parser_objc_class_implementation (parser); - break; - case RID_AT_END: - cp_parser_objc_end_implementation (parser); - break; - default: - error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct", - kwd->u.value); - cp_parser_skip_to_end_of_block_or_statement (parser); - } -} - -/* Parse an Objective-C try-catch-finally statement. - - objc-try-catch-finally-stmt: - @try compound-statement objc-catch-clause-seq [opt] - objc-finally-clause [opt] - - objc-catch-clause-seq: - objc-catch-clause objc-catch-clause-seq [opt] - - objc-catch-clause: - @catch ( objc-exception-declaration ) compound-statement - - objc-finally-clause: - @finally compound-statement - - objc-exception-declaration: - parameter-declaration - '...' - - where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS. - - Returns NULL_TREE. - - PS: This function is identical to c_parser_objc_try_catch_finally_statement - for C. Keep them in sync. */ - -static tree -cp_parser_objc_try_catch_finally_statement (cp_parser *parser) -{ - location_t location; - tree stmt; - - cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY); - location = cp_lexer_peek_token (parser->lexer)->location; - objc_maybe_warn_exceptions (location); - /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST - node, lest it get absorbed into the surrounding block. */ - stmt = push_stmt_list (); - cp_parser_compound_statement (parser, NULL, false); - objc_begin_try_stmt (location, pop_stmt_list (stmt)); - - while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH)) - { - cp_parameter_declarator *parm; - tree parameter_declaration = error_mark_node; - bool seen_open_paren = false; - - cp_lexer_consume_token (parser->lexer); - if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) - seen_open_paren = true; - if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) - { - /* We have "@catch (...)" (where the '...' are literally - what is in the code). Skip the '...'. - parameter_declaration is set to NULL_TREE, and - objc_being_catch_clauses() knows that that means - '...'. */ - cp_lexer_consume_token (parser->lexer); - parameter_declaration = NULL_TREE; - } - else - { - /* We have "@catch (NSException *exception)" or something - like that. Parse the parameter declaration. */ - parm = cp_parser_parameter_declaration (parser, false, NULL); - if (parm == NULL) - parameter_declaration = error_mark_node; - else - parameter_declaration = grokdeclarator (parm->declarator, - &parm->decl_specifiers, - PARM, /*initialized=*/0, - /*attrlist=*/NULL); - } - if (seen_open_paren) - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - else - { - /* If there was no open parenthesis, we are recovering from - an error, and we are trying to figure out what mistake - the user has made. */ - - /* If there is an immediate closing parenthesis, the user - probably forgot the opening one (ie, they typed "@catch - NSException *e)". Parse the closing parenthesis and keep - going. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) - cp_lexer_consume_token (parser->lexer); - - /* If these is no immediate closing parenthesis, the user - probably doesn't know that parenthesis are required at - all (ie, they typed "@catch NSException *e"). So, just - forget about the closing parenthesis and keep going. */ - } - objc_begin_catch_clause (parameter_declaration); - cp_parser_compound_statement (parser, NULL, false); - objc_finish_catch_clause (); - } - if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY)) - { - cp_lexer_consume_token (parser->lexer); - location = cp_lexer_peek_token (parser->lexer)->location; - /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST - node, lest it get absorbed into the surrounding block. */ - stmt = push_stmt_list (); - cp_parser_compound_statement (parser, NULL, false); - objc_build_finally_clause (location, pop_stmt_list (stmt)); - } - - return objc_finish_try_stmt (); -} - -/* Parse an Objective-C synchronized statement. - - objc-synchronized-stmt: - @synchronized ( expression ) compound-statement - - Returns NULL_TREE. */ - -static tree -cp_parser_objc_synchronized_statement (cp_parser *parser) -{ - location_t location; - tree lock, stmt; - - cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED); - - location = cp_lexer_peek_token (parser->lexer)->location; - objc_maybe_warn_exceptions (location); - cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); - lock = cp_parser_expression (parser, false, NULL); - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - - /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST - node, lest it get absorbed into the surrounding block. */ - stmt = push_stmt_list (); - cp_parser_compound_statement (parser, NULL, false); - - return objc_build_synchronized (location, lock, pop_stmt_list (stmt)); -} - -/* Parse an Objective-C throw statement. - - objc-throw-stmt: - @throw assignment-expression [opt] ; - - Returns a constructed '@throw' statement. */ - -static tree -cp_parser_objc_throw_statement (cp_parser *parser) -{ - tree expr = NULL_TREE; - location_t loc = cp_lexer_peek_token (parser->lexer)->location; - - cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW); - - if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); - - cp_parser_consume_semicolon_at_end_of_statement (parser); - - return objc_build_throw_stmt (loc, expr); -} - -/* Parse an Objective-C statement. */ - -static tree -cp_parser_objc_statement (cp_parser * parser) -{ - /* Try to figure out what kind of declaration is present. */ - cp_token *kwd = cp_lexer_peek_token (parser->lexer); - - switch (kwd->keyword) - { - case RID_AT_TRY: - return cp_parser_objc_try_catch_finally_statement (parser); - case RID_AT_SYNCHRONIZED: - return cp_parser_objc_synchronized_statement (parser); - case RID_AT_THROW: - return cp_parser_objc_throw_statement (parser); - default: - error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct", - kwd->u.value); - cp_parser_skip_to_end_of_block_or_statement (parser); - } - - return error_mark_node; -} - -/* If we are compiling ObjC++ and we see an __attribute__ we neeed to - look ahead to see if an objc keyword follows the attributes. This - is to detect the use of prefix attributes on ObjC @interface and - @protocol. */ - -static bool -cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib) -{ - cp_lexer_save_tokens (parser->lexer); - *attrib = cp_parser_attributes_opt (parser); - gcc_assert (*attrib); - if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword)) - { - cp_lexer_commit_tokens (parser->lexer); - return true; - } - cp_lexer_rollback_tokens (parser->lexer); - return false; -} - -/* This routine is a minimal replacement for - c_parser_struct_declaration () used when parsing the list of - types/names or ObjC++ properties. For example, when parsing the - code - - @property (readonly) int a, b, c; - - this function is responsible for parsing "int a, int b, int c" and - returning the declarations as CHAIN of DECLs. - - TODO: Share this code with cp_parser_objc_class_ivars. It's very - similar parsing. */ -static tree -cp_parser_objc_struct_declaration (cp_parser *parser) -{ - tree decls = NULL_TREE; - cp_decl_specifier_seq declspecs; - int decl_class_or_enum_p; - tree prefix_attributes; - - cp_parser_decl_specifier_seq (parser, - CP_PARSER_FLAGS_NONE, - &declspecs, - &decl_class_or_enum_p); - - if (declspecs.type == error_mark_node) - return error_mark_node; - - /* auto, register, static, extern, mutable. */ - if (declspecs.storage_class != sc_none) - { - cp_parser_error (parser, "invalid type for property"); - declspecs.storage_class = sc_none; - } - - /* __thread. */ - if (declspecs.specs[(int) ds_thread]) - { - cp_parser_error (parser, "invalid type for property"); - declspecs.specs[(int) ds_thread] = 0; - } - - /* typedef. */ - if (declspecs.specs[(int) ds_typedef]) - { - cp_parser_error (parser, "invalid type for property"); - declspecs.specs[(int) ds_typedef] = 0; - } - - prefix_attributes = declspecs.attributes; - declspecs.attributes = NULL_TREE; - - /* Keep going until we hit the `;' at the end of the declaration. */ - while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - tree attributes, first_attribute, decl; - cp_declarator *declarator; - cp_token *token; - - /* Parse the declarator. */ - declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, - NULL, NULL, false); - - /* Look for attributes that apply to the ivar. */ - attributes = cp_parser_attributes_opt (parser); - /* Remember which attributes are prefix attributes and - which are not. */ - first_attribute = attributes; - /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); - - decl = grokfield (declarator, &declspecs, - NULL_TREE, /*init_const_expr_p=*/false, - NULL_TREE, attributes); - - if (decl == error_mark_node || decl == NULL_TREE) - return error_mark_node; - - /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; - - DECL_CHAIN (decl) = decls; - decls = decl; - - token = cp_lexer_peek_token (parser->lexer); - if (token->type == CPP_COMMA) - { - cp_lexer_consume_token (parser->lexer); /* Eat ','. */ - continue; - } - else - break; - } - return decls; -} - -/* Parse an Objective-C @property declaration. The syntax is: - - objc-property-declaration: - '@property' objc-property-attributes[opt] struct-declaration ; - - objc-property-attributes: - '(' objc-property-attribute-list ')' - - objc-property-attribute-list: - objc-property-attribute - objc-property-attribute-list, objc-property-attribute - - objc-property-attribute - 'getter' = identifier - 'setter' = identifier - 'readonly' - 'readwrite' - 'assign' - 'retain' - 'copy' - 'nonatomic' - - For example: - @property NSString *name; - @property (readonly) id object; - @property (retain, nonatomic, getter=getTheName) id name; - @property int a, b, c; - - PS: This function is identical to - c_parser_objc_at_property_declaration for C. Keep them in sync. */ -static void -cp_parser_objc_at_property_declaration (cp_parser *parser) -{ - /* The following variables hold the attributes of the properties as - parsed. They are 'false' or 'NULL_TREE' if the attribute was not - seen. When we see an attribute, we set them to 'true' (if they - are boolean properties) or to the identifier (if they have an - argument, ie, for getter and setter). Note that here we only - parse the list of attributes, check the syntax and accumulate the - attributes that we find. objc_add_property_declaration() will - then process the information. */ - bool property_assign = false; - bool property_copy = false; - tree property_getter_ident = NULL_TREE; - bool property_nonatomic = false; - bool property_readonly = false; - bool property_readwrite = false; - bool property_retain = false; - tree property_setter_ident = NULL_TREE; - - /* 'properties' is the list of properties that we read. Usually a - single one, but maybe more (eg, in "@property int a, b, c;" there - are three). */ - tree properties; - location_t loc; - - loc = cp_lexer_peek_token (parser->lexer)->location; - - cp_lexer_consume_token (parser->lexer); /* Eat '@property'. */ - - /* Parse the optional attribute list... */ - if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) - { - /* Eat the '('. */ - cp_lexer_consume_token (parser->lexer); - - while (true) - { - bool syntax_error = false; - cp_token *token = cp_lexer_peek_token (parser->lexer); - enum rid keyword; - - if (token->type != CPP_NAME) - { - cp_parser_error (parser, "expected identifier"); - break; - } - keyword = C_RID_CODE (token->u.value); - cp_lexer_consume_token (parser->lexer); - switch (keyword) - { - case RID_ASSIGN: property_assign = true; break; - case RID_COPY: property_copy = true; break; - case RID_NONATOMIC: property_nonatomic = true; break; - case RID_READONLY: property_readonly = true; break; - case RID_READWRITE: property_readwrite = true; break; - case RID_RETAIN: property_retain = true; break; - - case RID_GETTER: - case RID_SETTER: - if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)) - { - if (keyword == RID_GETTER) - cp_parser_error (parser, - "missing %<=%> (after %<getter%> attribute)"); - else - cp_parser_error (parser, - "missing %<=%> (after %<setter%> attribute)"); - syntax_error = true; - break; - } - cp_lexer_consume_token (parser->lexer); /* eat the = */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) - { - cp_parser_error (parser, "expected identifier"); - syntax_error = true; - break; - } - if (keyword == RID_SETTER) - { - if (property_setter_ident != NULL_TREE) - cp_parser_error (parser, "the %<setter%> attribute may only be specified once"); - else - property_setter_ident = cp_lexer_peek_token (parser->lexer)->u.value; - cp_lexer_consume_token (parser->lexer); - if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)) - cp_parser_error (parser, "setter name must terminate with %<:%>"); - else - cp_lexer_consume_token (parser->lexer); - } - else - { - if (property_getter_ident != NULL_TREE) - cp_parser_error (parser, "the %<getter%> attribute may only be specified once"); - else - property_getter_ident = cp_lexer_peek_token (parser->lexer)->u.value; - cp_lexer_consume_token (parser->lexer); - } - break; - default: - cp_parser_error (parser, "unknown property attribute"); - syntax_error = true; - break; - } - - if (syntax_error) - break; - - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); - else - break; - } - - /* FIXME: "@property (setter, assign);" will generate a spurious - "error: expected ‘)’ before ‘,’ token". This is because - cp_parser_require, unlike the C counterpart, will produce an - error even if we are in error recovery. */ - if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) - { - cp_parser_skip_to_closing_parenthesis (parser, - /*recovering=*/true, - /*or_comma=*/false, - /*consume_paren=*/true); - } - } - - /* ... and the property declaration(s). */ - properties = cp_parser_objc_struct_declaration (parser); - - if (properties == error_mark_node) - { - cp_parser_skip_to_end_of_statement (parser); - /* If the next token is now a `;', consume it. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) - cp_lexer_consume_token (parser->lexer); - return; - } - - if (properties == NULL_TREE) - cp_parser_error (parser, "expected identifier"); - else - { - /* Comma-separated properties are chained together in - reverse order; add them one by one. */ - properties = nreverse (properties); - - for (; properties; properties = TREE_CHAIN (properties)) - objc_add_property_declaration (loc, copy_node (properties), - property_readonly, property_readwrite, - property_assign, property_retain, - property_copy, property_nonatomic, - property_getter_ident, property_setter_ident); - } - - cp_parser_consume_semicolon_at_end_of_statement (parser); -} - -/* Parse an Objective-C++ @synthesize declaration. The syntax is: - - objc-synthesize-declaration: - @synthesize objc-synthesize-identifier-list ; - - objc-synthesize-identifier-list: - objc-synthesize-identifier - objc-synthesize-identifier-list, objc-synthesize-identifier - - objc-synthesize-identifier - identifier - identifier = identifier - - For example: - @synthesize MyProperty; - @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty; - - PS: This function is identical to c_parser_objc_at_synthesize_declaration - for C. Keep them in sync. -*/ -static void -cp_parser_objc_at_synthesize_declaration (cp_parser *parser) -{ - tree list = NULL_TREE; - location_t loc; - loc = cp_lexer_peek_token (parser->lexer)->location; - - cp_lexer_consume_token (parser->lexer); /* Eat '@synthesize'. */ - while (true) - { - tree property, ivar; - property = cp_parser_identifier (parser); - if (property == error_mark_node) - { - cp_parser_consume_semicolon_at_end_of_statement (parser); - return; - } - if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) - { - cp_lexer_consume_token (parser->lexer); - ivar = cp_parser_identifier (parser); - if (ivar == error_mark_node) - { - cp_parser_consume_semicolon_at_end_of_statement (parser); - return; - } - } - else - ivar = NULL_TREE; - list = chainon (list, build_tree_list (ivar, property)); - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); - else - break; - } - cp_parser_consume_semicolon_at_end_of_statement (parser); - objc_add_synthesize_declaration (loc, list); -} - -/* Parse an Objective-C++ @dynamic declaration. The syntax is: - - objc-dynamic-declaration: - @dynamic identifier-list ; - - For example: - @dynamic MyProperty; - @dynamic MyProperty, AnotherProperty; - - PS: This function is identical to c_parser_objc_at_dynamic_declaration - for C. Keep them in sync. -*/ -static void -cp_parser_objc_at_dynamic_declaration (cp_parser *parser) -{ - tree list = NULL_TREE; - location_t loc; - loc = cp_lexer_peek_token (parser->lexer)->location; - - cp_lexer_consume_token (parser->lexer); /* Eat '@dynamic'. */ - while (true) - { - tree property; - property = cp_parser_identifier (parser); - if (property == error_mark_node) - { - cp_parser_consume_semicolon_at_end_of_statement (parser); - return; - } - list = chainon (list, build_tree_list (NULL, property)); - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); - else - break; - } - cp_parser_consume_semicolon_at_end_of_statement (parser); - objc_add_dynamic_declaration (loc, list); -} - -#endif diff --git a/gcc/objcp/plugin/parser.h b/gcc/objcp/plugin/parser.h deleted file mode 100644 index a8344543389..00000000000 --- a/gcc/objcp/plugin/parser.h +++ /dev/null @@ -1,227 +0,0 @@ -/* Objective-C++ Parser plugin - Copyright (C) 2000, 2001, 2002, 2003, 2004, - 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - GCC is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - - -/* This isn't defined anywhere, yet, but it could be. This will turn off - the entire C++ Objective-C++ plugin. */ -#ifndef HIDE_OBJC - -#include "c-family/c-objc.h" - - -/* Objective-C++ Productions */ - -static tree cp_parser_objc_message_receiver - (cp_parser *); -static tree cp_parser_objc_message_args - (cp_parser *); -static tree cp_parser_objc_message_expression - (cp_parser *); -static tree cp_parser_objc_encode_expression - (cp_parser *); -static tree cp_parser_objc_defs_expression - (cp_parser *); -static tree cp_parser_objc_protocol_expression - (cp_parser *); -static tree cp_parser_objc_selector_expression - (cp_parser *); -static tree cp_parser_objc_expression - (cp_parser *); -static bool cp_parser_objc_selector_p - (enum cpp_ttype); -static tree cp_parser_objc_selector - (cp_parser *); -static tree cp_parser_objc_protocol_refs_opt - (cp_parser *); -static void cp_parser_objc_declaration - (cp_parser *, tree); -static tree cp_parser_objc_statement - (cp_parser *); -static bool cp_parser_objc_valid_prefix_attributes - (cp_parser *, tree *); -static void cp_parser_objc_at_property_declaration - (cp_parser *) ; -static void cp_parser_objc_at_synthesize_declaration - (cp_parser *) ; -static void cp_parser_objc_at_dynamic_declaration - (cp_parser *) ; -static tree cp_parser_objc_struct_declaration - (cp_parser *) ; - -#define PLUGIN_PRIMARY_EXPRESSION_3(parser) @( - do { - if (c_dialect_objc ()) - /* We have an Objective-C++ message. */ - return cp_parser_objc_expression (parser); - } while (0)@) - -#define PLUGIN_PRIMARY_EXPRESSION_2(parser, cp_parser_error) @( - case CPP_OBJC_STRING: - if (c_dialect_objc ()) - /* We have an Objective-C++ string literal. */ - return cp_parser_objc_expression (parser); - cp_parser_error (parser, "expected primary-expression"); - return error_mark_node;@) - -#define PLUGIN_PRIMARY_EXPRESSION_1(parser) @( - /* Objective-C++ expressions. */ - case RID_AT_ENCODE: - case RID_AT_PROTOCOL: - case RID_AT_SELECTOR: - return cp_parser_objc_expression (parser);@) - -#define PLUGIN_PRIMARY_EXPRESSION(parser, decl, cp_lexer_consume_token, cp_lexer_peek_token) @( - do { - /* In Objective-C++, we may have an Objective-C 2.0 - dot-syntax for classes here. */ - if (c_dialect_objc () - && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT - && TREE_CODE (decl) == TYPE_DECL - && objc_is_class_name (decl)) - { - tree component; - cp_lexer_consume_token (parser->lexer); - component = cp_parser_identifier (parser); - if (component == error_mark_node) - return error_mark_node; - - return objc_build_class_component_ref (id_expression, component); - } - - /* In Objective-C++, an instance variable (ivar) may be preferred - to whatever cp_parser_lookup_name() found. */ - decl = objc_lookup_ivar (decl, id_expression); - } while (0)@) - -#define PLUGIN_TOKEN_STARTS_CAST_EXPR @( - do { - /* '[' may start a primary-expression in obj-c++. */ - return c_dialect_objc (); - } while (0)@) - -#define PLUGIN_STATEMENT @( - /* Objective-C++ exception-handling constructs. */ - case RID_AT_TRY: - case RID_AT_CATCH: - case RID_AT_FINALLY: - case RID_AT_SYNCHRONIZED: - case RID_AT_THROW: - statement = cp_parser_objc_statement (parser); - break;@) - - -#define PLUGIN_DECLARATION(token1, attributes) @( - /* Objective-C++ declaration/definition. */ - else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword)) - cp_parser_objc_declaration (parser, NULL_TREE); - else if (c_dialect_objc () - && token1.keyword == RID_ATTRIBUTE - && cp_parser_objc_valid_prefix_attributes (parser, &attributes)) - cp_parser_objc_declaration (parser, attributes);@) - -#define PLUGIN_SIMPLE_TYPE_SPECIFIER(parser, type, decl_specs) @( - do { - /* See if TYPE is an Objective-C type, and if so, parse and - accept any protocol references following it. Do this before - the cp_parser_check_for_invalid_template_id() call, because - Objective-C types can be followed by '<...>' which would - enclose protocol names rather than template arguments, and so - everything is fine. */ - if (c_dialect_objc () && !parser->scope - && (objc_is_id (type) || objc_is_class_name (type))) - { - tree protos = cp_parser_objc_protocol_refs_opt (parser); - tree qual_type = objc_get_protocol_qualified_type (type, protos); - - /* Clobber the "unqualified" type previously entered into - DECL_SPECS with the new, improved protocol-qualified version. */ - if (decl_specs) - decl_specs->type = qual_type; - - return qual_type; - } - } while (0)@) - - -#define PLUGIN_NONCLASS_NAME1(parser, type_decl, identifier) @( - do { - if (TREE_CODE (type_decl) != TYPE_DECL - && (objc_is_id (identifier) || objc_is_class_name (identifier))) - { - /* See if this is an Objective-C type. */ - tree protos = cp_parser_objc_protocol_refs_opt (parser); - tree type = objc_get_protocol_qualified_type (identifier, protos); - if (type) - type_decl = TYPE_NAME (type); - } - } while (0)@) - -#define PLUGIN_NONCLASS_NAME(parser, type_decl, cp_lexer_peek_token) @( - /* In Objective-C, we have the complication that class names are - normally type names and start declarations (eg, the - "NSObject" in "NSObject *object;"), but can be used in an - Objective-C 2.0 dot-syntax (as in "NSObject.version") which - is an expression. So, a classname followed by a dot is not a - valid type-name. */ - || (objc_is_class_name (TREE_TYPE (type_decl)) - && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT)@) - -#define PLUGIN_CLASS_NAME(parser, cp_lexer_peek_token, CPP_DOT) @( - /* In Objective-C 2.0, a classname followed by '.' starts a - dot-syntax expression, and it's not a type-name. */ - || (c_dialect_objc () - && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT - && objc_is_class_name (decl))@) - -#define PLUGIN_MEMBER_DECLARATION(parser, cp_lexer_next_token_is_keyword, finish_member_declaration) @( - do { - /* Check for @defs. */ - if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_DEFS)) - { - tree ivar, member; - tree ivar_chains = cp_parser_objc_defs_expression (parser); - ivar = ivar_chains; - while (ivar) - { - member = ivar; - ivar = TREE_CHAIN (member); - TREE_CHAIN (member) = NULL_TREE; - finish_member_declaration (member); - } - return; - } - } while (0)@) - -#else - -#define PLUGIN_PRIMARY_EXPRESSION_3(parser) -#define PLUGIN_PRIMARY_EXPRESSION_2(parser, cp_parser_error) -#define PLUGIN_PRIMARY_EXPRESSION_1(parser) -#define PLUGIN_PRIMARY_EXPRESSION(parser, decl, cp_lexer_consume_token, cp_lexer_peek_token) -#define PLUGIN_TOKEN_STARTS_CAST_EXPR -#define PLUGIN_STATEMENT -#define PLUGIN_DECLARATION(token1, attributes) -#define PLUGIN_SIMPLE_TYPE_SPECIFIER(parser, type, decl_specs) -#define PLUGIN_NONCLASS_NAME1(parser, type_decl, identifier) -#define PLUGIN_NONCLASS_NAME(parser, type_decl, cp_lexer_peek_token) -#define PLUGIN_CLASS_NAME(parser, cp_lexer_peek_token, CPP_DOT) -#define PLUGIN_MEMBER_DECLARATION(parser, cp_lexer_next_token_is_keyword, finish_member_declaration) - -#endif |