diff options
Diffstat (limited to 'gcc-4.2.1')
-rw-r--r-- | gcc-4.2.1/gcc/c.opt.orig | 928 | ||||
-rw-r--r-- | gcc-4.2.1/gcc/cp/semantics.c.orig | 3953 |
2 files changed, 0 insertions, 4881 deletions
diff --git a/gcc-4.2.1/gcc/c.opt.orig b/gcc-4.2.1/gcc/c.opt.orig deleted file mode 100644 index 0d26a8047..000000000 --- a/gcc-4.2.1/gcc/c.opt.orig +++ /dev/null @@ -1,928 +0,0 @@ -; Options for the C, ObjC, C++ and ObjC++ front ends. -; Copyright (C) 2003, 2004, 2005, 2006 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 2, 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 COPYING. If not, write to the Free -; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -; 02110-1301, USA. - -; See the GCC internals manual for a description of this file's format. - -; Please try to keep this file in ASCII collating order. - -Language -C - -Language -ObjC - -Language -C++ - -Language -ObjC++ - --output-pch= -C ObjC C++ ObjC++ Joined Separate - -A -C ObjC C++ ObjC++ Joined Separate --A<question>=<answer> Assert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question> - -C -C ObjC C++ ObjC++ -Do not discard comments - -CC -C ObjC C++ ObjC++ -Do not discard comments in macro expansions - -D -C ObjC C++ ObjC++ Joined Separate --D<macro>[=<val>] Define a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1 - -E -C ObjC C++ ObjC++ Undocumented - -F -C ObjC C++ ObjC++ Joined Separate --F <dir> Add <dir> to the end of the main framework include path - -H -C ObjC C++ ObjC++ -Print the name of header files as they are used - -I -C ObjC C++ ObjC++ Joined Separate --I <dir> Add <dir> to the end of the main include path - -M -C ObjC C++ ObjC++ -Generate make dependencies - -MD -C ObjC C++ ObjC++ Separate -Generate make dependencies and compile - -MF -C ObjC C++ ObjC++ Joined Separate --MF <file> Write dependency output to the given file - -MG -C ObjC C++ ObjC++ -Treat missing header files as generated files - -MM -C ObjC C++ ObjC++ -Like -M but ignore system header files - -MMD -C ObjC C++ ObjC++ Separate -Like -MD but ignore system header files - -MP -C ObjC C++ ObjC++ -Generate phony targets for all headers - -MQ -C ObjC C++ ObjC++ Joined Separate --MQ <target> Add a MAKE-quoted target - -MT -C ObjC C++ ObjC++ Joined Separate --MT <target> Add an unquoted target - -P -C ObjC C++ ObjC++ -Do not generate #line directives - -U -C ObjC C++ ObjC++ Joined Separate --U<macro> Undefine <macro> - -Wabi -C++ ObjC++ Var(warn_abi) -Warn about things that will change when compiling with an ABI-compliant compiler - -Waddress -C ObjC C++ ObjC++ Var(warn_address) -Warn about suspicious uses of memory addresses - -Wall -C ObjC C++ ObjC++ -Enable most warning messages - -Wassign-intercept -ObjC ObjC++ Var(warn_assign_intercept) -Warn whenever an Objective-C assignment is being intercepted by the garbage collector - -Wbad-function-cast -C ObjC Var(warn_bad_function_cast) -Warn about casting functions to incompatible types - -Wc++-compat -C ObjC Var(warn_cxx_compat) -Warn about C constructs that are not in the common subset of C and C++ - - -Wcast-qual -C ObjC C++ ObjC++ Var(warn_cast_qual) -Warn about casts which discard qualifiers - -Wchar-subscripts -C ObjC C++ ObjC++ Var(warn_char_subscripts) -Warn about subscripts whose type is \"char\" - -Wcomment -C ObjC C++ ObjC++ -Warn about possibly nested block comments, and C++ comments spanning more than one physical line - -Wcomments -C ObjC C++ ObjC++ -Synonym for -Wcomment - -Wconversion -C ObjC C++ ObjC++ Var(warn_conversion) -Warn about possibly confusing type conversions - -Wctor-dtor-privacy -C++ ObjC++ Var(warn_ctor_dtor_privacy) -Warn when all constructors and destructors are private - -Wdeclaration-after-statement -C ObjC Var(warn_declaration_after_statement) -Warn when a declaration is found after a statement - -Wdeprecated -C++ ObjC++ Var(warn_deprecated) Init(1) -Warn about deprecated compiler features - -Wdiv-by-zero -C ObjC C++ ObjC++ Var(warn_div_by_zero) Init(1) -Warn about compile-time integer division by zero - -Weffc++ -C++ ObjC++ Var(warn_ecpp) -Warn about violations of Effective C++ style rules - -Wendif-labels -C ObjC C++ ObjC++ -Warn about stray tokens after #elif and #endif - -Werror -C ObjC C++ ObjC++ -; Documented in common.opt - -Werror-implicit-function-declaration -C ObjC RejectNegative -Make implicit function declarations an error - -Wfloat-equal -C ObjC C++ ObjC++ Var(warn_float_equal) -Warn if testing floating point numbers for equality - -Wformat -C ObjC C++ ObjC++ -Warn about printf/scanf/strftime/strfmon format string anomalies - -Wformat-extra-args -C ObjC C++ ObjC++ Var(warn_format_extra_args) -Warn if passing too many arguments to a function for its format string - -Wformat-nonliteral -C ObjC C++ ObjC++ Var(warn_format_nonliteral) -Warn about format strings that are not literals - -Wformat-security -C ObjC C++ ObjC++ Var(warn_format_security) -Warn about possible security problems with format functions - -Wformat-y2k -C ObjC C++ ObjC++ Var(warn_format_y2k) -Warn about strftime formats yielding 2-digit years - -Wformat-zero-length -C ObjC Var(warn_format_zero_length) -Warn about zero-length formats - -Wformat= -C ObjC C++ ObjC++ Joined - -Winit-self -C ObjC C++ ObjC++ Var(warn_init_self) -Warn about variables which are initialized to themselves - -Wimplicit -C ObjC C++ ObjC++ - -Wimplicit-function-declaration -C ObjC Var(mesg_implicit_function_declaration) Init(-1) -Warn about implicit function declarations - -Wimplicit-int -C ObjC Var(warn_implicit_int) -Warn when a declaration does not specify a type - -Wimport -C ObjC C++ ObjC++ -Deprecated. This switch has no effect - -Wint-to-pointer-cast -C ObjC Var(warn_int_to_pointer_cast) Init(1) -Warn when there is a cast to a pointer from an integer of a different size - -Winvalid-offsetof -C++ ObjC++ Var(warn_invalid_offsetof) Init(1) -Warn about invalid uses of the \"offsetof\" macro - -Winvalid-pch -C ObjC C++ ObjC++ -Warn about PCH files that are found but not used - -Wlong-long -C ObjC C++ ObjC++ Var(warn_long_long) Init(1) -Do not warn about using \"long long\" when -pedantic - -Wmain -C ObjC -Warn about suspicious declarations of \"main\" - -Wmissing-braces -C ObjC C++ ObjC++ Var(warn_missing_braces) -Warn about possibly missing braces around initializers - -Wmissing-declarations -C ObjC Var(warn_missing_declarations) -Warn about global functions without previous declarations - -Wmissing-field-initializers -C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Init(-1) -Warn about missing fields in struct initializers - -Wmissing-format-attribute -C ObjC C++ ObjC++ Var(warn_missing_format_attribute) -Warn about functions which might be candidates for format attributes - -Wmissing-include-dirs -C ObjC C++ ObjC++ -Warn about user-specified include directories that do not exist - -Wmissing-prototypes -C ObjC Var(warn_missing_prototypes) -Warn about global functions without prototypes - -Wmultichar -C ObjC C++ ObjC++ -Warn about use of multi-character character constants - -Wnested-externs -C ObjC Var(warn_nested_externs) -Warn about \"extern\" declarations not at file scope - -Wnon-template-friend -C++ ObjC++ Var(warn_nontemplate_friend) Init(1) -Warn when non-templatized friend functions are declared within a template - -Wnon-virtual-dtor -C++ ObjC++ Var(warn_nonvdtor) -Warn about non-virtual destructors - -Wnonnull -C ObjC Var(warn_nonnull) -Warn about NULL being passed to argument slots marked as requiring non-NULL - -Wnormalized= -C ObjC C++ ObjC++ Joined --Wnormalized=<id|nfc|nfkc> Warn about non-normalised Unicode strings - -Wold-style-cast -C++ ObjC++ Var(warn_old_style_cast) -Warn if a C-style cast is used in a program - -Wold-style-definition -C ObjC Var(warn_old_style_definition) -Warn if an old-style parameter definition is used - -Woverlength-strings -C ObjC C++ ObjC++ Var(warn_overlength_strings) Init(-1) -Warn if a string is longer than the maximum portable length specified by the standard - -Woverloaded-virtual -C++ ObjC++ Var(warn_overloaded_virtual) -Warn about overloaded virtual function names - -Woverride-init -C ObjC Var(warn_override_init) Init(-1) -Warn about overriding initializers without side effects - -Wparentheses -C ObjC C++ ObjC++ Var(warn_parentheses) -Warn about possibly missing parentheses - -Wpmf-conversions -C++ ObjC++ Var(warn_pmf2ptr) Init(1) -Warn when converting the type of pointers to member functions - -Wpointer-arith -C ObjC C++ ObjC++ Var(warn_pointer_arith) -Warn about function pointer arithmetic - -Wpointer-to-int-cast -C ObjC Var(warn_pointer_to_int_cast) Init(1) -Warn when a pointer is cast to an integer of a different size - -Wpragmas -C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) -Warn about misuses of pragmas - -Wprotocol -ObjC ObjC++ Var(warn_protocol) Init(1) -Warn if inherited methods are unimplemented - -Wredundant-decls -C ObjC C++ ObjC++ Var(warn_redundant_decls) -Warn about multiple declarations of the same object - -Wreorder -C++ ObjC++ Var(warn_reorder) -Warn when the compiler reorders code - -Wreturn-type -C ObjC C++ ObjC++ Var(warn_return_type) -Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++) - -Wselector -ObjC ObjC++ Var(warn_selector) -Warn if a selector has multiple methods - -Wsequence-point -C ObjC C++ ObjC++ Var(warn_sequence_point) -Warn about possible violations of sequence point rules - -Wsign-compare -C ObjC C++ ObjC++ Var(warn_sign_compare) Init(-1) -Warn about signed-unsigned comparisons - -Wsign-promo -C++ ObjC++ Var(warn_sign_promo) -Warn when overload promotes from unsigned to signed - -Wstrict-null-sentinel -C++ ObjC++ -Warn about uncasted NULL used as sentinel - -Wstrict-prototypes -C ObjC Var(warn_strict_prototypes) -Warn about unprototyped function declarations - -Wstrict-selector-match -ObjC ObjC++ Var(warn_strict_selector_match) -Warn if type signatures of candidate methods do not match exactly - -Wsynth -C++ ObjC++ Var(warn_synth) -Warn when synthesis behavior differs from Cfront - -Wsystem-headers -C ObjC C++ ObjC++ -Do not suppress warnings from system headers - -Wtraditional -C ObjC Var(warn_traditional) -Warn about features not present in traditional C - -Wtrigraphs -C ObjC C++ ObjC++ -Warn if trigraphs are encountered that might affect the meaning of the program - -Wundeclared-selector -ObjC ObjC++ Var(warn_undeclared_selector) -Warn about @selector()s without previously declared methods - -Wundef -C ObjC C++ ObjC++ -Warn if an undefined macro is used in an #if directive - -Wunknown-pragmas -C ObjC C++ ObjC++ -Warn about unrecognized pragmas - -Wunused-macros -C ObjC C++ ObjC++ -Warn about macros defined in the main file that are not used - -Wvariadic-macros -C ObjC C++ ObjC++ -Do not warn about using variadic macros when -pedantic - -Wvla -C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning -Warn if a variable length array is used - -Wwrite-strings -C ObjC C++ ObjC++ Var(warn_write_strings) -In C++, nonzero means warn about deprecated conversion from string literals to `char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard. - -Wpointer-sign -C ObjC Var(warn_pointer_sign) Init(-1) -Warn when a pointer differs in signedness in an assignment - -ansi -C ObjC C++ ObjC++ -A synonym for -std=c89 (for C) or -std=c++98 (for C++) - -d -C ObjC C++ ObjC++ Joined -; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD? - -faccess-control -C++ ObjC++ -Enforce class member access control semantics - -fall-virtual -C++ ObjC++ - -falt-external-templates -C++ ObjC++ -Change when template instances are emitted - -fasm -C ObjC C++ ObjC++ -Recognize the \"asm\" keyword - -fbuiltin -C ObjC C++ ObjC++ -Recognize built-in functions - -fbuiltin- -C ObjC C++ ObjC++ Joined - -fcheck-new -C++ ObjC++ -Check the return value of new - -fcond-mismatch -C ObjC C++ ObjC++ -Allow the arguments of the '?' operator to have different types - -fconserve-space -C++ ObjC++ -Reduce the size of object files - -fconstant-string-class= -ObjC ObjC++ Joined --fconst-string-class=<name> Use class <name> for constant strings - -fdefault-inline -C++ ObjC++ -Inline member functions by default - -fdirectives-only -C ObjC C++ ObjC++ -Preprocess directives only. - -fdollars-in-identifiers -C ObjC C++ ObjC++ -Permit '$' as an identifier character - -felide-constructors -C++ ObjC++ - -fenforce-eh-specs -C++ ObjC++ -Generate code to check exception specifications - -fenum-int-equiv -C++ ObjC++ - -fexec-charset= -C ObjC C++ ObjC++ Joined RejectNegative --fexec-charset=<cset> Convert all strings and character constants to character set <cset> - -fextended-identifiers -C ObjC C++ ObjC++ -Permit universal character names (\\u and \\U) in identifiers - -finput-charset= -C ObjC C++ ObjC++ Joined RejectNegative --finput-charset=<cset> Specify the default character set for source files - - -fexternal-templates -C++ ObjC++ - -ffor-scope -C++ ObjC++ -Scope of for-init-statement variables is local to the loop - -ffreestanding -C ObjC -Do not assume that standard C libraries and \"main\" exist - -fgnu-keywords -C++ ObjC++ -Recognize GNU-defined keywords - -fgnu-runtime -ObjC ObjC++ -Generate code for GNU runtime environment - -fgnu89-inline -C ObjC Var(flag_gnu89_inline) Init(-1) -Use traditional GNU semantics for inline functions - -fguiding-decls -C++ ObjC++ - -fhandle-exceptions -C++ ObjC++ - -fhonor-std -C++ ObjC++ - -fhosted -C ObjC -Assume normal C execution environment - -fhuge-objects -C++ ObjC++ -Enable support for huge objects - -fimplement-inlines -C++ ObjC++ -Export functions even if they can be inlined - -fimplicit-inline-templates -C++ ObjC++ -Emit implicit instantiations of inline templates - -fimplicit-templates -C++ ObjC++ -Emit implicit instantiations of templates - -ffriend-injection -C++ ObjC++ Var(flag_friend_injection) -Inject friend functions into enclosing namespace - -flabels-ok -C++ ObjC++ - -fms-extensions -C ObjC C++ ObjC++ -Don't warn about uses of Microsoft extensions - -fname-mangling-version- -C++ ObjC++ Joined - -fnew-abi -C++ ObjC++ - -fnext-runtime -ObjC ObjC++ -Generate code for NeXT (Apple Mac OS X) runtime environment - -fnil-receivers -ObjC ObjC++ -Assume that receivers of Objective-C messages may be nil - -fnonansi-builtins -C++ ObjC++ - -fnonnull-objects -C++ ObjC++ - -; Generate special '- .cxx_construct' and '- .cxx_destruct' methods -; to initialize any non-POD ivars in Objective-C++ classes. -fobjc-call-cxx-cdtors -ObjC++ Var(flag_objc_call_cxx_cdtors) -Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed - -fobjc-direct-dispatch -ObjC ObjC++ Var(flag_objc_direct_dispatch) -Allow fast jumps to the message dispatcher - -; Nonzero means that we will allow new ObjC exception syntax (@throw, -; @try, etc.) in source code. -fobjc-exceptions -ObjC ObjC++ Var(flag_objc_exceptions) -Enable Objective-C exception and synchronization syntax - -fobjc-gc -ObjC ObjC++ Var(flag_objc_gc) -Enable garbage collection (GC) in Objective-C/Objective-C++ programs - -; Nonzero means that we generate NeXT setjmp based exceptions. -fobjc-sjlj-exceptions -ObjC ObjC++ Var(flag_objc_sjlj_exceptions) Init(-1) -Enable Objective-C setjmp exception handling runtime - -fopenmp -C ObjC C++ ObjC++ Var(flag_openmp) -Enable OpenMP - -foperator-names -C++ ObjC++ -Recognize C++ kewords like \"compl\" and \"xor\" - -foptional-diags -C++ ObjC++ -Enable optional diagnostics - -fpch-deps -C ObjC C++ ObjC++ - -fpch-preprocess -C ObjC C++ ObjC++ -Look for and use PCH files even when preprocessing - -fpermissive -C++ ObjC++ -Downgrade conformance errors to warnings - -fpreprocessed -C ObjC C++ ObjC++ -Treat the input file as already preprocessed - -freplace-objc-classes -ObjC ObjC++ -Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime - -frepo -C++ ObjC++ -Enable automatic template instantiation - -frtti -C++ ObjC++ -Generate run time type descriptor information - -fshort-double -C ObjC C++ ObjC++ -Use the same size for double as for float - -fshort-enums -C ObjC C++ ObjC++ -Use the narrowest integer type possible for enumeration types - -fshort-wchar -C ObjC C++ ObjC++ -Force the underlying type for \"wchar_t\" to be \"unsigned short\" - -fsigned-bitfields -C ObjC C++ ObjC++ -When \"signed\" or \"unsigned\" is not given make the bitfield signed - -fsigned-char -C ObjC C++ ObjC++ -Make \"char\" signed by default - -fsquangle -C++ ObjC++ - -fstats -C++ ObjC++ -Display statistics accumulated during compilation - -fstrict-prototype -C++ ObjC++ - -ftabstop= -C ObjC C++ ObjC++ Joined RejectNegative UInteger --ftabstop=<number> Distance between tab stops for column reporting - -ftemplate-depth- -C++ ObjC++ Joined RejectNegative UInteger --ftemplate-depth-<number> Specify maximum template instantiation depth - -fthis-is-variable -C++ ObjC++ - -fthreadsafe-statics -C++ ObjC++ --fno-threadsafe-statics Do not generate thread-safe code for initializing local statics - -funsigned-bitfields -C ObjC C++ ObjC++ -When \"signed\" or \"unsigned\" is not given make the bitfield unsigned - -funsigned-char -C ObjC C++ ObjC++ -Make \"char\" unsigned by default - -fuse-cxa-atexit -C++ ObjC++ -Use __cxa_atexit to register destructors - -fuse-cxa-get-exception-ptr -C++ ObjC++ -Use __cxa_get_exception_ptr in exception handling - -fvisibility-inlines-hidden -C++ ObjC++ -Marks all inlined methods as having hidden visibility - -fvtable-gc -C++ ObjC++ -Discard unused virtual functions - -fvtable-thunks -C++ ObjC++ -Implement vtables using thunks - -fweak -C++ ObjC++ -Emit common-like symbols as weak symbols - -fwide-exec-charset= -C ObjC C++ ObjC++ Joined RejectNegative --fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset> - -fworking-directory -C ObjC C++ ObjC++ -Generate a #line directive pointing at the current working directory - -fxref -C++ ObjC++ -Emit cross referencing information - -fzero-link -ObjC ObjC++ -Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode - -gen-decls -ObjC ObjC++ -Dump declarations to a .decl file - -femit-struct-debug-baseonly -C ObjC C++ ObjC++ --femit-struct-debug-baseonly Aggressive reduced debug info for structs - -femit-struct-debug-reduced -C ObjC C++ ObjC++ --femit-struct-debug-reduced Conservative reduced debug info for structs - -femit-struct-debug-detailed= -C ObjC C++ ObjC++ Joined --femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs - -idirafter -C ObjC C++ ObjC++ Joined Separate --idirafter <dir> Add <dir> to the end of the system include path - -imacros -C ObjC C++ ObjC++ Joined Separate --imacros <file> Accept definition of macros in <file> - -imultilib -C ObjC C++ ObjC++ Joined Separate --imultilib <dir> Set <dir> to be the multilib include subdirectory - -include -C ObjC C++ ObjC++ Joined Separate --include <file> Include the contents of <file> before other files - -iprefix -C ObjC C++ ObjC++ Joined Separate --iprefix <path> Specify <path> as a prefix for next two options - -isysroot -C ObjC C++ ObjC++ Joined Separate --isysroot <dir> Set <dir> to be the system root directory - -isystem -C ObjC C++ ObjC++ Joined Separate --isystem <dir> Add <dir> to the start of the system include path - -iquote -C ObjC C++ ObjC++ Joined Separate --iquote <dir> Add <dir> to the end of the quote include path - -iwithprefix -C ObjC C++ ObjC++ Joined Separate --iwithprefix <dir> Add <dir> to the end of the system include path - -iwithprefixbefore -C ObjC C++ ObjC++ Joined Separate --iwithprefixbefore <dir> Add <dir> to the end of the main include path - -lang-asm -C Undocumented - -lang-fortran -C Undocumented - -lang-objc -C ObjC C++ ObjC++ Undocumented - -nostdinc -C ObjC C++ ObjC++ -Do not search standard system include directories (those specified with -isystem will still be used) - -nostdinc++ -C++ ObjC++ -Do not search standard system include directories for C++ - -o -C ObjC C++ ObjC++ Joined Separate -; Documented in common.opt - -pedantic -C ObjC C++ ObjC++ -; Documented in common.opt - -pedantic-errors -C ObjC C++ ObjC++ -; Documented in common.opt - -print-objc-runtime-info -ObjC ObjC++ -Generate C header of platform-specific features - -print-pch-checksum -C ObjC C++ ObjC++ -Print a checksum of the executable for PCH validity checking, and stop - -remap -C ObjC C++ ObjC++ -Remap file names when including files - -std=c++98 -C++ ObjC++ -Conform to the ISO 1998 C++ standard - -std=c89 -C ObjC -Conform to the ISO 1990 C standard - -std=c99 -C ObjC -Conform to the ISO 1999 C standard - -std=c9x -C ObjC -Deprecated in favor of -std=c99 - -std=gnu++98 -C++ ObjC++ -Conform to the ISO 1998 C++ standard with GNU extensions - -std=gnu89 -C ObjC -Conform to the ISO 1990 C standard with GNU extensions - -std=gnu99 -C ObjC -Conform to the ISO 1999 C standard with GNU extensions - -std=gnu9x -C ObjC -Deprecated in favor of -std=gnu99 - -std=iso9899:1990 -C ObjC -Conform to the ISO 1990 C standard - -std=iso9899:199409 -C ObjC -Conform to the ISO 1990 C standard as amended in 1994 - -std=iso9899:1999 -C ObjC -Conform to the ISO 1999 C standard - -std=iso9899:199x -C ObjC -Deprecated in favor of -std=iso9899:1999 - -traditional-cpp -C ObjC C++ ObjC++ -Enable traditional preprocessing - -trigraphs -C ObjC C++ ObjC++ --trigraphs Support ISO C trigraphs - -undef -C ObjC C++ ObjC++ -Do not predefine system-specific and GCC-specific macros - -v -C ObjC C++ ObjC++ -Enable verbose output - -w -C ObjC C++ ObjC++ -; Documented in common.opt - -; This comment is to ensure we retain the blank line above. diff --git a/gcc-4.2.1/gcc/cp/semantics.c.orig b/gcc-4.2.1/gcc/cp/semantics.c.orig deleted file mode 100644 index 7c8054f24..000000000 --- a/gcc-4.2.1/gcc/cp/semantics.c.orig +++ /dev/null @@ -1,3953 +0,0 @@ -/* Perform the semantic phase of parsing, i.e., the process of - building tree structure, checking semantic consistency, and - building RTL. These routines are used both during actual parsing - and during the instantiation of template functions. - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. - Written by Mark Mitchell (mmitchell@usa.net) based on code found - formerly in parse.y and pt.c. - - 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 2, 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 COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "tree.h" -#include "cp-tree.h" -#include "c-common.h" -#include "tree-inline.h" -#include "tree-mudflap.h" -#include "except.h" -#include "toplev.h" -#include "flags.h" -#include "rtl.h" -#include "expr.h" -#include "output.h" -#include "timevar.h" -#include "debug.h" -#include "diagnostic.h" -#include "cgraph.h" -#include "tree-iterator.h" -#include "vec.h" -#include "target.h" - -/* There routines provide a modular interface to perform many parsing - operations. They may therefore be used during actual parsing, or - during template instantiation, which may be regarded as a - degenerate form of parsing. */ - -static tree maybe_convert_cond (tree); -static tree simplify_aggr_init_exprs_r (tree *, int *, void *); -static void emit_associated_thunks (tree); -static tree finalize_nrv_r (tree *, int *, void *); - - -/* Deferred Access Checking Overview - --------------------------------- - - Most C++ expressions and declarations require access checking - to be performed during parsing. However, in several cases, - this has to be treated differently. - - For member declarations, access checking has to be deferred - until more information about the declaration is known. For - example: - - class A { - typedef int X; - public: - X f(); - }; - - A::X A::f(); - A::X g(); - - When we are parsing the function return type `A::X', we don't - really know if this is allowed until we parse the function name. - - Furthermore, some contexts require that access checking is - never performed at all. These include class heads, and template - instantiations. - - Typical use of access checking functions is described here: - - 1. When we enter a context that requires certain access checking - mode, the function `push_deferring_access_checks' is called with - DEFERRING argument specifying the desired mode. Access checking - may be performed immediately (dk_no_deferred), deferred - (dk_deferred), or not performed (dk_no_check). - - 2. When a declaration such as a type, or a variable, is encountered, - the function `perform_or_defer_access_check' is called. It - maintains a VEC of all deferred checks. - - 3. The global `current_class_type' or `current_function_decl' is then - setup by the parser. `enforce_access' relies on these information - to check access. - - 4. Upon exiting the context mentioned in step 1, - `perform_deferred_access_checks' is called to check all declaration - stored in the VEC. `pop_deferring_access_checks' is then - called to restore the previous access checking mode. - - In case of parsing error, we simply call `pop_deferring_access_checks' - without `perform_deferred_access_checks'. */ - -typedef struct deferred_access GTY(()) -{ - /* A VEC representing name-lookups for which we have deferred - checking access controls. We cannot check the accessibility of - names used in a decl-specifier-seq until we know what is being - declared because code like: - - class A { - class B {}; - B* f(); - } - - A::B* A::f() { return 0; } - - is valid, even though `A::B' is not generally accessible. */ - VEC (deferred_access_check,gc)* GTY(()) deferred_access_checks; - - /* The current mode of access checks. */ - enum deferring_kind deferring_access_checks_kind; - -} deferred_access; -DEF_VEC_O (deferred_access); -DEF_VEC_ALLOC_O (deferred_access,gc); - -/* Data for deferred access checking. */ -static GTY(()) VEC(deferred_access,gc) *deferred_access_stack; -static GTY(()) unsigned deferred_access_no_check; - -/* Save the current deferred access states and start deferred - access checking iff DEFER_P is true. */ - -void -push_deferring_access_checks (deferring_kind deferring) -{ - /* For context like template instantiation, access checking - disabling applies to all nested context. */ - if (deferred_access_no_check || deferring == dk_no_check) - deferred_access_no_check++; - else - { - deferred_access *ptr; - - ptr = VEC_safe_push (deferred_access, gc, deferred_access_stack, NULL); - ptr->deferred_access_checks = NULL; - ptr->deferring_access_checks_kind = deferring; - } -} - -/* Resume deferring access checks again after we stopped doing - this previously. */ - -void -resume_deferring_access_checks (void) -{ - if (!deferred_access_no_check) - VEC_last (deferred_access, deferred_access_stack) - ->deferring_access_checks_kind = dk_deferred; -} - -/* Stop deferring access checks. */ - -void -stop_deferring_access_checks (void) -{ - if (!deferred_access_no_check) - VEC_last (deferred_access, deferred_access_stack) - ->deferring_access_checks_kind = dk_no_deferred; -} - -/* Discard the current deferred access checks and restore the - previous states. */ - -void -pop_deferring_access_checks (void) -{ - if (deferred_access_no_check) - deferred_access_no_check--; - else - VEC_pop (deferred_access, deferred_access_stack); -} - -/* Returns a TREE_LIST representing the deferred checks. - The TREE_PURPOSE of each node is the type through which the - access occurred; the TREE_VALUE is the declaration named. - */ - -VEC (deferred_access_check,gc)* -get_deferred_access_checks (void) -{ - if (deferred_access_no_check) - return NULL; - else - return (VEC_last (deferred_access, deferred_access_stack) - ->deferred_access_checks); -} - -/* Take current deferred checks and combine with the - previous states if we also defer checks previously. - Otherwise perform checks now. */ - -void -pop_to_parent_deferring_access_checks (void) -{ - if (deferred_access_no_check) - deferred_access_no_check--; - else - { - VEC (deferred_access_check,gc) *checks; - deferred_access *ptr; - - checks = (VEC_last (deferred_access, deferred_access_stack) - ->deferred_access_checks); - - VEC_pop (deferred_access, deferred_access_stack); - ptr = VEC_last (deferred_access, deferred_access_stack); - if (ptr->deferring_access_checks_kind == dk_no_deferred) - { - /* Check access. */ - perform_access_checks (checks); - } - else - { - /* Merge with parent. */ - int i, j; - deferred_access_check *chk, *probe; - - for (i = 0 ; - VEC_iterate (deferred_access_check, checks, i, chk) ; - ++i) - { - for (j = 0 ; - VEC_iterate (deferred_access_check, - ptr->deferred_access_checks, j, probe) ; - ++j) - { - if (probe->binfo == chk->binfo && - probe->decl == chk->decl && - probe->diag_decl == chk->diag_decl) - goto found; - } - /* Insert into parent's checks. */ - VEC_safe_push (deferred_access_check, gc, - ptr->deferred_access_checks, chk); - found:; - } - } - } -} - -/* Perform the access checks in CHECKS. The TREE_PURPOSE of each node - is the BINFO indicating the qualifying scope used to access the - DECL node stored in the TREE_VALUE of the node. */ - -void -perform_access_checks (VEC (deferred_access_check,gc)* checks) -{ - int i; - deferred_access_check *chk; - - if (!checks) - return; - - for (i = 0 ; VEC_iterate (deferred_access_check, checks, i, chk) ; ++i) - enforce_access (chk->binfo, chk->decl, chk->diag_decl); -} - -/* Perform the deferred access checks. - - After performing the checks, we still have to keep the list - `deferred_access_stack->deferred_access_checks' since we may want - to check access for them again later in a different context. - For example: - - class A { - typedef int X; - static X a; - }; - A::X A::a, x; // No error for `A::a', error for `x' - - We have to perform deferred access of `A::X', first with `A::a', - next with `x'. */ - -void -perform_deferred_access_checks (void) -{ - perform_access_checks (get_deferred_access_checks ()); -} - -/* Defer checking the accessibility of DECL, when looked up in - BINFO. DIAG_DECL is the declaration to use to print diagnostics. */ - -void -perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl) -{ - int i; - deferred_access *ptr; - deferred_access_check *chk; - deferred_access_check *new_access; - - - /* Exit if we are in a context that no access checking is performed. - */ - if (deferred_access_no_check) - return; - - gcc_assert (TREE_CODE (binfo) == TREE_BINFO); - - ptr = VEC_last (deferred_access, deferred_access_stack); - - /* If we are not supposed to defer access checks, just check now. */ - if (ptr->deferring_access_checks_kind == dk_no_deferred) - { - enforce_access (binfo, decl, diag_decl); - return; - } - - /* See if we are already going to perform this check. */ - for (i = 0 ; - VEC_iterate (deferred_access_check, - ptr->deferred_access_checks, i, chk) ; - ++i) - { - if (chk->decl == decl && chk->binfo == binfo && - chk->diag_decl == diag_decl) - { - return; - } - } - /* If not, record the check. */ - new_access = - VEC_safe_push (deferred_access_check, gc, - ptr->deferred_access_checks, 0); - new_access->binfo = binfo; - new_access->decl = decl; - new_access->diag_decl = diag_decl; -} - -/* Returns nonzero if the current statement is a full expression, - i.e. temporaries created during that statement should be destroyed - at the end of the statement. */ - -int -stmts_are_full_exprs_p (void) -{ - return current_stmt_tree ()->stmts_are_full_exprs_p; -} - -/* T is a statement. Add it to the statement-tree. This is the C++ - version. The C/ObjC frontends have a slightly different version of - this function. */ - -tree -add_stmt (tree t) -{ - enum tree_code code = TREE_CODE (t); - - if (EXPR_P (t) && code != LABEL_EXPR) - { - if (!EXPR_HAS_LOCATION (t)) - SET_EXPR_LOCATION (t, input_location); - - /* When we expand a statement-tree, we must know whether or not the - statements are full-expressions. We record that fact here. */ - STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); - } - - /* Add T to the statement-tree. Non-side-effect statements need to be - recorded during statement expressions. */ - append_to_statement_list_force (t, &cur_stmt_list); - - return t; -} - -/* Returns the stmt_tree (if any) to which statements are currently - being added. If there is no active statement-tree, NULL is - returned. */ - -stmt_tree -current_stmt_tree (void) -{ - return (cfun - ? &cfun->language->base.x_stmt_tree - : &scope_chain->x_stmt_tree); -} - -/* If statements are full expressions, wrap STMT in a CLEANUP_POINT_EXPR. */ - -static tree -maybe_cleanup_point_expr (tree expr) -{ - if (!processing_template_decl && stmts_are_full_exprs_p ()) - expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr); - return expr; -} - -/* Like maybe_cleanup_point_expr except have the type of the new expression be - void so we don't need to create a temporary variable to hold the inner - expression. The reason why we do this is because the original type might be - an aggregate and we cannot create a temporary variable for that type. */ - -static tree -maybe_cleanup_point_expr_void (tree expr) -{ - if (!processing_template_decl && stmts_are_full_exprs_p ()) - expr = fold_build_cleanup_point_expr (void_type_node, expr); - return expr; -} - - - -/* Create a declaration statement for the declaration given by the DECL. */ - -void -add_decl_expr (tree decl) -{ - tree r = build_stmt (DECL_EXPR, decl); - if (DECL_INITIAL (decl) - || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl)))) - r = maybe_cleanup_point_expr_void (r); - add_stmt (r); -} - -/* Nonzero if TYPE is an anonymous union or struct type. We have to use a - flag for this because "A union for which objects or pointers are - declared is not an anonymous union" [class.union]. */ - -int -anon_aggr_type_p (tree node) -{ - return ANON_AGGR_TYPE_P (node); -} - -/* Finish a scope. */ - -tree -do_poplevel (tree stmt_list) -{ - tree block = NULL; - - if (stmts_are_full_exprs_p ()) - block = poplevel (kept_level_p (), 1, 0); - - stmt_list = pop_stmt_list (stmt_list); - - if (!processing_template_decl) - { - stmt_list = c_build_bind_expr (block, stmt_list); - /* ??? See c_end_compound_stmt re statement expressions. */ - } - - return stmt_list; -} - -/* Begin a new scope. */ - -static tree -do_pushlevel (scope_kind sk) -{ - tree ret = push_stmt_list (); - if (stmts_are_full_exprs_p ()) - begin_scope (sk, NULL); - return ret; -} - -/* Queue a cleanup. CLEANUP is an expression/statement to be executed - when the current scope is exited. EH_ONLY is true when this is not - meant to apply to normal control flow transfer. */ - -void -push_cleanup (tree decl, tree cleanup, bool eh_only) -{ - tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl); - CLEANUP_EH_ONLY (stmt) = eh_only; - add_stmt (stmt); - CLEANUP_BODY (stmt) = push_stmt_list (); -} - -/* Begin a conditional that might contain a declaration. When generating - normal code, we want the declaration to appear before the statement - containing the conditional. When generating template code, we want the - conditional to be rendered as the raw DECL_EXPR. */ - -static void -begin_cond (tree *cond_p) -{ - if (processing_template_decl) - *cond_p = push_stmt_list (); -} - -/* Finish such a conditional. */ - -static void -finish_cond (tree *cond_p, tree expr) -{ - if (processing_template_decl) - { - tree cond = pop_stmt_list (*cond_p); - if (TREE_CODE (cond) == DECL_EXPR) - expr = cond; - } - *cond_p = expr; -} - -/* If *COND_P specifies a conditional with a declaration, transform the - loop such that - while (A x = 42) { } - for (; A x = 42;) { } - becomes - while (true) { A x = 42; if (!x) break; } - for (;;) { A x = 42; if (!x) break; } - The statement list for BODY will be empty if the conditional did - not declare anything. */ - -static void -simplify_loop_decl_cond (tree *cond_p, tree body) -{ - tree cond, if_stmt; - - if (!TREE_SIDE_EFFECTS (body)) - return; - - cond = *cond_p; - *cond_p = boolean_true_node; - - if_stmt = begin_if_stmt (); - cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0); - finish_if_stmt_cond (cond, if_stmt); - finish_break_stmt (); - finish_then_clause (if_stmt); - finish_if_stmt (if_stmt); -} - -/* Finish a goto-statement. */ - -tree -finish_goto_stmt (tree destination) -{ - if (TREE_CODE (destination) == IDENTIFIER_NODE) - destination = lookup_label (destination); - - /* We warn about unused labels with -Wunused. That means we have to - mark the used labels as used. */ - if (TREE_CODE (destination) == LABEL_DECL) - TREE_USED (destination) = 1; - else - { - /* The DESTINATION is being used as an rvalue. */ - if (!processing_template_decl) - destination = decay_conversion (destination); - /* We don't inline calls to functions with computed gotos. - Those functions are typically up to some funny business, - and may be depending on the labels being at particular - addresses, or some such. */ - DECL_UNINLINABLE (current_function_decl) = 1; - } - - check_goto (destination); - - return add_stmt (build_stmt (GOTO_EXPR, destination)); -} - -/* COND is the condition-expression for an if, while, etc., - statement. Convert it to a boolean value, if appropriate. */ - -static tree -maybe_convert_cond (tree cond) -{ - /* Empty conditions remain empty. */ - if (!cond) - return NULL_TREE; - - /* Wait until we instantiate templates before doing conversion. */ - if (processing_template_decl) - return cond; - - /* Do the conversion. */ - cond = convert_from_reference (cond); - - if (TREE_CODE (cond) == MODIFY_EXPR - && !TREE_NO_WARNING (cond) - && warn_parentheses) - { - warning (OPT_Wparentheses, - "suggest parentheses around assignment used as truth value"); - TREE_NO_WARNING (cond) = 1; - } - - return condition_conversion (cond); -} - -/* Finish an expression-statement, whose EXPRESSION is as indicated. */ - -tree -finish_expr_stmt (tree expr) -{ - tree r = NULL_TREE; - - if (expr != NULL_TREE) - { - if (!processing_template_decl) - { - if (warn_sequence_point) - verify_sequence_points (expr); - expr = convert_to_void (expr, "statement"); - } - else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "statement"); - - /* Simplification of inner statement expressions, compound exprs, - etc can result in us already having an EXPR_STMT. */ - if (TREE_CODE (expr) != CLEANUP_POINT_EXPR) - { - if (TREE_CODE (expr) != EXPR_STMT) - expr = build_stmt (EXPR_STMT, expr); - expr = maybe_cleanup_point_expr_void (expr); - } - - r = add_stmt (expr); - } - - finish_stmt (); - - return r; -} - - -/* Begin an if-statement. Returns a newly created IF_STMT if - appropriate. */ - -tree -begin_if_stmt (void) -{ - tree r, scope; - scope = do_pushlevel (sk_block); - r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE); - TREE_CHAIN (r) = scope; - begin_cond (&IF_COND (r)); - return r; -} - -/* Process the COND of an if-statement, which may be given by - IF_STMT. */ - -void -finish_if_stmt_cond (tree cond, tree if_stmt) -{ - finish_cond (&IF_COND (if_stmt), maybe_convert_cond (cond)); - add_stmt (if_stmt); - THEN_CLAUSE (if_stmt) = push_stmt_list (); -} - -/* Finish the then-clause of an if-statement, which may be given by - IF_STMT. */ - -tree -finish_then_clause (tree if_stmt) -{ - THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt)); - return if_stmt; -} - -/* Begin the else-clause of an if-statement. */ - -void -begin_else_clause (tree if_stmt) -{ - ELSE_CLAUSE (if_stmt) = push_stmt_list (); -} - -/* Finish the else-clause of an if-statement, which may be given by - IF_STMT. */ - -void -finish_else_clause (tree if_stmt) -{ - ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt)); -} - -/* Finish an if-statement. */ - -void -finish_if_stmt (tree if_stmt) -{ - tree scope = TREE_CHAIN (if_stmt); - TREE_CHAIN (if_stmt) = NULL; - add_stmt (do_poplevel (scope)); - finish_stmt (); - empty_body_warning (THEN_CLAUSE (if_stmt), ELSE_CLAUSE (if_stmt)); -} - -/* Begin a while-statement. Returns a newly created WHILE_STMT if - appropriate. */ - -tree -begin_while_stmt (void) -{ - tree r; - r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE); - add_stmt (r); - WHILE_BODY (r) = do_pushlevel (sk_block); - begin_cond (&WHILE_COND (r)); - return r; -} - -/* Process the COND of a while-statement, which may be given by - WHILE_STMT. */ - -void -finish_while_stmt_cond (tree cond, tree while_stmt) -{ - finish_cond (&WHILE_COND (while_stmt), maybe_convert_cond (cond)); - simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt)); -} - -/* Finish a while-statement, which may be given by WHILE_STMT. */ - -void -finish_while_stmt (tree while_stmt) -{ - WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt)); - finish_stmt (); -} - -/* Begin a do-statement. Returns a newly created DO_STMT if - appropriate. */ - -tree -begin_do_stmt (void) -{ - tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE); - add_stmt (r); - DO_BODY (r) = push_stmt_list (); - return r; -} - -/* Finish the body of a do-statement, which may be given by DO_STMT. */ - -void -finish_do_body (tree do_stmt) -{ - DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt)); -} - -/* Finish a do-statement, which may be given by DO_STMT, and whose - COND is as indicated. */ - -void -finish_do_stmt (tree cond, tree do_stmt) -{ - cond = maybe_convert_cond (cond); - DO_COND (do_stmt) = cond; - finish_stmt (); -} - -/* Finish a return-statement. The EXPRESSION returned, if any, is as - indicated. */ - -tree -finish_return_stmt (tree expr) -{ - tree r; - bool no_warning; - - expr = check_return_expr (expr, &no_warning); - - if (flag_openmp && !check_omp_return ()) - return error_mark_node; - if (!processing_template_decl) - { - if (DECL_DESTRUCTOR_P (current_function_decl) - || (DECL_CONSTRUCTOR_P (current_function_decl) - && targetm.cxx.cdtor_returns_this ())) - { - /* Similarly, all destructors must run destructors for - base-classes before returning. So, all returns in a - destructor get sent to the DTOR_LABEL; finish_function emits - code to return a value there. */ - return finish_goto_stmt (cdtor_label); - } - } - - r = build_stmt (RETURN_EXPR, expr); - TREE_NO_WARNING (r) |= no_warning; - r = maybe_cleanup_point_expr_void (r); - r = add_stmt (r); - finish_stmt (); - - return r; -} - -/* Begin a for-statement. Returns a new FOR_STMT if appropriate. */ - -tree -begin_for_stmt (void) -{ - tree r; - - r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE, - NULL_TREE, NULL_TREE); - - if (flag_new_for_scope > 0) - TREE_CHAIN (r) = do_pushlevel (sk_for); - - if (processing_template_decl) - FOR_INIT_STMT (r) = push_stmt_list (); - - return r; -} - -/* Finish the for-init-statement of a for-statement, which may be - given by FOR_STMT. */ - -void -finish_for_init_stmt (tree for_stmt) -{ - if (processing_template_decl) - FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt)); - add_stmt (for_stmt); - FOR_BODY (for_stmt) = do_pushlevel (sk_block); - begin_cond (&FOR_COND (for_stmt)); -} - -/* Finish the COND of a for-statement, which may be given by - FOR_STMT. */ - -void -finish_for_cond (tree cond, tree for_stmt) -{ - finish_cond (&FOR_COND (for_stmt), maybe_convert_cond (cond)); - simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt)); -} - -/* Finish the increment-EXPRESSION in a for-statement, which may be - given by FOR_STMT. */ - -void -finish_for_expr (tree expr, tree for_stmt) -{ - if (!expr) - return; - /* If EXPR is an overloaded function, issue an error; there is no - context available to use to perform overload resolution. */ - if (type_unknown_p (expr)) - { - cxx_incomplete_type_error (expr, TREE_TYPE (expr)); - expr = error_mark_node; - } - if (!processing_template_decl) - { - if (warn_sequence_point) - verify_sequence_points (expr); - expr = convert_to_void (expr, "3rd expression in for"); - } - else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "3rd expression in for"); - expr = maybe_cleanup_point_expr_void (expr); - FOR_EXPR (for_stmt) = expr; -} - -/* Finish the body of a for-statement, which may be given by - FOR_STMT. The increment-EXPR for the loop must be - provided. */ - -void -finish_for_stmt (tree for_stmt) -{ - FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt)); - - /* Pop the scope for the body of the loop. */ - if (flag_new_for_scope > 0) - { - tree scope = TREE_CHAIN (for_stmt); - TREE_CHAIN (for_stmt) = NULL; - add_stmt (do_poplevel (scope)); - } - - finish_stmt (); -} - -/* Finish a break-statement. */ - -tree -finish_break_stmt (void) -{ - return add_stmt (build_stmt (BREAK_STMT)); -} - -/* Finish a continue-statement. */ - -tree -finish_continue_stmt (void) -{ - return add_stmt (build_stmt (CONTINUE_STMT)); -} - -/* Begin a switch-statement. Returns a new SWITCH_STMT if - appropriate. */ - -tree -begin_switch_stmt (void) -{ - tree r, scope; - - r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE); - - scope = do_pushlevel (sk_block); - TREE_CHAIN (r) = scope; - begin_cond (&SWITCH_STMT_COND (r)); - - return r; -} - -/* Finish the cond of a switch-statement. */ - -void -finish_switch_cond (tree cond, tree switch_stmt) -{ - tree orig_type = NULL; - if (!processing_template_decl) - { - tree index; - - /* Convert the condition to an integer or enumeration type. */ - cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true); - if (cond == NULL_TREE) - { - error ("switch quantity not an integer"); - cond = error_mark_node; - } - orig_type = TREE_TYPE (cond); - if (cond != error_mark_node) - { - /* [stmt.switch] - - Integral promotions are performed. */ - cond = perform_integral_promotions (cond); - cond = maybe_cleanup_point_expr (cond); - } - - if (cond != error_mark_node) - { - index = get_unwidened (cond, NULL_TREE); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TYPE_UNSIGNED (TREE_TYPE (cond)) - == TYPE_UNSIGNED (TREE_TYPE (index))) - cond = index; - } - } - finish_cond (&SWITCH_STMT_COND (switch_stmt), cond); - SWITCH_STMT_TYPE (switch_stmt) = orig_type; - add_stmt (switch_stmt); - push_switch (switch_stmt); - SWITCH_STMT_BODY (switch_stmt) = push_stmt_list (); -} - -/* Finish the body of a switch-statement, which may be given by - SWITCH_STMT. The COND to switch on is indicated. */ - -void -finish_switch_stmt (tree switch_stmt) -{ - tree scope; - - SWITCH_STMT_BODY (switch_stmt) = - pop_stmt_list (SWITCH_STMT_BODY (switch_stmt)); - pop_switch (); - finish_stmt (); - - scope = TREE_CHAIN (switch_stmt); - TREE_CHAIN (switch_stmt) = NULL; - add_stmt (do_poplevel (scope)); -} - -/* Begin a try-block. Returns a newly-created TRY_BLOCK if - appropriate. */ - -tree -begin_try_block (void) -{ - tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE); - add_stmt (r); - TRY_STMTS (r) = push_stmt_list (); - return r; -} - -/* Likewise, for a function-try-block. The block returned in - *COMPOUND_STMT is an artificial outer scope, containing the - function-try-block. */ - -tree -begin_function_try_block (tree *compound_stmt) -{ - tree r; - /* This outer scope does not exist in the C++ standard, but we need - a place to put __FUNCTION__ and similar variables. */ - *compound_stmt = begin_compound_stmt (0); - r = begin_try_block (); - FN_TRY_BLOCK_P (r) = 1; - return r; -} - -/* Finish a try-block, which may be given by TRY_BLOCK. */ - -void -finish_try_block (tree try_block) -{ - TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block)); - TRY_HANDLERS (try_block) = push_stmt_list (); -} - -/* Finish the body of a cleanup try-block, which may be given by - TRY_BLOCK. */ - -void -finish_cleanup_try_block (tree try_block) -{ - TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block)); -} - -/* Finish an implicitly generated try-block, with a cleanup is given - by CLEANUP. */ - -void -finish_cleanup (tree cleanup, tree try_block) -{ - TRY_HANDLERS (try_block) = cleanup; - CLEANUP_P (try_block) = 1; -} - -/* Likewise, for a function-try-block. */ - -void -finish_function_try_block (tree try_block) -{ - finish_try_block (try_block); - /* FIXME : something queer about CTOR_INITIALIZER somehow following - the try block, but moving it inside. */ - in_function_try_handler = 1; -} - -/* Finish a handler-sequence for a try-block, which may be given by - TRY_BLOCK. */ - -void -finish_handler_sequence (tree try_block) -{ - TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block)); - check_handlers (TRY_HANDLERS (try_block)); -} - -/* Finish the handler-seq for a function-try-block, given by - TRY_BLOCK. COMPOUND_STMT is the outer block created by - begin_function_try_block. */ - -void -finish_function_handler_sequence (tree try_block, tree compound_stmt) -{ - in_function_try_handler = 0; - finish_handler_sequence (try_block); - finish_compound_stmt (compound_stmt); -} - -/* Begin a handler. Returns a HANDLER if appropriate. */ - -tree -begin_handler (void) -{ - tree r; - - r = build_stmt (HANDLER, NULL_TREE, NULL_TREE); - add_stmt (r); - - /* Create a binding level for the eh_info and the exception object - cleanup. */ - HANDLER_BODY (r) = do_pushlevel (sk_catch); - - return r; -} - -/* Finish the handler-parameters for a handler, which may be given by - HANDLER. DECL is the declaration for the catch parameter, or NULL - if this is a `catch (...)' clause. */ - -void -finish_handler_parms (tree decl, tree handler) -{ - tree type = NULL_TREE; - if (processing_template_decl) - { - if (decl) - { - decl = pushdecl (decl); - decl = push_template_decl (decl); - HANDLER_PARMS (handler) = decl; - type = TREE_TYPE (decl); - } - } - else - type = expand_start_catch_block (decl); - HANDLER_TYPE (handler) = type; - if (!processing_template_decl && type) - mark_used (eh_type_info (type)); -} - -/* Finish a handler, which may be given by HANDLER. The BLOCKs are - the return value from the matching call to finish_handler_parms. */ - -void -finish_handler (tree handler) -{ - if (!processing_template_decl) - expand_end_catch_block (); - HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler)); -} - -/* Begin a compound statement. FLAGS contains some bits that control the - behavior and context. If BCS_NO_SCOPE is set, the compound statement - does not define a scope. If BCS_FN_BODY is set, this is the outermost - block of a function. If BCS_TRY_BLOCK is set, this is the block - created on behalf of a TRY statement. Returns a token to be passed to - finish_compound_stmt. */ - -tree -begin_compound_stmt (unsigned int flags) -{ - tree r; - - if (flags & BCS_NO_SCOPE) - { - r = push_stmt_list (); - STATEMENT_LIST_NO_SCOPE (r) = 1; - - /* Normally, we try hard to keep the BLOCK for a statement-expression. - But, if it's a statement-expression with a scopeless block, there's - nothing to keep, and we don't want to accidentally keep a block - *inside* the scopeless block. */ - keep_next_level (false); - } - else - r = do_pushlevel (flags & BCS_TRY_BLOCK ? sk_try : sk_block); - - /* When processing a template, we need to remember where the braces were, - so that we can set up identical scopes when instantiating the template - later. BIND_EXPR is a handy candidate for this. - Note that do_poplevel won't create a BIND_EXPR itself here (and thus - result in nested BIND_EXPRs), since we don't build BLOCK nodes when - processing templates. */ - if (processing_template_decl) - { - r = build3 (BIND_EXPR, NULL, NULL, r, NULL); - BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0; - BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0; - TREE_SIDE_EFFECTS (r) = 1; - } - - return r; -} - -/* Finish a compound-statement, which is given by STMT. */ - -void -finish_compound_stmt (tree stmt) -{ - if (TREE_CODE (stmt) == BIND_EXPR) - BIND_EXPR_BODY (stmt) = do_poplevel (BIND_EXPR_BODY (stmt)); - else if (STATEMENT_LIST_NO_SCOPE (stmt)) - stmt = pop_stmt_list (stmt); - else - { - /* Destroy any ObjC "super" receivers that may have been - created. */ - objc_clear_super_receiver (); - - stmt = do_poplevel (stmt); - } - - /* ??? See c_end_compound_stmt wrt statement expressions. */ - add_stmt (stmt); - finish_stmt (); -} - -/* Finish an asm-statement, whose components are a STRING, some - OUTPUT_OPERANDS, some INPUT_OPERANDS, and some CLOBBERS. Also note - whether the asm-statement should be considered volatile. */ - -tree -finish_asm_stmt (int volatile_p, tree string, tree output_operands, - tree input_operands, tree clobbers) -{ - tree r; - tree t; - int ninputs = list_length (input_operands); - int noutputs = list_length (output_operands); - - if (!processing_template_decl) - { - const char *constraint; - const char **oconstraints; - bool allows_mem, allows_reg, is_inout; - tree operand; - int i; - - oconstraints = (const char **) alloca (noutputs * sizeof (char *)); - - string = resolve_asm_operand_names (string, output_operands, - input_operands); - - for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i) - { - operand = TREE_VALUE (t); - - /* ??? Really, this should not be here. Users should be using a - proper lvalue, dammit. But there's a long history of using - casts in the output operands. In cases like longlong.h, this - becomes a primitive form of typechecking -- if the cast can be - removed, then the output operand had a type of the proper width; - otherwise we'll get an error. Gross, but ... */ - STRIP_NOPS (operand); - - if (!lvalue_or_else (operand, lv_asm)) - operand = error_mark_node; - - if (operand != error_mark_node - && (TREE_READONLY (operand) - || CP_TYPE_CONST_P (TREE_TYPE (operand)) - /* Functions are not modifiable, even though they are - lvalues. */ - || TREE_CODE (TREE_TYPE (operand)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (operand)) == METHOD_TYPE - /* If it's an aggregate and any field is const, then it is - effectively const. */ - || (CLASS_TYPE_P (TREE_TYPE (operand)) - && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand))))) - readonly_error (operand, "assignment (via 'asm' output)", 0); - - constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); - oconstraints[i] = constraint; - - if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) - { - /* If the operand is going to end up in memory, - mark it addressable. */ - if (!allows_reg && !cxx_mark_addressable (operand)) - operand = error_mark_node; - } - else - operand = error_mark_node; - - TREE_VALUE (t) = operand; - } - - for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t)) - { - constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); - operand = decay_conversion (TREE_VALUE (t)); - - /* If the type of the operand hasn't been determined (e.g., - because it involves an overloaded function), then issue - an error message. There's no context available to - resolve the overloading. */ - if (TREE_TYPE (operand) == unknown_type_node) - { - error ("type of asm operand %qE could not be determined", - TREE_VALUE (t)); - operand = error_mark_node; - } - - if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - oconstraints, &allows_mem, &allows_reg)) - { - /* If the operand is going to end up in memory, - mark it addressable. */ - if (!allows_reg && allows_mem) - { - /* Strip the nops as we allow this case. FIXME, this really - should be rejected or made deprecated. */ - STRIP_NOPS (operand); - if (!cxx_mark_addressable (operand)) - operand = error_mark_node; - } - } - else - operand = error_mark_node; - - TREE_VALUE (t) = operand; - } - } - - r = build_stmt (ASM_EXPR, string, - output_operands, input_operands, - clobbers); - ASM_VOLATILE_P (r) = volatile_p || noutputs == 0; - r = maybe_cleanup_point_expr_void (r); - return add_stmt (r); -} - -/* Finish a label with the indicated NAME. */ - -tree -finish_label_stmt (tree name) -{ - tree decl = define_label (input_location, name); - - if (decl == error_mark_node) - return error_mark_node; - - return add_stmt (build_stmt (LABEL_EXPR, decl)); -} - -/* Finish a series of declarations for local labels. G++ allows users - to declare "local" labels, i.e., labels with scope. This extension - is useful when writing code involving statement-expressions. */ - -void -finish_label_decl (tree name) -{ - tree decl = declare_local_label (name); - add_decl_expr (decl); -} - -/* When DECL goes out of scope, make sure that CLEANUP is executed. */ - -void -finish_decl_cleanup (tree decl, tree cleanup) -{ - push_cleanup (decl, cleanup, false); -} - -/* If the current scope exits with an exception, run CLEANUP. */ - -void -finish_eh_cleanup (tree cleanup) -{ - push_cleanup (NULL, cleanup, true); -} - -/* The MEM_INITS is a list of mem-initializers, in reverse of the - order they were written by the user. Each node is as for - emit_mem_initializers. */ - -void -finish_mem_initializers (tree mem_inits) -{ - /* Reorder the MEM_INITS so that they are in the order they appeared - in the source program. */ - mem_inits = nreverse (mem_inits); - - if (processing_template_decl) - add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits)); - else - emit_mem_initializers (mem_inits); -} - -/* Finish a parenthesized expression EXPR. */ - -tree -finish_parenthesized_expr (tree expr) -{ - if (EXPR_P (expr)) - /* This inhibits warnings in c_common_truthvalue_conversion. */ - TREE_NO_WARNING (expr) = 1; - - if (TREE_CODE (expr) == OFFSET_REF) - /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be - enclosed in parentheses. */ - PTRMEM_OK_P (expr) = 0; - - if (TREE_CODE (expr) == STRING_CST) - PAREN_STRING_LITERAL_P (expr) = 1; - - return expr; -} - -/* Finish a reference to a non-static data member (DECL) that is not - preceded by `.' or `->'. */ - -tree -finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) -{ - gcc_assert (TREE_CODE (decl) == FIELD_DECL); - - if (!object) - { - if (current_function_decl - && DECL_STATIC_FUNCTION_P (current_function_decl)) - error ("invalid use of member %q+D in static member function", decl); - else - error ("invalid use of non-static data member %q+D", decl); - error ("from this location"); - - return error_mark_node; - } - TREE_USED (current_class_ptr) = 1; - if (processing_template_decl && !qualifying_scope) - { - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - else - { - /* Set the cv qualifiers. */ - int quals = cp_type_quals (TREE_TYPE (current_class_ref)); - - if (DECL_MUTABLE_P (decl)) - quals &= ~TYPE_QUAL_CONST; - - quals |= cp_type_quals (TREE_TYPE (decl)); - type = cp_build_qualified_type (type, quals); - } - - return build_min (COMPONENT_REF, type, object, decl, NULL_TREE); - } - else - { - tree access_type = TREE_TYPE (object); - tree lookup_context = context_for_name_lookup (decl); - - while (!DERIVED_FROM_P (lookup_context, access_type)) - { - access_type = TYPE_CONTEXT (access_type); - while (access_type && DECL_P (access_type)) - access_type = DECL_CONTEXT (access_type); - - if (!access_type) - { - error ("object missing in reference to %q+D", decl); - error ("from this location"); - return error_mark_node; - } - } - - /* If PROCESSING_TEMPLATE_DECL is nonzero here, then - QUALIFYING_SCOPE is also non-null. Wrap this in a SCOPE_REF - for now. */ - if (processing_template_decl) - return build_qualified_name (TREE_TYPE (decl), - qualifying_scope, - DECL_NAME (decl), - /*template_p=*/false); - - perform_or_defer_access_check (TYPE_BINFO (access_type), decl, - decl); - - /* If the data member was named `C::M', convert `*this' to `C' - first. */ - if (qualifying_scope) - { - tree binfo = NULL_TREE; - object = build_scoped_ref (object, qualifying_scope, - &binfo); - } - - return build_class_member_access_expr (object, decl, - /*access_path=*/NULL_TREE, - /*preserve_reference=*/false); - } -} - -/* DECL was the declaration to which a qualified-id resolved. Issue - an error message if it is not accessible. If OBJECT_TYPE is - non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the - type of `*x', or `x', respectively. If the DECL was named as - `A::B' then NESTED_NAME_SPECIFIER is `A'. */ - -void -check_accessibility_of_qualified_id (tree decl, - tree object_type, - tree nested_name_specifier) -{ - tree scope; - tree qualifying_type = NULL_TREE; - - /* If we're not checking, return immediately. */ - if (deferred_access_no_check) - return; - - /* Determine the SCOPE of DECL. */ - scope = context_for_name_lookup (decl); - /* If the SCOPE is not a type, then DECL is not a member. */ - if (!TYPE_P (scope)) - return; - /* Compute the scope through which DECL is being accessed. */ - if (object_type - /* OBJECT_TYPE might not be a class type; consider: - - class A { typedef int I; }; - I *p; - p->A::I::~I(); - - In this case, we will have "A::I" as the DECL, but "I" as the - OBJECT_TYPE. */ - && CLASS_TYPE_P (object_type) - && DERIVED_FROM_P (scope, object_type)) - /* If we are processing a `->' or `.' expression, use the type of the - left-hand side. */ - qualifying_type = object_type; - else if (nested_name_specifier) - { - /* If the reference is to a non-static member of the - current class, treat it as if it were referenced through - `this'. */ - if (DECL_NONSTATIC_MEMBER_P (decl) - && current_class_ptr - && DERIVED_FROM_P (scope, current_class_type)) - qualifying_type = current_class_type; - /* Otherwise, use the type indicated by the - nested-name-specifier. */ - else - qualifying_type = nested_name_specifier; - } - else - /* Otherwise, the name must be from the current class or one of - its bases. */ - qualifying_type = currently_open_derived_class (scope); - - if (qualifying_type - /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM - or similar in a default argument value. */ - && CLASS_TYPE_P (qualifying_type) - && !dependent_type_p (qualifying_type)) - perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl, - decl); -} - -/* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the - class named to the left of the "::" operator. DONE is true if this - expression is a complete postfix-expression; it is false if this - expression is followed by '->', '[', '(', etc. ADDRESS_P is true - iff this expression is the operand of '&'. TEMPLATE_P is true iff - the qualified-id was of the form "A::template B". TEMPLATE_ARG_P - is true iff this qualified name appears as a template argument. */ - -tree -finish_qualified_id_expr (tree qualifying_class, - tree expr, - bool done, - bool address_p, - bool template_p, - bool template_arg_p) -{ - gcc_assert (TYPE_P (qualifying_class)); - - if (error_operand_p (expr)) - return error_mark_node; - - if (DECL_P (expr) || BASELINK_P (expr)) - mark_used (expr); - - if (template_p) - check_template_keyword (expr); - - /* If EXPR occurs as the operand of '&', use special handling that - permits a pointer-to-member. */ - if (address_p && done) - { - if (TREE_CODE (expr) == SCOPE_REF) - expr = TREE_OPERAND (expr, 1); - expr = build_offset_ref (qualifying_class, expr, - /*address_p=*/true); - return expr; - } - - /* Within the scope of a class, turn references to non-static - members into expression of the form "this->...". */ - if (template_arg_p) - /* But, within a template argument, we do not want make the - transformation, as there is no "this" pointer. */ - ; - else if (TREE_CODE (expr) == FIELD_DECL) - expr = finish_non_static_data_member (expr, current_class_ref, - qualifying_class); - else if (BASELINK_P (expr) && !processing_template_decl) - { - tree fns; - - /* See if any of the functions are non-static members. */ - fns = BASELINK_FUNCTIONS (expr); - if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) - fns = TREE_OPERAND (fns, 0); - /* If so, the expression may be relative to the current - class. */ - if (!shared_member_p (fns) - && current_class_type - && DERIVED_FROM_P (qualifying_class, current_class_type)) - expr = (build_class_member_access_expr - (maybe_dummy_object (qualifying_class, NULL), - expr, - BASELINK_ACCESS_BINFO (expr), - /*preserve_reference=*/false)); - else if (done) - /* The expression is a qualified name whose address is not - being taken. */ - expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false); - } - - return expr; -} - -/* Begin a statement-expression. The value returned must be passed to - finish_stmt_expr. */ - -tree -begin_stmt_expr (void) -{ - return push_stmt_list (); -} - -/* Process the final expression of a statement expression. EXPR can be - NULL, if the final expression is empty. Return a STATEMENT_LIST - containing all the statements in the statement-expression, or - ERROR_MARK_NODE if there was an error. */ - -tree -finish_stmt_expr_expr (tree expr, tree stmt_expr) -{ - if (error_operand_p (expr)) - return error_mark_node; - - /* If the last statement does not have "void" type, then the value - of the last statement is the value of the entire expression. */ - if (expr) - { - tree type = TREE_TYPE (expr); - - if (processing_template_decl) - { - expr = build_stmt (EXPR_STMT, expr); - expr = add_stmt (expr); - /* Mark the last statement so that we can recognize it as such at - template-instantiation time. */ - EXPR_STMT_STMT_EXPR_RESULT (expr) = 1; - } - else if (VOID_TYPE_P (type)) - { - /* Just treat this like an ordinary statement. */ - expr = finish_expr_stmt (expr); - } - else - { - /* It actually has a value we need to deal with. First, force it - to be an rvalue so that we won't need to build up a copy - constructor call later when we try to assign it to something. */ - expr = force_rvalue (expr); - if (error_operand_p (expr)) - return error_mark_node; - - /* Update for array-to-pointer decay. */ - type = TREE_TYPE (expr); - - /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a - normal statement, but don't convert to void or actually add - the EXPR_STMT. */ - if (TREE_CODE (expr) != CLEANUP_POINT_EXPR) - expr = maybe_cleanup_point_expr (expr); - add_stmt (expr); - } - - /* The type of the statement-expression is the type of the last - expression. */ - TREE_TYPE (stmt_expr) = type; - } - - return stmt_expr; -} - -/* Finish a statement-expression. EXPR should be the value returned - by the previous begin_stmt_expr. Returns an expression - representing the statement-expression. */ - -tree -finish_stmt_expr (tree stmt_expr, bool has_no_scope) -{ - tree type; - tree result; - - if (error_operand_p (stmt_expr)) - return error_mark_node; - - gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST); - - type = TREE_TYPE (stmt_expr); - result = pop_stmt_list (stmt_expr); - TREE_TYPE (result) = type; - - if (processing_template_decl) - { - result = build_min (STMT_EXPR, type, result); - TREE_SIDE_EFFECTS (result) = 1; - STMT_EXPR_NO_SCOPE (result) = has_no_scope; - } - else if (CLASS_TYPE_P (type)) - { - /* Wrap the statement-expression in a TARGET_EXPR so that the - temporary object created by the final expression is destroyed at - the end of the full-expression containing the - statement-expression. */ - result = force_target_expr (type, result); - } - - return result; -} - -/* Perform Koenig lookup. FN is the postfix-expression representing - the function (or functions) to call; ARGS are the arguments to the - call. Returns the functions to be considered by overload - resolution. */ - -tree -perform_koenig_lookup (tree fn, tree args) -{ - tree identifier = NULL_TREE; - tree functions = NULL_TREE; - - /* Find the name of the overloaded function. */ - if (TREE_CODE (fn) == IDENTIFIER_NODE) - identifier = fn; - else if (is_overloaded_fn (fn)) - { - functions = fn; - identifier = DECL_NAME (get_first_fn (functions)); - } - else if (DECL_P (fn)) - { - functions = fn; - identifier = DECL_NAME (fn); - } - - /* A call to a namespace-scope function using an unqualified name. - - Do Koenig lookup -- unless any of the arguments are - type-dependent. */ - if (!any_type_dependent_arguments_p (args)) - { - fn = lookup_arg_dependent (identifier, functions, args); - if (!fn) - /* The unqualified name could not be resolved. */ - fn = unqualified_fn_lookup_error (identifier); - } - - return fn; -} - -/* Generate an expression for `FN (ARGS)'. - - If DISALLOW_VIRTUAL is true, the call to FN will be not generated - as a virtual call, even if FN is virtual. (This flag is set when - encountering an expression where the function name is explicitly - qualified. For example a call to `X::f' never generates a virtual - call.) - - Returns code for the call. */ - -tree -finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p) -{ - tree result; - tree orig_fn; - tree orig_args; - - if (fn == error_mark_node || args == error_mark_node) - return error_mark_node; - - /* ARGS should be a list of arguments. */ - gcc_assert (!args || TREE_CODE (args) == TREE_LIST); - gcc_assert (!TYPE_P (fn)); - - orig_fn = fn; - orig_args = args; - - if (processing_template_decl) - { - if (type_dependent_expression_p (fn) - || any_type_dependent_arguments_p (args)) - { - result = build_nt (CALL_EXPR, fn, args, NULL_TREE); - KOENIG_LOOKUP_P (result) = koenig_p; - return result; - } - if (!BASELINK_P (fn) - && TREE_CODE (fn) != PSEUDO_DTOR_EXPR - && TREE_TYPE (fn) != unknown_type_node) - fn = build_non_dependent_expr (fn); - args = build_non_dependent_args (orig_args); - } - - if (is_overloaded_fn (fn)) - fn = baselink_for_fns (fn); - - result = NULL_TREE; - if (BASELINK_P (fn)) - { - tree object; - - /* A call to a member function. From [over.call.func]: - - If the keyword this is in scope and refers to the class of - that member function, or a derived class thereof, then the - function call is transformed into a qualified function call - using (*this) as the postfix-expression to the left of the - . operator.... [Otherwise] a contrived object of type T - becomes the implied object argument. - - This paragraph is unclear about this situation: - - struct A { void f(); }; - struct B : public A {}; - struct C : public A { void g() { B::f(); }}; - - In particular, for `B::f', this paragraph does not make clear - whether "the class of that member function" refers to `A' or - to `B'. We believe it refers to `B'. */ - if (current_class_type - && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - current_class_type) - && current_class_ref) - object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - NULL); - else - { - tree representative_fn; - - representative_fn = BASELINK_FUNCTIONS (fn); - if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR) - representative_fn = TREE_OPERAND (representative_fn, 0); - representative_fn = get_first_fn (representative_fn); - object = build_dummy_object (DECL_CONTEXT (representative_fn)); - } - - if (processing_template_decl) - { - if (type_dependent_expression_p (object)) - return build_nt (CALL_EXPR, orig_fn, orig_args, NULL_TREE); - object = build_non_dependent_expr (object); - } - - result = build_new_method_call (object, fn, args, NULL_TREE, - (disallow_virtual - ? LOOKUP_NONVIRTUAL : 0), - /*fn_p=*/NULL); - } - else if (is_overloaded_fn (fn)) - { - /* If the function is an overloaded builtin, resolve it. */ - if (TREE_CODE (fn) == FUNCTION_DECL - && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL - || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD)) - result = resolve_overloaded_builtin (fn, args); - - if (!result) - /* A call to a namespace-scope function. */ - result = build_new_function_call (fn, args, koenig_p); - } - else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) - { - if (args) - error ("arguments to destructor are not allowed"); - /* Mark the pseudo-destructor call as having side-effects so - that we do not issue warnings about its use. */ - result = build1 (NOP_EXPR, - void_type_node, - TREE_OPERAND (fn, 0)); - TREE_SIDE_EFFECTS (result) = 1; - } - else if (CLASS_TYPE_P (TREE_TYPE (fn))) - /* If the "function" is really an object of class type, it might - have an overloaded `operator ()'. */ - result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE, - /*overloaded_p=*/NULL); - - if (!result) - /* A call where the function is unknown. */ - result = build_function_call (fn, args); - - if (processing_template_decl) - { - result = build3 (CALL_EXPR, TREE_TYPE (result), orig_fn, - orig_args, NULL_TREE); - KOENIG_LOOKUP_P (result) = koenig_p; - } - return result; -} - -/* Finish a call to a postfix increment or decrement or EXPR. (Which - is indicated by CODE, which should be POSTINCREMENT_EXPR or - POSTDECREMENT_EXPR.) */ - -tree -finish_increment_expr (tree expr, enum tree_code code) -{ - return build_x_unary_op (code, expr); -} - -/* Finish a use of `this'. Returns an expression for `this'. */ - -tree -finish_this_expr (void) -{ - tree result; - - if (current_class_ptr) - { - result = current_class_ptr; - } - else if (current_function_decl - && DECL_STATIC_FUNCTION_P (current_function_decl)) - { - error ("%<this%> is unavailable for static member functions"); - result = error_mark_node; - } - else - { - if (current_function_decl) - error ("invalid use of %<this%> in non-member function"); - else - error ("invalid use of %<this%> at top level"); - result = error_mark_node; - } - - return result; -} - -/* Finish a pseudo-destructor expression. If SCOPE is NULL, the - expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is - the TYPE for the type given. If SCOPE is non-NULL, the expression - was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */ - -tree -finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) -{ - if (destructor == error_mark_node) - return error_mark_node; - - gcc_assert (TYPE_P (destructor)); - - if (!processing_template_decl) - { - if (scope == error_mark_node) - { - error ("invalid qualifying scope in pseudo-destructor name"); - return error_mark_node; - } - if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor)) - { - error ("qualified type %qT does not match destructor name ~%qT", - scope, destructor); - return error_mark_node; - } - - - /* [expr.pseudo] says both: - - The type designated by the pseudo-destructor-name shall be - the same as the object type. - - and: - - The cv-unqualified versions of the object type and of the - type designated by the pseudo-destructor-name shall be the - same type. - - We implement the more generous second sentence, since that is - what most other compilers do. */ - if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object), - destructor)) - { - error ("%qE is not of type %qT", object, destructor); - return error_mark_node; - } - } - - return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor); -} - -/* Finish an expression of the form CODE EXPR. */ - -tree -finish_unary_op_expr (enum tree_code code, tree expr) -{ - tree result = build_x_unary_op (code, expr); - /* Inside a template, build_x_unary_op does not fold the - expression. So check whether the result is folded before - setting TREE_NEGATED_INT. */ - if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST - && TREE_CODE (result) == INTEGER_CST - && !TYPE_UNSIGNED (TREE_TYPE (result)) - && INT_CST_LT (result, integer_zero_node)) - { - /* RESULT may be a cached INTEGER_CST, so we must copy it before - setting TREE_NEGATED_INT. */ - result = copy_node (result); - TREE_NEGATED_INT (result) = 1; - } - overflow_warning (result); - return result; -} - -/* Finish a compound-literal expression. TYPE is the type to which - the INITIALIZER_LIST is being cast. */ - -tree -finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list) -{ - tree var; - tree compound_literal; - - if (!TYPE_OBJ_P (type)) - { - error ("compound literal of non-object type %qT", type); - return error_mark_node; - } - - /* Build a CONSTRUCTOR for the INITIALIZER_LIST. */ - compound_literal = build_constructor (NULL_TREE, initializer_list); - if (processing_template_decl) - { - TREE_TYPE (compound_literal) = type; - /* Mark the expression as a compound literal. */ - TREE_HAS_CONSTRUCTOR (compound_literal) = 1; - return compound_literal; - } - - /* Create a temporary variable to represent the compound literal. */ - var = create_temporary_var (type); - if (!current_function_decl) - { - /* If this compound-literal appears outside of a function, then - the corresponding variable has static storage duration, just - like the variable in whose initializer it appears. */ - TREE_STATIC (var) = 1; - /* The variable has internal linkage, since there is no need to - reference it from another translation unit. */ - TREE_PUBLIC (var) = 0; - /* It must have a name, so that the name mangler can mangle it. */ - DECL_NAME (var) = make_anon_name (); - } - /* We must call pushdecl, since the gimplifier complains if the - variable has not been declared via a BIND_EXPR. */ - pushdecl (var); - /* Initialize the variable as we would any other variable with a - brace-enclosed initializer. */ - cp_finish_decl (var, compound_literal, - /*init_const_expr_p=*/false, - /*asmspec_tree=*/NULL_TREE, - LOOKUP_ONLYCONVERTING); - return var; -} - -/* Return the declaration for the function-name variable indicated by - ID. */ - -tree -finish_fname (tree id) -{ - tree decl; - - decl = fname_decl (C_RID_CODE (id), id); - if (processing_template_decl) - decl = DECL_NAME (decl); - return decl; -} - -/* Finish a translation unit. */ - -void -finish_translation_unit (void) -{ - /* In case there were missing closebraces, - get us back to the global binding level. */ - pop_everything (); - while (current_namespace != global_namespace) - pop_namespace (); - - /* Do file scope __FUNCTION__ et al. */ - finish_fname_decls (); -} - -/* Finish a template type parameter, specified as AGGR IDENTIFIER. - Returns the parameter. */ - -tree -finish_template_type_parm (tree aggr, tree identifier) -{ - if (aggr != class_type_node) - { - pedwarn ("template type parameters must use the keyword %<class%> or %<typename%>"); - aggr = class_type_node; - } - - return build_tree_list (aggr, identifier); -} - -/* Finish a template template parameter, specified as AGGR IDENTIFIER. - Returns the parameter. */ - -tree -finish_template_template_parm (tree aggr, tree identifier) -{ - tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE); - tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE); - DECL_TEMPLATE_PARMS (tmpl) = current_template_parms; - DECL_TEMPLATE_RESULT (tmpl) = decl; - DECL_ARTIFICIAL (decl) = 1; - end_template_decl (); - - gcc_assert (DECL_TEMPLATE_PARMS (tmpl)); - - return finish_template_type_parm (aggr, tmpl); -} - -/* ARGUMENT is the default-argument value for a template template - parameter. If ARGUMENT is invalid, issue error messages and return - the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */ - -tree -check_template_template_default_arg (tree argument) -{ - if (TREE_CODE (argument) != TEMPLATE_DECL - && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM - && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE) - { - if (TREE_CODE (argument) == TYPE_DECL) - error ("invalid use of type %qT as a default value for a template " - "template-parameter", TREE_TYPE (argument)); - else - error ("invalid default argument for a template template parameter"); - return error_mark_node; - } - - return argument; -} - -/* Begin a class definition, as indicated by T. */ - -tree -begin_class_definition (tree t, tree attributes) -{ - if (t == error_mark_node) - return error_mark_node; - - if (processing_template_parmlist) - { - error ("definition of %q#T inside template parameter list", t); - return error_mark_node; - } - /* A non-implicit typename comes from code like: - - template <typename T> struct A { - template <typename U> struct A<T>::B ... - - This is erroneous. */ - else if (TREE_CODE (t) == TYPENAME_TYPE) - { - error ("invalid definition of qualified type %qT", t); - t = error_mark_node; - } - - if (t == error_mark_node || ! IS_AGGR_TYPE (t)) - { - t = make_aggr_type (RECORD_TYPE); - pushtag (make_anon_name (), t, /*tag_scope=*/ts_current); - } - - /* Update the location of the decl. */ - DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location; - - if (TYPE_BEING_DEFINED (t)) - { - t = make_aggr_type (TREE_CODE (t)); - pushtag (TYPE_IDENTIFIER (t), t, /*tag_scope=*/ts_current); - } - maybe_process_partial_specialization (t); - pushclass (t); - TYPE_BEING_DEFINED (t) = 1; - - cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); - - if (flag_pack_struct) - { - tree v; - TYPE_PACKED (t) = 1; - /* Even though the type is being defined for the first time - here, there might have been a forward declaration, so there - might be cv-qualified variants of T. */ - for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v)) - TYPE_PACKED (v) = 1; - } - /* Reset the interface data, at the earliest possible - moment, as it might have been set via a class foo; - before. */ - if (! TYPE_ANONYMOUS_P (t)) - { - struct c_fileinfo *finfo = get_fileinfo (input_filename); - CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X - (t, finfo->interface_unknown); - } - reset_specialization(); - - /* Make a declaration for this class in its own scope. */ - build_self_reference (); - - return t; -} - -/* Finish the member declaration given by DECL. */ - -void -finish_member_declaration (tree decl) -{ - if (decl == error_mark_node || decl == NULL_TREE) - return; - - if (decl == void_type_node) - /* The COMPONENT was a friend, not a member, and so there's - nothing for us to do. */ - return; - - /* We should see only one DECL at a time. */ - gcc_assert (TREE_CHAIN (decl) == NULL_TREE); - - /* Set up access control for DECL. */ - TREE_PRIVATE (decl) - = (current_access_specifier == access_private_node); - TREE_PROTECTED (decl) - = (current_access_specifier == access_protected_node); - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl); - TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl); - } - - /* Mark the DECL as a member of the current class. */ - DECL_CONTEXT (decl) = current_class_type; - - /* [dcl.link] - - A C language linkage is ignored for the names of class members - and the member function type of class member functions. */ - if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c) - SET_DECL_LANGUAGE (decl, lang_cplusplus); - - /* Put functions on the TYPE_METHODS list and everything else on the - TYPE_FIELDS list. Note that these are built up in reverse order. - We reverse them (to obtain declaration order) in finish_struct. */ - if (TREE_CODE (decl) == FUNCTION_DECL - || DECL_FUNCTION_TEMPLATE_P (decl)) - { - /* We also need to add this function to the - CLASSTYPE_METHOD_VEC. */ - if (add_method (current_class_type, decl, NULL_TREE)) - { - TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); - TYPE_METHODS (current_class_type) = decl; - - maybe_add_class_template_decl_list (current_class_type, decl, - /*friend_p=*/0); - } - } - /* Enter the DECL into the scope of the class. */ - else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl)) - || pushdecl_class_level (decl)) - { - /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields - go at the beginning. The reason is that lookup_field_1 - searches the list in order, and we want a field name to - override a type name so that the "struct stat hack" will - work. In particular: - - struct S { enum E { }; int E } s; - s.E = 3; - - is valid. In addition, the FIELD_DECLs must be maintained in - declaration order so that class layout works as expected. - However, we don't need that order until class layout, so we - save a little time by putting FIELD_DECLs on in reverse order - here, and then reversing them in finish_struct_1. (We could - also keep a pointer to the correct insertion points in the - list.) */ - - if (TREE_CODE (decl) == TYPE_DECL) - TYPE_FIELDS (current_class_type) - = chainon (TYPE_FIELDS (current_class_type), decl); - else - { - TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type); - TYPE_FIELDS (current_class_type) = decl; - } - - maybe_add_class_template_decl_list (current_class_type, decl, - /*friend_p=*/0); - } - - if (pch_file) - note_decl_for_pch (decl); -} - -/* DECL has been declared while we are building a PCH file. Perform - actions that we might normally undertake lazily, but which can be - performed now so that they do not have to be performed in - translation units which include the PCH file. */ - -void -note_decl_for_pch (tree decl) -{ - gcc_assert (pch_file); - - /* There's a good chance that we'll have to mangle names at some - point, even if only for emission in debugging information. */ - if ((TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == FUNCTION_DECL) - && !processing_template_decl) - mangle_decl (decl); -} - -/* Finish processing a complete template declaration. The PARMS are - the template parameters. */ - -void -finish_template_decl (tree parms) -{ - if (parms) - end_template_decl (); - else - end_specialization (); -} - -/* Finish processing a template-id (which names a type) of the form - NAME < ARGS >. Return the TYPE_DECL for the type named by the - template-id. If ENTERING_SCOPE is nonzero we are about to enter - the scope of template-id indicated. */ - -tree -finish_template_type (tree name, tree args, int entering_scope) -{ - tree decl; - - decl = lookup_template_class (name, args, - NULL_TREE, NULL_TREE, entering_scope, - tf_warning_or_error | tf_user); - if (decl != error_mark_node) - decl = TYPE_STUB_DECL (decl); - - return decl; -} - -/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER. - Return a TREE_LIST containing the ACCESS_SPECIFIER and the - BASE_CLASS, or NULL_TREE if an error occurred. The - ACCESS_SPECIFIER is one of - access_{default,public,protected_private}_node. For a virtual base - we set TREE_TYPE. */ - -tree -finish_base_specifier (tree base, tree access, bool virtual_p) -{ - tree result; - - if (base == error_mark_node) - { - error ("invalid base-class specification"); - result = NULL_TREE; - } - else if (! is_aggr_type (base, 1)) - result = NULL_TREE; - else - { - if (cp_type_quals (base) != 0) - { - error ("base class %qT has cv qualifiers", base); - base = TYPE_MAIN_VARIANT (base); - } - result = build_tree_list (access, base); - if (virtual_p) - TREE_TYPE (result) = integer_type_node; - } - - return result; -} - -/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is - what we found when we tried to do the lookup. */ - -void -qualified_name_lookup_error (tree scope, tree name, tree decl) -{ - if (scope == error_mark_node) - ; /* We already complained. */ - else if (TYPE_P (scope)) - { - if (!COMPLETE_TYPE_P (scope)) - error ("incomplete type %qT used in nested name specifier", scope); - else if (TREE_CODE (decl) == TREE_LIST) - { - error ("reference to %<%T::%D%> is ambiguous", scope, name); - print_candidates (decl); - } - else - error ("%qD is not a member of %qT", name, scope); - } - else if (scope != global_namespace) - error ("%qD is not a member of %qD", name, scope); - else - error ("%<::%D%> has not been declared", name); -} - -/* If FNS is a member function, a set of member functions, or a - template-id referring to one or more member functions, return a - BASELINK for FNS, incorporating the current access context. - Otherwise, return FNS unchanged. */ - -tree -baselink_for_fns (tree fns) -{ - tree fn; - tree cl; - - if (BASELINK_P (fns) - || error_operand_p (fns)) - return fns; - - fn = fns; - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - fn = TREE_OPERAND (fn, 0); - fn = get_first_fn (fn); - if (!DECL_FUNCTION_MEMBER_P (fn)) - return fns; - - cl = currently_open_derived_class (DECL_CONTEXT (fn)); - if (!cl) - cl = DECL_CONTEXT (fn); - cl = TYPE_BINFO (cl); - return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE); -} - -/* ID_EXPRESSION is a representation of parsed, but unprocessed, - id-expression. (See cp_parser_id_expression for details.) SCOPE, - if non-NULL, is the type or namespace used to explicitly qualify - ID_EXPRESSION. DECL is the entity to which that name has been - resolved. - - *CONSTANT_EXPRESSION_P is true if we are presently parsing a - constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will - be set to true if this expression isn't permitted in a - constant-expression, but it is otherwise not set by this function. - *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a - constant-expression, but a non-constant expression is also - permissible. - - DONE is true if this expression is a complete postfix-expression; - it is false if this expression is followed by '->', '[', '(', etc. - ADDRESS_P is true iff this expression is the operand of '&'. - TEMPLATE_P is true iff the qualified-id was of the form - "A::template B". TEMPLATE_ARG_P is true iff this qualified name - appears as a template argument. - - If an error occurs, and it is the kind of error that might cause - the parser to abort a tentative parse, *ERROR_MSG is filled in. It - is the caller's responsibility to issue the message. *ERROR_MSG - will be a string with static storage duration, so the caller need - not "free" it. - - Return an expression for the entity, after issuing appropriate - diagnostics. This function is also responsible for transforming a - reference to a non-static member into a COMPONENT_REF that makes - the use of "this" explicit. - - Upon return, *IDK will be filled in appropriately. */ - -tree -finish_id_expression (tree id_expression, - tree decl, - tree scope, - cp_id_kind *idk, - bool integral_constant_expression_p, - bool allow_non_integral_constant_expression_p, - bool *non_integral_constant_expression_p, - bool template_p, - bool done, - bool address_p, - bool template_arg_p, - const char **error_msg) -{ - /* Initialize the output parameters. */ - *idk = CP_ID_KIND_NONE; - *error_msg = NULL; - - if (id_expression == error_mark_node) - return error_mark_node; - /* If we have a template-id, then no further lookup is - required. If the template-id was for a template-class, we - will sometimes have a TYPE_DECL at this point. */ - else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR - || TREE_CODE (decl) == TYPE_DECL) - ; - /* Look up the name. */ - else - { - if (decl == error_mark_node) - { - /* Name lookup failed. */ - if (scope - && (!TYPE_P (scope) - || (!dependent_type_p (scope) - && !(TREE_CODE (id_expression) == IDENTIFIER_NODE - && IDENTIFIER_TYPENAME_P (id_expression) - && dependent_type_p (TREE_TYPE (id_expression)))))) - { - /* If the qualifying type is non-dependent (and the name - does not name a conversion operator to a dependent - type), issue an error. */ - qualified_name_lookup_error (scope, id_expression, decl); - return error_mark_node; - } - else if (!scope) - { - /* It may be resolved via Koenig lookup. */ - *idk = CP_ID_KIND_UNQUALIFIED; - return id_expression; - } - else - decl = id_expression; - } - /* If DECL is a variable that would be out of scope under - ANSI/ISO rules, but in scope in the ARM, name lookup - will succeed. Issue a diagnostic here. */ - else - decl = check_for_out_of_scope_variable (decl); - - /* Remember that the name was used in the definition of - the current class so that we can check later to see if - the meaning would have been different after the class - was entirely defined. */ - if (!scope && decl != error_mark_node) - maybe_note_name_used_in_class (id_expression, decl); - - /* Disallow uses of local variables from containing functions. */ - if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) - { - tree context = decl_function_context (decl); - if (context != NULL_TREE && context != current_function_decl - && ! TREE_STATIC (decl)) - { - error (TREE_CODE (decl) == VAR_DECL - ? "use of %<auto%> variable from containing function" - : "use of parameter from containing function"); - error (" %q+#D declared here", decl); - return error_mark_node; - } - } - } - - /* If we didn't find anything, or what we found was a type, - then this wasn't really an id-expression. */ - if (TREE_CODE (decl) == TEMPLATE_DECL - && !DECL_FUNCTION_TEMPLATE_P (decl)) - { - *error_msg = "missing template arguments"; - return error_mark_node; - } - else if (TREE_CODE (decl) == TYPE_DECL - || TREE_CODE (decl) == NAMESPACE_DECL) - { - *error_msg = "expected primary-expression"; - return error_mark_node; - } - - /* If the name resolved to a template parameter, there is no - need to look it up again later. */ - if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl)) - || TREE_CODE (decl) == TEMPLATE_PARM_INDEX) - { - tree r; - - *idk = CP_ID_KIND_NONE; - if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX) - decl = TEMPLATE_PARM_DECL (decl); - r = convert_from_reference (DECL_INITIAL (decl)); - - if (integral_constant_expression_p - && !dependent_type_p (TREE_TYPE (decl)) - && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r)))) - { - if (!allow_non_integral_constant_expression_p) - error ("template parameter %qD of type %qT is not allowed in " - "an integral constant expression because it is not of " - "integral or enumeration type", decl, TREE_TYPE (decl)); - *non_integral_constant_expression_p = true; - } - return r; - } - /* Similarly, we resolve enumeration constants to their - underlying values. */ - else if (TREE_CODE (decl) == CONST_DECL) - { - *idk = CP_ID_KIND_NONE; - if (!processing_template_decl) - { - used_types_insert (TREE_TYPE (decl)); - return DECL_INITIAL (decl); - } - return decl; - } - else - { - bool dependent_p; - - /* If the declaration was explicitly qualified indicate - that. The semantics of `A::f(3)' are different than - `f(3)' if `f' is virtual. */ - *idk = (scope - ? CP_ID_KIND_QUALIFIED - : (TREE_CODE (decl) == TEMPLATE_ID_EXPR - ? CP_ID_KIND_TEMPLATE_ID - : CP_ID_KIND_UNQUALIFIED)); - - - /* [temp.dep.expr] - - An id-expression is type-dependent if it contains an - identifier that was declared with a dependent type. - - The standard is not very specific about an id-expression that - names a set of overloaded functions. What if some of them - have dependent types and some of them do not? Presumably, - such a name should be treated as a dependent name. */ - /* Assume the name is not dependent. */ - dependent_p = false; - if (!processing_template_decl) - /* No names are dependent outside a template. */ - ; - /* A template-id where the name of the template was not resolved - is definitely dependent. */ - else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR - && (TREE_CODE (TREE_OPERAND (decl, 0)) - == IDENTIFIER_NODE)) - dependent_p = true; - /* For anything except an overloaded function, just check its - type. */ - else if (!is_overloaded_fn (decl)) - dependent_p - = dependent_type_p (TREE_TYPE (decl)); - /* For a set of overloaded functions, check each of the - functions. */ - else - { - tree fns = decl; - - if (BASELINK_P (fns)) - fns = BASELINK_FUNCTIONS (fns); - - /* For a template-id, check to see if the template - arguments are dependent. */ - if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) - { - tree args = TREE_OPERAND (fns, 1); - dependent_p = any_dependent_template_arguments_p (args); - /* The functions are those referred to by the - template-id. */ - fns = TREE_OPERAND (fns, 0); - } - - /* If there are no dependent template arguments, go through - the overloaded functions. */ - while (fns && !dependent_p) - { - tree fn = OVL_CURRENT (fns); - - /* Member functions of dependent classes are - dependent. */ - if (TREE_CODE (fn) == FUNCTION_DECL - && type_dependent_expression_p (fn)) - dependent_p = true; - else if (TREE_CODE (fn) == TEMPLATE_DECL - && dependent_template_p (fn)) - dependent_p = true; - - fns = OVL_NEXT (fns); - } - } - - /* If the name was dependent on a template parameter, we will - resolve the name at instantiation time. */ - if (dependent_p) - { - /* Create a SCOPE_REF for qualified names, if the scope is - dependent. */ - if (scope) - { - /* Since this name was dependent, the expression isn't - constant -- yet. No error is issued because it might - be constant when things are instantiated. */ - if (integral_constant_expression_p) - *non_integral_constant_expression_p = true; - if (TYPE_P (scope)) - { - if (address_p && done) - decl = finish_qualified_id_expr (scope, decl, - done, address_p, - template_p, - template_arg_p); - else if (dependent_type_p (scope)) - decl = build_qualified_name (/*type=*/NULL_TREE, - scope, - id_expression, - template_p); - else if (DECL_P (decl)) - decl = build_qualified_name (TREE_TYPE (decl), - scope, - id_expression, - template_p); - } - if (TREE_TYPE (decl)) - decl = convert_from_reference (decl); - return decl; - } - /* A TEMPLATE_ID already contains all the information we - need. */ - if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR) - return id_expression; - *idk = CP_ID_KIND_UNQUALIFIED_DEPENDENT; - /* If we found a variable, then name lookup during the - instantiation will always resolve to the same VAR_DECL - (or an instantiation thereof). */ - if (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == PARM_DECL) - return convert_from_reference (decl); - /* The same is true for FIELD_DECL, but we also need to - make sure that the syntax is correct. */ - else if (TREE_CODE (decl) == FIELD_DECL) - { - /* Since SCOPE is NULL here, this is an unqualified name. - Access checking has been performed during name lookup - already. Turn off checking to avoid duplicate errors. */ - push_deferring_access_checks (dk_no_check); - decl = finish_non_static_data_member - (decl, current_class_ref, - /*qualifying_scope=*/NULL_TREE); - pop_deferring_access_checks (); - return decl; - } - return id_expression; - } - - /* Only certain kinds of names are allowed in constant - expression. Enumerators and template parameters have already - been handled above. */ - if (integral_constant_expression_p - && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl) - && ! builtin_valid_in_constant_expr_p (decl)) - { - if (!allow_non_integral_constant_expression_p) - { - error ("%qD cannot appear in a constant-expression", decl); - return error_mark_node; - } - *non_integral_constant_expression_p = true; - } - - if (TREE_CODE (decl) == NAMESPACE_DECL) - { - error ("use of namespace %qD as expression", decl); - return error_mark_node; - } - else if (DECL_CLASS_TEMPLATE_P (decl)) - { - error ("use of class template %qT as expression", decl); - return error_mark_node; - } - else if (TREE_CODE (decl) == TREE_LIST) - { - /* Ambiguous reference to base members. */ - error ("request for member %qD is ambiguous in " - "multiple inheritance lattice", id_expression); - print_candidates (decl); - return error_mark_node; - } - - /* Mark variable-like entities as used. Functions are similarly - marked either below or after overload resolution. */ - if (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == RESULT_DECL) - mark_used (decl); - - if (scope) - { - decl = (adjust_result_of_qualified_name_lookup - (decl, scope, current_class_type)); - - if (TREE_CODE (decl) == FUNCTION_DECL) - mark_used (decl); - - if (TREE_CODE (decl) == FIELD_DECL || BASELINK_P (decl)) - decl = finish_qualified_id_expr (scope, - decl, - done, - address_p, - template_p, - template_arg_p); - else - { - tree r = convert_from_reference (decl); - - if (processing_template_decl && TYPE_P (scope)) - r = build_qualified_name (TREE_TYPE (r), - scope, decl, - template_p); - decl = r; - } - } - else if (TREE_CODE (decl) == FIELD_DECL) - { - /* Since SCOPE is NULL here, this is an unqualified name. - Access checking has been performed during name lookup - already. Turn off checking to avoid duplicate errors. */ - push_deferring_access_checks (dk_no_check); - decl = finish_non_static_data_member (decl, current_class_ref, - /*qualifying_scope=*/NULL_TREE); - pop_deferring_access_checks (); - } - else if (is_overloaded_fn (decl)) - { - tree first_fn; - - first_fn = decl; - if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR) - first_fn = TREE_OPERAND (first_fn, 0); - first_fn = get_first_fn (first_fn); - if (TREE_CODE (first_fn) == TEMPLATE_DECL) - first_fn = DECL_TEMPLATE_RESULT (first_fn); - - if (!really_overloaded_fn (decl)) - mark_used (first_fn); - - if (!template_arg_p - && TREE_CODE (first_fn) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (first_fn) - && !shared_member_p (decl)) - { - /* A set of member functions. */ - decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0); - return finish_class_member_access_expr (decl, id_expression, - /*template_p=*/false); - } - - decl = baselink_for_fns (decl); - } - else - { - if (DECL_P (decl) && DECL_NONLOCAL (decl) - && DECL_CLASS_SCOPE_P (decl) - && DECL_CONTEXT (decl) != current_class_type) - { - tree path; - - path = currently_open_derived_class (DECL_CONTEXT (decl)); - perform_or_defer_access_check (TYPE_BINFO (path), decl, decl); - } - - decl = convert_from_reference (decl); - } - } - - if (TREE_DEPRECATED (decl)) - warn_deprecated_use (decl); - - return decl; -} - -/* Implement the __typeof keyword: Return the type of EXPR, suitable for - use as a type-specifier. */ - -tree -finish_typeof (tree expr) -{ - tree type; - - if (type_dependent_expression_p (expr)) - { - type = make_aggr_type (TYPEOF_TYPE); - TYPEOF_TYPE_EXPR (type) = expr; - - return type; - } - - type = unlowered_expr_type (expr); - - if (!type || type == unknown_type_node) - { - error ("type of %qE is unknown", expr); - return error_mark_node; - } - - return type; -} - -/* Perform C++-specific checks for __builtin_offsetof before calling - fold_offsetof. */ - -tree -finish_offsetof (tree expr) -{ - if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) - { - error ("cannot apply %<offsetof%> to destructor %<~%T%>", - TREE_OPERAND (expr, 2)); - return error_mark_node; - } - if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE - || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE) - { - if (TREE_CODE (expr) == COMPONENT_REF - || TREE_CODE (expr) == COMPOUND_EXPR) - expr = TREE_OPERAND (expr, 1); - error ("cannot apply %<offsetof%> to member function %qD", expr); - return error_mark_node; - } - return fold_offsetof (expr, NULL_TREE); -} - -/* Called from expand_body via walk_tree. Replace all AGGR_INIT_EXPRs - with equivalent CALL_EXPRs. */ - -static tree -simplify_aggr_init_exprs_r (tree* tp, - int* walk_subtrees, - void* data ATTRIBUTE_UNUSED) -{ - /* We don't need to walk into types; there's nothing in a type that - needs simplification. (And, furthermore, there are places we - actively don't want to go. For example, we don't want to wander - into the default arguments for a FUNCTION_DECL that appears in a - CALL_EXPR.) */ - if (TYPE_P (*tp)) - { - *walk_subtrees = 0; - return NULL_TREE; - } - /* Only AGGR_INIT_EXPRs are interesting. */ - else if (TREE_CODE (*tp) != AGGR_INIT_EXPR) - return NULL_TREE; - - simplify_aggr_init_expr (tp); - - /* Keep iterating. */ - return NULL_TREE; -} - -/* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This - function is broken out from the above for the benefit of the tree-ssa - project. */ - -void -simplify_aggr_init_expr (tree *tp) -{ - tree aggr_init_expr = *tp; - - /* Form an appropriate CALL_EXPR. */ - tree fn = TREE_OPERAND (aggr_init_expr, 0); - tree args = TREE_OPERAND (aggr_init_expr, 1); - tree slot = TREE_OPERAND (aggr_init_expr, 2); - tree type = TREE_TYPE (slot); - - tree call_expr; - enum style_t { ctor, arg, pcc } style; - - if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr)) - style = ctor; -#ifdef PCC_STATIC_STRUCT_RETURN - else if (1) - style = pcc; -#endif - else - { - gcc_assert (TREE_ADDRESSABLE (type)); - style = arg; - } - - if (style == ctor) - { - /* Replace the first argument to the ctor with the address of the - slot. */ - tree addr; - - args = TREE_CHAIN (args); - cxx_mark_addressable (slot); - addr = build1 (ADDR_EXPR, build_pointer_type (type), slot); - args = tree_cons (NULL_TREE, addr, args); - } - - call_expr = build3 (CALL_EXPR, - TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), - fn, args, NULL_TREE); - - if (style == arg) - { - /* Just mark it addressable here, and leave the rest to - expand_call{,_inline}. */ - cxx_mark_addressable (slot); - CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true; - call_expr = build2 (MODIFY_EXPR, TREE_TYPE (call_expr), slot, call_expr); - } - else if (style == pcc) - { - /* If we're using the non-reentrant PCC calling convention, then we - need to copy the returned value out of the static buffer into the - SLOT. */ - push_deferring_access_checks (dk_no_check); - call_expr = build_aggr_init (slot, call_expr, - DIRECT_BIND | LOOKUP_ONLYCONVERTING); - pop_deferring_access_checks (); - call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot); - } - - *tp = call_expr; -} - -/* Emit all thunks to FN that should be emitted when FN is emitted. */ - -static void -emit_associated_thunks (tree fn) -{ - /* When we use vcall offsets, we emit thunks with the virtual - functions to which they thunk. The whole point of vcall offsets - is so that you can know statically the entire set of thunks that - will ever be needed for a given virtual function, thereby - enabling you to output all the thunks with the function itself. */ - if (DECL_VIRTUAL_P (fn)) - { - tree thunk; - - for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk)) - { - if (!THUNK_ALIAS (thunk)) - { - use_thunk (thunk, /*emit_p=*/1); - if (DECL_RESULT_THUNK_P (thunk)) - { - tree probe; - - for (probe = DECL_THUNKS (thunk); - probe; probe = TREE_CHAIN (probe)) - use_thunk (probe, /*emit_p=*/1); - } - } - else - gcc_assert (!DECL_THUNKS (thunk)); - } - } -} - -/* Generate RTL for FN. */ - -void -expand_body (tree fn) -{ - tree saved_function; - - /* Compute the appropriate object-file linkage for inline - functions. */ - if (DECL_DECLARED_INLINE_P (fn)) - import_export_decl (fn); - - /* If FN is external, then there's no point in generating RTL for - it. This situation can arise with an inline function under - `-fexternal-templates'; we instantiate the function, even though - we're not planning on emitting it, in case we get a chance to - inline it. */ - if (DECL_EXTERNAL (fn)) - return; - - /* ??? When is this needed? */ - saved_function = current_function_decl; - - /* Emit any thunks that should be emitted at the same time as FN. */ - emit_associated_thunks (fn); - - /* This function is only called from cgraph, or recursively from - emit_associated_thunks. In neither case should we be currently - generating trees for a function. */ - gcc_assert (function_depth == 0); - - tree_rest_of_compilation (fn); - - current_function_decl = saved_function; - - if (DECL_CLONED_FUNCTION_P (fn)) - { - /* If this is a clone, go through the other clones now and mark - their parameters used. We have to do that here, as we don't - know whether any particular clone will be expanded, and - therefore cannot pick one arbitrarily. */ - tree probe; - - for (probe = TREE_CHAIN (DECL_CLONED_FUNCTION (fn)); - probe && DECL_CLONED_FUNCTION_P (probe); - probe = TREE_CHAIN (probe)) - { - tree parms; - - for (parms = DECL_ARGUMENTS (probe); - parms; parms = TREE_CHAIN (parms)) - TREE_USED (parms) = 1; - } - } -} - -/* Generate RTL for FN. */ - -void -expand_or_defer_fn (tree fn) -{ - /* When the parser calls us after finishing the body of a template - function, we don't really want to expand the body. */ - if (processing_template_decl) - { - /* Normally, collection only occurs in rest_of_compilation. So, - if we don't collect here, we never collect junk generated - during the processing of templates until we hit a - non-template function. It's not safe to do this inside a - nested class, though, as the parser may have local state that - is not a GC root. */ - if (!function_depth) - ggc_collect (); - return; - } - - /* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */ - walk_tree_without_duplicates (&DECL_SAVED_TREE (fn), - simplify_aggr_init_exprs_r, - NULL); - - /* If this is a constructor or destructor body, we have to clone - it. */ - if (maybe_clone_body (fn)) - { - /* We don't want to process FN again, so pretend we've written - it out, even though we haven't. */ - TREE_ASM_WRITTEN (fn) = 1; - return; - } - - /* If this function is marked with the constructor attribute, add it - to the list of functions to be called along with constructors - from static duration objects. */ - if (DECL_STATIC_CONSTRUCTOR (fn)) - static_ctors = tree_cons (NULL_TREE, fn, static_ctors); - - /* If this function is marked with the destructor attribute, add it - to the list of functions to be called along with destructors from - static duration objects. */ - if (DECL_STATIC_DESTRUCTOR (fn)) - static_dtors = tree_cons (NULL_TREE, fn, static_dtors); - - /* We make a decision about linkage for these functions at the end - of the compilation. Until that point, we do not want the back - end to output them -- but we do want it to see the bodies of - these functions so that it can inline them as appropriate. */ - if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn)) - { - if (DECL_INTERFACE_KNOWN (fn)) - /* We've already made a decision as to how this function will - be handled. */; - else if (!at_eof) - { - DECL_EXTERNAL (fn) = 1; - DECL_NOT_REALLY_EXTERN (fn) = 1; - note_vague_linkage_fn (fn); - /* A non-template inline function with external linkage will - always be COMDAT. As we must eventually determine the - linkage of all functions, and as that causes writes to - the data mapped in from the PCH file, it's advantageous - to mark the functions at this point. */ - if (!DECL_IMPLICIT_INSTANTIATION (fn)) - { - /* This function must have external linkage, as - otherwise DECL_INTERFACE_KNOWN would have been - set. */ - gcc_assert (TREE_PUBLIC (fn)); - comdat_linkage (fn); - DECL_INTERFACE_KNOWN (fn) = 1; - } - } - else - import_export_decl (fn); - - /* If the user wants us to keep all inline functions, then mark - this function as needed so that finish_file will make sure to - output it later. */ - if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn)) - mark_needed (fn); - } - - /* There's no reason to do any of the work here if we're only doing - semantic analysis; this code just generates RTL. */ - if (flag_syntax_only) - return; - - function_depth++; - - /* Expand or defer, at the whim of the compilation unit manager. */ - cgraph_finalize_function (fn, function_depth > 1); - - function_depth--; -} - -struct nrv_data -{ - tree var; - tree result; - htab_t visited; -}; - -/* Helper function for walk_tree, used by finalize_nrv below. */ - -static tree -finalize_nrv_r (tree* tp, int* walk_subtrees, void* data) -{ - struct nrv_data *dp = (struct nrv_data *)data; - void **slot; - - /* No need to walk into types. There wouldn't be any need to walk into - non-statements, except that we have to consider STMT_EXPRs. */ - if (TYPE_P (*tp)) - *walk_subtrees = 0; - /* Change all returns to just refer to the RESULT_DECL; this is a nop, - but differs from using NULL_TREE in that it indicates that we care - about the value of the RESULT_DECL. */ - else if (TREE_CODE (*tp) == RETURN_EXPR) - TREE_OPERAND (*tp, 0) = dp->result; - /* Change all cleanups for the NRV to only run when an exception is - thrown. */ - else if (TREE_CODE (*tp) == CLEANUP_STMT - && CLEANUP_DECL (*tp) == dp->var) - CLEANUP_EH_ONLY (*tp) = 1; - /* Replace the DECL_EXPR for the NRV with an initialization of the - RESULT_DECL, if needed. */ - else if (TREE_CODE (*tp) == DECL_EXPR - && DECL_EXPR_DECL (*tp) == dp->var) - { - tree init; - if (DECL_INITIAL (dp->var) - && DECL_INITIAL (dp->var) != error_mark_node) - { - init = build2 (INIT_EXPR, void_type_node, dp->result, - DECL_INITIAL (dp->var)); - DECL_INITIAL (dp->var) = error_mark_node; - } - else - init = build_empty_stmt (); - SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp)); - *tp = init; - } - /* And replace all uses of the NRV with the RESULT_DECL. */ - else if (*tp == dp->var) - *tp = dp->result; - - /* Avoid walking into the same tree more than once. Unfortunately, we - can't just use walk_tree_without duplicates because it would only call - us for the first occurrence of dp->var in the function body. */ - slot = htab_find_slot (dp->visited, *tp, INSERT); - if (*slot) - *walk_subtrees = 0; - else - *slot = *tp; - - /* Keep iterating. */ - return NULL_TREE; -} - -/* Called from finish_function to implement the named return value - optimization by overriding all the RETURN_EXPRs and pertinent - CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the - RESULT_DECL for the function. */ - -void -finalize_nrv (tree *tp, tree var, tree result) -{ - struct nrv_data data; - - /* Copy debugging information from VAR to RESULT. */ - DECL_NAME (result) = DECL_NAME (var); - DECL_ARTIFICIAL (result) = DECL_ARTIFICIAL (var); - DECL_IGNORED_P (result) = DECL_IGNORED_P (var); - DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var); - DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var); - /* Don't forget that we take its address. */ - TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var); - - data.var = var; - data.result = result; - data.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL); - walk_tree (tp, finalize_nrv_r, &data, 0); - htab_delete (data.visited); -} - -/* For all elements of CLAUSES, validate them vs OpenMP constraints. - Remove any elements from the list that are invalid. */ - -tree -finish_omp_clauses (tree clauses) -{ - bitmap_head generic_head, firstprivate_head, lastprivate_head; - tree c, t, *pc = &clauses; - const char *name; - - bitmap_obstack_initialize (NULL); - bitmap_initialize (&generic_head, &bitmap_default_obstack); - bitmap_initialize (&firstprivate_head, &bitmap_default_obstack); - bitmap_initialize (&lastprivate_head, &bitmap_default_obstack); - - for (pc = &clauses, c = clauses; c ; c = *pc) - { - bool remove = false; - - switch (OMP_CLAUSE_CODE (c)) - { - case OMP_CLAUSE_SHARED: - name = "shared"; - goto check_dup_generic; - case OMP_CLAUSE_PRIVATE: - name = "private"; - goto check_dup_generic; - case OMP_CLAUSE_REDUCTION: - name = "reduction"; - goto check_dup_generic; - case OMP_CLAUSE_COPYPRIVATE: - name = "copyprivate"; - goto check_dup_generic; - case OMP_CLAUSE_COPYIN: - name = "copyin"; - goto check_dup_generic; - check_dup_generic: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - if (processing_template_decl) - break; - if (DECL_P (t)) - error ("%qD is not a variable in clause %qs", t, name); - else - error ("%qE is not a variable in clause %qs", t, name); - remove = true; - } - else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&firstprivate_head, DECL_UID (t)) - || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) - { - error ("%qD appears more than once in data clauses", t); - remove = true; - } - else - bitmap_set_bit (&generic_head, DECL_UID (t)); - break; - - case OMP_CLAUSE_FIRSTPRIVATE: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - if (processing_template_decl) - break; - error ("%qE is not a variable in clause %<firstprivate%>", t); - remove = true; - } - else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) - { - error ("%qE appears more than once in data clauses", t); - remove = true; - } - else - bitmap_set_bit (&firstprivate_head, DECL_UID (t)); - break; - - case OMP_CLAUSE_LASTPRIVATE: - t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - if (processing_template_decl) - break; - error ("%qE is not a variable in clause %<lastprivate%>", t); - remove = true; - } - else if (bitmap_bit_p (&generic_head, DECL_UID (t)) - || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) - { - error ("%qE appears more than once in data clauses", t); - remove = true; - } - else - bitmap_set_bit (&lastprivate_head, DECL_UID (t)); - break; - - case OMP_CLAUSE_IF: - t = OMP_CLAUSE_IF_EXPR (c); - t = maybe_convert_cond (t); - if (t == error_mark_node) - remove = true; - OMP_CLAUSE_IF_EXPR (c) = t; - break; - - case OMP_CLAUSE_NUM_THREADS: - t = OMP_CLAUSE_NUM_THREADS_EXPR (c); - if (t == error_mark_node) - remove = true; - else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - && !type_dependent_expression_p (t)) - { - error ("num_threads expression must be integral"); - remove = true; - } - break; - - case OMP_CLAUSE_SCHEDULE: - t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c); - if (t == NULL) - ; - else if (t == error_mark_node) - remove = true; - else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - && !type_dependent_expression_p (t)) - { - error ("schedule chunk size expression must be integral"); - remove = true; - } - break; - - case OMP_CLAUSE_NOWAIT: - case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_DEFAULT: - break; - - default: - gcc_unreachable (); - } - - if (remove) - *pc = OMP_CLAUSE_CHAIN (c); - else - pc = &OMP_CLAUSE_CHAIN (c); - } - - for (pc = &clauses, c = clauses; c ; c = *pc) - { - enum tree_code c_kind = OMP_CLAUSE_CODE (c); - bool remove = false; - bool need_complete_non_reference = false; - bool need_default_ctor = false; - bool need_copy_ctor = false; - bool need_copy_assignment = false; - bool need_implicitly_determined = false; - tree type, inner_type; - - switch (c_kind) - { - case OMP_CLAUSE_SHARED: - name = "shared"; - need_implicitly_determined = true; - break; - case OMP_CLAUSE_PRIVATE: - name = "private"; - need_complete_non_reference = true; - need_default_ctor = true; - need_implicitly_determined = true; - break; - case OMP_CLAUSE_FIRSTPRIVATE: - name = "firstprivate"; - need_complete_non_reference = true; - need_copy_ctor = true; - need_implicitly_determined = true; - break; - case OMP_CLAUSE_LASTPRIVATE: - name = "lastprivate"; - need_complete_non_reference = true; - need_copy_assignment = true; - need_implicitly_determined = true; - break; - case OMP_CLAUSE_REDUCTION: - name = "reduction"; - need_implicitly_determined = true; - break; - case OMP_CLAUSE_COPYPRIVATE: - name = "copyprivate"; - need_copy_assignment = true; - break; - case OMP_CLAUSE_COPYIN: - name = "copyin"; - need_copy_assignment = true; - break; - default: - pc = &OMP_CLAUSE_CHAIN (c); - continue; - } - - t = OMP_CLAUSE_DECL (c); - if (processing_template_decl - && TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) - { - pc = &OMP_CLAUSE_CHAIN (c); - continue; - } - - switch (c_kind) - { - case OMP_CLAUSE_LASTPRIVATE: - if (!bitmap_bit_p (&firstprivate_head, DECL_UID (t))) - need_default_ctor = true; - break; - - case OMP_CLAUSE_REDUCTION: - if (AGGREGATE_TYPE_P (TREE_TYPE (t)) - || POINTER_TYPE_P (TREE_TYPE (t))) - { - error ("%qE has invalid type for %<reduction%>", t); - remove = true; - } - else if (FLOAT_TYPE_P (TREE_TYPE (t))) - { - enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c); - switch (r_code) - { - case PLUS_EXPR: - case MULT_EXPR: - case MINUS_EXPR: - break; - default: - error ("%qE has invalid type for %<reduction(%s)%>", - t, operator_name_info[r_code].name); - remove = true; - } - } - break; - - case OMP_CLAUSE_COPYIN: - if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t)) - { - error ("%qE must be %<threadprivate%> for %<copyin%>", t); - remove = true; - } - break; - - default: - break; - } - - if (need_complete_non_reference) - { - t = require_complete_type (t); - if (t == error_mark_node) - remove = true; - else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) - { - error ("%qE has reference type for %qs", t, name); - remove = true; - } - } - if (need_implicitly_determined) - { - const char *share_name = NULL; - - if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t)) - share_name = "threadprivate"; - else switch (cxx_omp_predetermined_sharing (t)) - { - case OMP_CLAUSE_DEFAULT_UNSPECIFIED: - break; - case OMP_CLAUSE_DEFAULT_SHARED: - share_name = "shared"; - break; - case OMP_CLAUSE_DEFAULT_PRIVATE: - share_name = "private"; - break; - default: - gcc_unreachable (); - } - if (share_name) - { - error ("%qE is predetermined %qs for %qs", - t, share_name, name); - remove = true; - } - } - - /* We're interested in the base element, not arrays. */ - inner_type = type = TREE_TYPE (t); - while (TREE_CODE (inner_type) == ARRAY_TYPE) - inner_type = TREE_TYPE (inner_type); - - /* Check for special function availability by building a call to one. - Save the results, because later we won't be in the right context - for making these queries. */ - if (CLASS_TYPE_P (inner_type) - && (need_default_ctor || need_copy_ctor || need_copy_assignment) - && !type_dependent_expression_p (t)) - { - int save_errorcount = errorcount; - tree info; - - /* Always allocate 3 elements for simplicity. These are the - function decls for the ctor, dtor, and assignment op. - This layout is known to the three lang hooks, - cxx_omp_clause_default_init, cxx_omp_clause_copy_init, - and cxx_omp_clause_assign_op. */ - info = make_tree_vec (3); - CP_OMP_CLAUSE_INFO (c) = info; - - if (need_default_ctor - || (need_copy_ctor - && !TYPE_HAS_TRIVIAL_INIT_REF (inner_type))) - { - if (need_default_ctor) - t = NULL; - else - { - t = build_int_cst (build_pointer_type (inner_type), 0); - t = build1 (INDIRECT_REF, inner_type, t); - t = build_tree_list (NULL, t); - } - t = build_special_member_call (NULL_TREE, - complete_ctor_identifier, - t, inner_type, LOOKUP_NORMAL); - t = get_callee_fndecl (t); - TREE_VEC_ELT (info, 0) = t; - } - - if ((need_default_ctor || need_copy_ctor) - && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_type)) - { - t = build_int_cst (build_pointer_type (inner_type), 0); - t = build1 (INDIRECT_REF, inner_type, t); - t = build_special_member_call (t, complete_dtor_identifier, - NULL, inner_type, LOOKUP_NORMAL); - t = get_callee_fndecl (t); - TREE_VEC_ELT (info, 1) = t; - } - - if (need_copy_assignment - && !TYPE_HAS_TRIVIAL_ASSIGN_REF (inner_type)) - { - t = build_int_cst (build_pointer_type (inner_type), 0); - t = build1 (INDIRECT_REF, inner_type, t); - t = build_special_member_call (t, ansi_assopname (NOP_EXPR), - build_tree_list (NULL, t), - inner_type, LOOKUP_NORMAL); - - /* We'll have called convert_from_reference on the call, which - may well have added an indirect_ref. It's unneeded here, - and in the way, so kill it. */ - if (TREE_CODE (t) == INDIRECT_REF) - t = TREE_OPERAND (t, 0); - - t = get_callee_fndecl (t); - TREE_VEC_ELT (info, 2) = t; - } - - if (errorcount != save_errorcount) - remove = true; - } - - if (remove) - *pc = OMP_CLAUSE_CHAIN (c); - else - pc = &OMP_CLAUSE_CHAIN (c); - } - - bitmap_obstack_release (NULL); - return clauses; -} - -/* For all variables in the tree_list VARS, mark them as thread local. */ - -void -finish_omp_threadprivate (tree vars) -{ - tree t; - - /* Mark every variable in VARS to be assigned thread local storage. */ - for (t = vars; t; t = TREE_CHAIN (t)) - { - tree v = TREE_PURPOSE (t); - - /* If V had already been marked threadprivate, it doesn't matter - whether it had been used prior to this point. */ - if (TREE_USED (v) - && (DECL_LANG_SPECIFIC (v) == NULL - || !CP_DECL_THREADPRIVATE_P (v))) - error ("%qE declared %<threadprivate%> after first use", v); - else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v)) - error ("automatic variable %qE cannot be %<threadprivate%>", v); - else if (! COMPLETE_TYPE_P (TREE_TYPE (v))) - error ("%<threadprivate%> %qE has incomplete type", v); - else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v))) - error ("%<threadprivate%> %qE is not file, namespace " - "or block scope variable", v); - else - { - /* Allocate a LANG_SPECIFIC structure for V, if needed. */ - if (DECL_LANG_SPECIFIC (v) == NULL) - { - retrofit_lang_decl (v); - - /* Make sure that DECL_DISCRIMINATOR_P continues to be true - after the allocation of the lang_decl structure. */ - if (DECL_DISCRIMINATOR_P (v)) - DECL_LANG_SPECIFIC (v)->decl_flags.u2sel = 1; - } - - if (! DECL_THREAD_LOCAL_P (v)) - { - DECL_TLS_MODEL (v) = decl_default_tls_model (v); - /* If rtl has been already set for this var, call - make_decl_rtl once again, so that encode_section_info - has a chance to look at the new decl flags. */ - if (DECL_RTL_SET_P (v)) - make_decl_rtl (v); - } - CP_DECL_THREADPRIVATE_P (v) = 1; - } - } -} - -/* Build an OpenMP structured block. */ - -tree -begin_omp_structured_block (void) -{ - return do_pushlevel (sk_omp); -} - -tree -finish_omp_structured_block (tree block) -{ - return do_poplevel (block); -} - -/* Similarly, except force the retention of the BLOCK. */ - -tree -begin_omp_parallel (void) -{ - keep_next_level (true); - return begin_omp_structured_block (); -} - -tree -finish_omp_parallel (tree clauses, tree body) -{ - tree stmt; - - body = finish_omp_structured_block (body); - - stmt = make_node (OMP_PARALLEL); - TREE_TYPE (stmt) = void_type_node; - OMP_PARALLEL_CLAUSES (stmt) = clauses; - OMP_PARALLEL_BODY (stmt) = body; - - return add_stmt (stmt); -} - -/* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR - are directly for their associated operands in the statement. DECL - and INIT are a combo; if DECL is NULL then INIT ought to be a - MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are - optional statements that need to go before the loop into its - sk_omp scope. */ - -tree -finish_omp_for (location_t locus, tree decl, tree init, tree cond, - tree incr, tree body, tree pre_body) -{ - if (decl == NULL) - { - if (init != NULL) - switch (TREE_CODE (init)) - { - case MODIFY_EXPR: - decl = TREE_OPERAND (init, 0); - init = TREE_OPERAND (init, 1); - break; - case MODOP_EXPR: - if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR) - { - decl = TREE_OPERAND (init, 0); - init = TREE_OPERAND (init, 2); - } - break; - default: - break; - } - - if (decl == NULL) - { - error ("expected iteration declaration or initialization"); - return NULL; - } - } - - if (type_dependent_expression_p (decl) - || type_dependent_expression_p (init) - || (cond && type_dependent_expression_p (cond)) - || (incr && type_dependent_expression_p (incr))) - { - tree stmt; - - if (cond == NULL) - { - error ("%Hmissing controlling predicate", &locus); - return NULL; - } - - if (incr == NULL) - { - error ("%Hmissing increment expression", &locus); - return NULL; - } - - stmt = make_node (OMP_FOR); - - /* This is really just a place-holder. We'll be decomposing this - again and going through the build_modify_expr path below when - we instantiate the thing. */ - init = build2 (MODIFY_EXPR, void_type_node, decl, init); - - TREE_TYPE (stmt) = void_type_node; - OMP_FOR_INIT (stmt) = init; - OMP_FOR_COND (stmt) = cond; - OMP_FOR_INCR (stmt) = incr; - OMP_FOR_BODY (stmt) = body; - OMP_FOR_PRE_BODY (stmt) = pre_body; - - SET_EXPR_LOCATION (stmt, locus); - return add_stmt (stmt); - } - - if (!DECL_P (decl)) - { - error ("expected iteration declaration or initialization"); - return NULL; - } - - if (pre_body == NULL || IS_EMPTY_STMT (pre_body)) - pre_body = NULL; - else if (! processing_template_decl) - { - add_stmt (pre_body); - pre_body = NULL; - } - init = build_modify_expr (decl, NOP_EXPR, init); - return c_finish_omp_for (locus, decl, init, cond, incr, body, pre_body); -} - -void -finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) -{ - tree orig_lhs; - tree orig_rhs; - bool dependent_p; - tree stmt; - - orig_lhs = lhs; - orig_rhs = rhs; - dependent_p = false; - stmt = NULL_TREE; - - /* Even in a template, we can detect invalid uses of the atomic - pragma if neither LHS nor RHS is type-dependent. */ - if (processing_template_decl) - { - dependent_p = (type_dependent_expression_p (lhs) - || type_dependent_expression_p (rhs)); - if (!dependent_p) - { - lhs = build_non_dependent_expr (lhs); - rhs = build_non_dependent_expr (rhs); - } - } - if (!dependent_p) - { - stmt = c_finish_omp_atomic (code, lhs, rhs); - if (stmt == error_mark_node) - return; - } - if (processing_template_decl) - { - stmt = build2 (OMP_ATOMIC, void_type_node, orig_lhs, orig_rhs); - OMP_ATOMIC_DEPENDENT_P (stmt) = 1; - OMP_ATOMIC_CODE (stmt) = code; - } - add_stmt (stmt); -} - -void -finish_omp_barrier (void) -{ - tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER]; - tree stmt = finish_call_expr (fn, NULL, false, false); - finish_expr_stmt (stmt); -} - -void -finish_omp_flush (void) -{ - tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE]; - tree stmt = finish_call_expr (fn, NULL, false, false); - finish_expr_stmt (stmt); -} - -/* True if OpenMP sharing attribute of DECL is predetermined. */ - -enum omp_clause_default_kind -cxx_omp_predetermined_sharing (tree decl) -{ - enum omp_clause_default_kind kind; - - kind = c_omp_predetermined_sharing (decl); - if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED) - return kind; - - /* Static data members are predetermined as shared. */ - if (TREE_STATIC (decl)) - { - tree ctx = CP_DECL_CONTEXT (decl); - if (TYPE_P (ctx) && IS_AGGR_TYPE (ctx)) - return OMP_CLAUSE_DEFAULT_SHARED; - } - - return OMP_CLAUSE_DEFAULT_UNSPECIFIED; -} - -void -init_cp_semantics (void) -{ -} - -#include "gt-cp-semantics.h" |