summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-05-21 15:55:56 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-05-21 15:55:56 +0000
commite9c0ac6adade75d7bf98f8d41a996c7236554ffe (patch)
tree4e92434070d5a41b4f55d72fcc9bd86c081920ec /gcc/cp
parentaa74f96b6a5ace30daa598bbc1d1cfa92f520e71 (diff)
downloadgcc-e9c0ac6adade75d7bf98f8d41a996c7236554ffe.tar.gz
* Make-lang.in (cc1plus): Make it depend on gxx.gperf.
* cp-tree.h: Fix typo in documentation on pointers-to-members. (cp_build_qualified_type): Make it a macro. (cp_build_qualified_type_real): Declare. * decl.c (grokdeclarator): Remove misleading comment. Avoid problem with template parameters and restrict-qualification. * gxx.gperf: Replace NORID with RID_UNUSED throughout. * hash.h: Regenerated. * lex.h (rid): Move RID_FIRST_MODIFIER and RID_LAST_MODIFIER into the enumeration. (NORID): Remove definition. * pt.c (tsubst_aggr_type): Use cp_build_qualified_type_real. (tsubst): Likewise. Remove special handling for FUNCTION_TYPEs. (fn_type_unification): Check that the function type resulting from the deduction is legal. (check_cv_quals_for_unify): Don't handle FUNCTION_TYPEs specially. (unify): Use cp_build_qualified_type_real. * tree.c (build_cplus_array_type_1): Handle error_marks as inputs. (cp_build_qualified_type): Rename to ... (cp_build_qualified_type_real): Add additional COMPLAIN parameter and modify appropriately. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27086 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog25
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/cp/gxx.gperf120
-rw-r--r--gcc/cp/hash.h120
-rw-r--r--gcc/cp/lex.h9
-rw-r--r--gcc/cp/pt.c71
-rw-r--r--gcc/cp/tree.c35
9 files changed, 225 insertions, 171 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6ff46de2a62..6c64408f1db 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,28 @@
1999-05-21 Mark Mitchell <mark@codesourcery.com>
-
+ Nathan Sidwell <nathan@acm.org>
+
+ * Make-lang.in (cc1plus): Make it depend on gxx.gperf.
+ * cp-tree.h: Fix typo in documentation on pointers-to-members.
+ (cp_build_qualified_type): Make it a macro.
+ (cp_build_qualified_type_real): Declare.
+ * decl.c (grokdeclarator): Remove misleading comment. Avoid
+ problem with template parameters and restrict-qualification.
+ * gxx.gperf: Replace NORID with RID_UNUSED throughout.
+ * hash.h: Regenerated.
+ * lex.h (rid): Move RID_FIRST_MODIFIER and RID_LAST_MODIFIER into
+ the enumeration.
+ (NORID): Remove definition.
+ * pt.c (tsubst_aggr_type): Use cp_build_qualified_type_real.
+ (tsubst): Likewise. Remove special handling for FUNCTION_TYPEs.
+ (fn_type_unification): Check that the function type resulting from
+ the deduction is legal.
+ (check_cv_quals_for_unify): Don't handle FUNCTION_TYPEs specially.
+ (unify): Use cp_build_qualified_type_real.
+ * tree.c (build_cplus_array_type_1): Handle error_marks as inputs.
+ (cp_build_qualified_type): Rename to ...
+ (cp_build_qualified_type_real): Add additional COMPLAIN parameter
+ and modify appropriately.
+
* typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to
reveal optimization opportunities.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index d5d4e4d4cef..72795da3499 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -120,7 +120,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c
cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \
- $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def hash.o
+ $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def $(srcdir)/cp/gxx.gperf hash.o
cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext)
#
# Build hooks:
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c2becd903af..b2b6313fd85 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1721,7 +1721,7 @@ extern int flag_new_for_scope;
non-virtual function. Of course, `&f__2B2' is the name of that
function.
- (Of course, the exactl values may differ depending on the mangling
+ (Of course, the exact values may differ depending on the mangling
scheme, sizes of types, and such.). */
/* Get the POINTER_TYPE to the METHOD_TYPE associated with this
@@ -2100,7 +2100,6 @@ extern void check_function_format PROTO((tree, tree, tree));
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PROTO((enum tree_code));
-extern tree cp_build_qualified_type PROTO((tree, int));
extern tree canonical_type_variant PROTO((tree));
extern void c_expand_expr_stmt PROTO((tree));
/* Validate the expression after `case' and apply default promotions. */
@@ -3387,6 +3386,9 @@ extern int is_dummy_object PROTO((tree));
extern tree search_tree PROTO((tree, tree (*)(tree)));
extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree));
extern tree make_ptrmem_cst PROTO((tree, tree));
+extern tree cp_build_qualified_type_real PROTO((tree, int, int));
+#define cp_build_qualified_type(TYPE, QUALS) \
+ cp_build_qualified_type_real ((TYPE), (QUALS), /*complain=*/1)
#define scratchalloc expralloc
#define scratch_tree_cons expr_tree_cons
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 111ce222fe9..dd2dbb754b0 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11650,9 +11650,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (RIDBIT_SETP (RID_STATIC, specbits))
DECL_THIS_STATIC (decl) = 1;
- /* Record constancy and volatility. */
- /* FIXME: Disallow `restrict' pointer-to-member declarations. */
- c_apply_type_quals_to_decl (type_quals, decl);
+ /* Record constancy and volatility. There's no need to do this
+ when processing a template; we'll do this for the instantiated
+ declaration based on the type of DECL. */
+ if (!processing_template_decl)
+ c_apply_type_quals_to_decl (type_quals, decl);
return decl;
}
diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf
index 1e621c4a22d..2134939fed7 100644
--- a/gcc/cp/gxx.gperf
+++ b/gcc/cp/gxx.gperf
@@ -3,109 +3,109 @@
%}
struct resword { const char *name; short token; enum rid rid;};
%%
-__alignof, ALIGNOF, NORID
-__alignof__, ALIGNOF, NORID
-__asm, ASM_KEYWORD, NORID
-__asm__, ASM_KEYWORD, NORID
-__attribute, ATTRIBUTE, NORID
-__attribute__, ATTRIBUTE, NORID
+__alignof, ALIGNOF, RID_UNUSED
+__alignof__, ALIGNOF, RID_UNUSED
+__asm, ASM_KEYWORD, RID_UNUSED
+__asm__, ASM_KEYWORD, RID_UNUSED
+__attribute, ATTRIBUTE, RID_UNUSED
+__attribute__, ATTRIBUTE, RID_UNUSED
__complex, TYPESPEC, RID_COMPLEX
__complex__, TYPESPEC, RID_COMPLEX
__const, CV_QUALIFIER, RID_CONST
__const__, CV_QUALIFIER, RID_CONST
-__extension__, EXTENSION, NORID
-__imag, IMAGPART, NORID
-__imag__, IMAGPART, NORID
+__extension__, EXTENSION, RID_UNUSED
+__imag, IMAGPART, RID_UNUSED
+__imag__, IMAGPART, RID_UNUSED
__inline, SCSPEC, RID_INLINE
__inline__, SCSPEC, RID_INLINE
-__label__, LABEL, NORID
+__label__, LABEL, RID_UNUSED
__null, CONSTANT, RID_NULL
-__real, REALPART, NORID
-__real__, REALPART, NORID
+__real, REALPART, RID_UNUSED
+__real__, REALPART, RID_UNUSED
__restrict, CV_QUALIFIER, RID_RESTRICT
__restrict__, CV_QUALIFIER, RID_RESTRICT
__signature__, AGGR, RID_SIGNATURE /* Extension */,
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
-__sigof__, SIGOF, NORID /* Extension */,
-__typeof, TYPEOF, NORID
-__typeof__, TYPEOF, NORID
+__sigof__, SIGOF, RID_UNUSED /* Extension */,
+__typeof, TYPEOF, RID_UNUSED
+__typeof__, TYPEOF, RID_UNUSED
__volatile, CV_QUALIFIER, RID_VOLATILE
__volatile__, CV_QUALIFIER, RID_VOLATILE
__wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,
-asm, ASM_KEYWORD, NORID,
-and, ANDAND, NORID,
-and_eq, ASSIGN, NORID,
+asm, ASM_KEYWORD, RID_UNUSED,
+and, ANDAND, RID_UNUSED,
+and_eq, ASSIGN, RID_UNUSED,
auto, SCSPEC, RID_AUTO,
-bitand, '&', NORID,
-bitor, '|', NORID,
+bitand, '&', RID_UNUSED,
+bitor, '|', RID_UNUSED,
bool, TYPESPEC, RID_BOOL,
-break, BREAK, NORID,
-case, CASE, NORID,
-catch, CATCH, NORID,
+break, BREAK, RID_UNUSED,
+case, CASE, RID_UNUSED,
+catch, CATCH, RID_UNUSED,
char, TYPESPEC, RID_CHAR,
class, AGGR, RID_CLASS,
-compl, '~', NORID,
+compl, '~', RID_UNUSED,
const, CV_QUALIFIER, RID_CONST,
-const_cast, CONST_CAST, NORID,
-continue, CONTINUE, NORID,
-default, DEFAULT, NORID,
-delete, DELETE, NORID,
-do, DO, NORID,
+const_cast, CONST_CAST, RID_UNUSED,
+continue, CONTINUE, RID_UNUSED,
+default, DEFAULT, RID_UNUSED,
+delete, DELETE, RID_UNUSED,
+do, DO, RID_UNUSED,
double, TYPESPEC, RID_DOUBLE,
-dynamic_cast, DYNAMIC_CAST, NORID,
-else, ELSE, NORID,
-enum, ENUM, NORID,
+dynamic_cast, DYNAMIC_CAST, RID_UNUSED,
+else, ELSE, RID_UNUSED,
+enum, ENUM, RID_UNUSED,
explicit, SCSPEC, RID_EXPLICIT,
export, SCSPEC, RID_EXPORT,
extern, SCSPEC, RID_EXTERN,
-false, CXX_FALSE, NORID,
+false, CXX_FALSE, RID_UNUSED,
float, TYPESPEC, RID_FLOAT,
-for, FOR, NORID,
+for, FOR, RID_UNUSED,
friend, SCSPEC, RID_FRIEND,
-goto, GOTO, NORID,
-if, IF, NORID,
+goto, GOTO, RID_UNUSED,
+if, IF, RID_UNUSED,
inline, SCSPEC, RID_INLINE,
int, TYPESPEC, RID_INT,
long, TYPESPEC, RID_LONG,
mutable, SCSPEC, RID_MUTABLE,
-namespace, NAMESPACE, NORID,
-new, NEW, NORID,
-not, '!', NORID,
-not_eq, EQCOMPARE, NORID,
-operator, OPERATOR, NORID,
-or, OROR, NORID,
-or_eq, ASSIGN, NORID,
+namespace, NAMESPACE, RID_UNUSED,
+new, NEW, RID_UNUSED,
+not, '!', RID_UNUSED,
+not_eq, EQCOMPARE, RID_UNUSED,
+operator, OPERATOR, RID_UNUSED,
+or, OROR, RID_UNUSED,
+or_eq, ASSIGN, RID_UNUSED,
private, VISSPEC, RID_PRIVATE,
protected, VISSPEC, RID_PROTECTED,
public, VISSPEC, RID_PUBLIC,
register, SCSPEC, RID_REGISTER,
-reinterpret_cast, REINTERPRET_CAST, NORID,
-return, RETURN_KEYWORD, NORID,
+reinterpret_cast, REINTERPRET_CAST, RID_UNUSED,
+return, RETURN_KEYWORD, RID_UNUSED,
short, TYPESPEC, RID_SHORT,
signature, AGGR, RID_SIGNATURE /* Extension */,
signed, TYPESPEC, RID_SIGNED,
-sigof, SIGOF, NORID /* Extension */,
-sizeof, SIZEOF, NORID,
+sigof, SIGOF, RID_UNUSED /* Extension */,
+sizeof, SIZEOF, RID_UNUSED,
static, SCSPEC, RID_STATIC,
-static_cast, STATIC_CAST, NORID,
+static_cast, STATIC_CAST, RID_UNUSED,
struct, AGGR, RID_RECORD,
-switch, SWITCH, NORID,
+switch, SWITCH, RID_UNUSED,
template, TEMPLATE, RID_TEMPLATE,
-this, THIS, NORID,
-throw, THROW, NORID,
-true, CXX_TRUE, NORID,
-try, TRY, NORID,
+this, THIS, RID_UNUSED,
+throw, THROW, RID_UNUSED,
+true, CXX_TRUE, RID_UNUSED,
+try, TRY, RID_UNUSED,
typedef, SCSPEC, RID_TYPEDEF,
-typename, TYPENAME_KEYWORD, NORID,
-typeid, TYPEID, NORID,
-typeof, TYPEOF, NORID,
+typename, TYPENAME_KEYWORD, RID_UNUSED,
+typeid, TYPEID, RID_UNUSED,
+typeof, TYPEOF, RID_UNUSED,
union, AGGR, RID_UNION,
unsigned, TYPESPEC, RID_UNSIGNED,
-using, USING, NORID,
+using, USING, RID_UNUSED,
virtual, SCSPEC, RID_VIRTUAL,
void, TYPESPEC, RID_VOID,
volatile, CV_QUALIFIER, RID_VOLATILE,
-while, WHILE, NORID,
-xor, '^', NORID,
-xor_eq, ASSIGN, NORID,
+while, WHILE, RID_UNUSED,
+xor, '^', RID_UNUSED,
+xor_eq, ASSIGN, RID_UNUSED,
diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h
index 3c6199630c1..b7db192440c 100644
--- a/gcc/cp/hash.h
+++ b/gcc/cp/hash.h
@@ -78,16 +78,16 @@ is_reserved_word (str, len)
static struct resword wordlist[] =
{
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"else", ELSE, NORID,},
+ {"else", ELSE, RID_UNUSED,},
{"", 0, 0},
- {"delete", DELETE, NORID,},
- {"case", CASE, NORID,},
- {"__real__", REALPART, NORID},
+ {"delete", DELETE, RID_UNUSED,},
+ {"case", CASE, RID_UNUSED,},
+ {"__real__", REALPART, RID_UNUSED},
{"", 0, 0},
- {"true", CXX_TRUE, NORID,},
- {"catch", CATCH, NORID,},
- {"typeid", TYPEID, NORID,},
- {"try", TRY, NORID,},
+ {"true", CXX_TRUE, RID_UNUSED,},
+ {"catch", CATCH, RID_UNUSED,},
+ {"typeid", TYPEID, RID_UNUSED,},
+ {"try", TRY, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0},
{"void", TYPESPEC, RID_VOID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
@@ -96,23 +96,23 @@ is_reserved_word (str, len)
{"protected", VISSPEC, RID_PROTECTED,},
{"extern", SCSPEC, RID_EXTERN,},
{"", 0, 0}, {"", 0, 0},
- {"not", '!', NORID,},
+ {"not", '!', RID_UNUSED,},
{"", 0, 0},
{"__signed", TYPESPEC, RID_SIGNED},
{"int", TYPESPEC, RID_INT,},
{"__signed__", TYPESPEC, RID_SIGNED},
- {"__real", REALPART, NORID},
+ {"__real", REALPART, RID_UNUSED},
{"", 0, 0},
- {"xor_eq", ASSIGN, NORID,},
+ {"xor_eq", ASSIGN, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"__attribute", ATTRIBUTE, NORID},
- {"__asm__", ASM_KEYWORD, NORID},
- {"__attribute__", ATTRIBUTE, NORID},
- {"compl", '~', NORID,},
+ {"__attribute", ATTRIBUTE, RID_UNUSED},
+ {"__asm__", ASM_KEYWORD, RID_UNUSED},
+ {"__attribute__", ATTRIBUTE, RID_UNUSED},
+ {"compl", '~', RID_UNUSED,},
{"public", VISSPEC, RID_PUBLIC,},
- {"not_eq", EQCOMPARE, NORID,},
- {"switch", SWITCH, NORID,},
- {"__extension__", EXTENSION, NORID},
+ {"not_eq", EQCOMPARE, RID_UNUSED,},
+ {"switch", SWITCH, RID_UNUSED,},
+ {"__extension__", EXTENSION, RID_UNUSED},
{"const", CV_QUALIFIER, RID_CONST,},
{"static", SCSPEC, RID_STATIC,},
{"", 0, 0},
@@ -121,77 +121,77 @@ is_reserved_word (str, len)
{"__inline__", SCSPEC, RID_INLINE},
{"__restrict__", CV_QUALIFIER, RID_RESTRICT},
{"inline", SCSPEC, RID_INLINE,},
- {"const_cast", CONST_CAST, NORID,},
- {"static_cast", STATIC_CAST, NORID,},
+ {"const_cast", CONST_CAST, RID_UNUSED,},
+ {"static_cast", STATIC_CAST, RID_UNUSED,},
{"__restrict", CV_QUALIFIER, RID_RESTRICT},
- {"xor", '^', NORID,},
+ {"xor", '^', RID_UNUSED,},
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
- {"new", NEW, NORID,},
- {"__alignof__", ALIGNOF, NORID},
+ {"new", NEW, RID_UNUSED,},
+ {"__alignof__", ALIGNOF, RID_UNUSED},
{"signed", TYPESPEC, RID_SIGNED,},
- {"and", ANDAND, NORID,},
+ {"and", ANDAND, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"explicit", SCSPEC, RID_EXPLICIT,},
{"", 0, 0},
- {"__imag__", IMAGPART, NORID},
- {"while", WHILE, NORID,},
+ {"__imag__", IMAGPART, RID_UNUSED},
+ {"while", WHILE, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"do", DO, NORID,},
- {"typename", TYPENAME_KEYWORD, NORID,},
+ {"do", DO, RID_UNUSED,},
+ {"typename", TYPENAME_KEYWORD, RID_UNUSED,},
{"friend", SCSPEC, RID_FRIEND,},
- {"continue", CONTINUE, NORID,},
+ {"continue", CONTINUE, RID_UNUSED,},
{"class", AGGR, RID_CLASS,},
- {"default", DEFAULT, NORID,},
- {"this", THIS, NORID,},
- {"dynamic_cast", DYNAMIC_CAST, NORID,},
- {"typeof", TYPEOF, NORID,},
+ {"default", DEFAULT, RID_UNUSED,},
+ {"this", THIS, RID_UNUSED,},
+ {"dynamic_cast", DYNAMIC_CAST, RID_UNUSED,},
+ {"typeof", TYPEOF, RID_UNUSED,},
{"virtual", SCSPEC, RID_VIRTUAL,},
{"export", SCSPEC, RID_EXPORT,},
- {"and_eq", ASSIGN, NORID,},
- {"__typeof__", TYPEOF, NORID},
+ {"and_eq", ASSIGN, RID_UNUSED,},
+ {"__typeof__", TYPEOF, RID_UNUSED},
{"__const__", CV_QUALIFIER, RID_CONST},
{"__volatile", CV_QUALIFIER, RID_VOLATILE},
{"short", TYPESPEC, RID_SHORT,},
{"__volatile__", CV_QUALIFIER, RID_VOLATILE},
{"__const", CV_QUALIFIER, RID_CONST},
- {"namespace", NAMESPACE, NORID,},
+ {"namespace", NAMESPACE, RID_UNUSED,},
{"char", TYPESPEC, RID_CHAR,},
{"unsigned", TYPESPEC, RID_UNSIGNED,},
{"double", TYPESPEC, RID_DOUBLE,},
- {"or_eq", ASSIGN, NORID,},
+ {"or_eq", ASSIGN, RID_UNUSED,},
{"__null", CONSTANT, RID_NULL},
- {"if", IF, NORID,},
+ {"if", IF, RID_UNUSED,},
{"__signature__", AGGR, RID_SIGNATURE /* Extension */,},
- {"__label__", LABEL, NORID},
+ {"__label__", LABEL, RID_UNUSED},
{"long", TYPESPEC, RID_LONG,},
- {"__imag", IMAGPART, NORID},
- {"__asm", ASM_KEYWORD, NORID},
+ {"__imag", IMAGPART, RID_UNUSED},
+ {"__asm", ASM_KEYWORD, RID_UNUSED},
{"", 0, 0},
- {"__sigof__", SIGOF, NORID /* Extension */,},
+ {"__sigof__", SIGOF, RID_UNUSED /* Extension */,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"struct", AGGR, RID_RECORD,},
{"", 0, 0},
{"volatile", CV_QUALIFIER, RID_VOLATILE,},
- {"false", CXX_FALSE, NORID,},
- {"sizeof", SIZEOF, NORID,},
+ {"false", CXX_FALSE, RID_UNUSED,},
+ {"sizeof", SIZEOF, RID_UNUSED,},
{"__complex__", TYPESPEC, RID_COMPLEX},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"for", FOR, NORID,},
- {"or", OROR, NORID,},
+ {"for", FOR, RID_UNUSED,},
+ {"or", OROR, RID_UNUSED,},
{"register", SCSPEC, RID_REGISTER,},
- {"throw", THROW, NORID,},
+ {"throw", THROW, RID_UNUSED,},
{"", 0, 0},
- {"using", USING, NORID,},
+ {"using", USING, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0},
{"__complex", TYPESPEC, RID_COMPLEX},
{"", 0, 0},
- {"asm", ASM_KEYWORD, NORID,},
+ {"asm", ASM_KEYWORD, RID_UNUSED,},
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
- {"enum", ENUM, NORID,},
- {"reinterpret_cast", REINTERPRET_CAST, NORID,},
+ {"enum", ENUM, RID_UNUSED,},
+ {"reinterpret_cast", REINTERPRET_CAST, RID_UNUSED,},
{"mutable", SCSPEC, RID_MUTABLE,},
- {"__alignof", ALIGNOF, NORID},
- {"return", RETURN_KEYWORD, NORID,},
+ {"__alignof", ALIGNOF, RID_UNUSED},
+ {"return", RETURN_KEYWORD, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0},
{"float", TYPESPEC, RID_FLOAT,},
@@ -199,26 +199,26 @@ is_reserved_word (str, len)
{"bool", TYPESPEC, RID_BOOL,},
{"", 0, 0},
{"typedef", SCSPEC, RID_TYPEDEF,},
- {"__typeof", TYPEOF, NORID},
- {"bitand", '&', NORID,},
- {"break", BREAK, NORID,},
+ {"__typeof", TYPEOF, RID_UNUSED},
+ {"bitand", '&', RID_UNUSED,},
+ {"break", BREAK, RID_UNUSED,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"union", AGGR, RID_UNION,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"goto", GOTO, NORID,},
- {"sigof", SIGOF, NORID /* Extension */,},
+ {"goto", GOTO, RID_UNUSED,},
+ {"sigof", SIGOF, RID_UNUSED /* Extension */,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
- {"bitor", '|', NORID,},
+ {"bitor", '|', RID_UNUSED,},
{"auto", SCSPEC, RID_AUTO,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0},
- {"operator", OPERATOR, NORID,}
+ {"operator", OPERATOR, RID_UNUSED,}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h
index 249eef9bb0f..5c2a1d148c6 100644
--- a/gcc/cp/lex.h
+++ b/gcc/cp/lex.h
@@ -43,8 +43,9 @@ enum rid
/* This is where grokdeclarator starts its search when setting the specbits.
The first seven are in the order of most frequently used, as found
building libg++. */
+ RID_FIRST_MODIFIER,
- RID_EXTERN,
+ RID_EXTERN = RID_FIRST_MODIFIER,
RID_CONST,
RID_LONG,
RID_TYPEDEF,
@@ -66,6 +67,7 @@ enum rid
RID_COMPLEX,
RID_RESTRICT,
+ RID_LAST_MODIFIER = RID_RESTRICT,
/* This is where grokdeclarator ends its search when setting the
specbits. */
@@ -81,11 +83,6 @@ enum rid
RID_MAX
};
-#define NORID RID_UNUSED
-
-#define RID_FIRST_MODIFIER RID_EXTERN
-#define RID_LAST_MODIFIER RID_COMPLEX
-
/* The type that can represent all values of RIDBIT. */
/* We assume that we can stick in at least 32 bits into this. */
typedef struct { unsigned long idata[2]; }
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9698b965124..6db901c9299 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5311,7 +5311,8 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
{
tree r = build_ptrmemfunc_type
(tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl));
- return cp_build_qualified_type (r, TYPE_QUALS (t));
+ return cp_build_qualified_type_real (r, TYPE_QUALS (t),
+ complain);
}
/* else fall through */
@@ -5349,7 +5350,8 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
entering_scope);
pop_momentary ();
- return cp_build_qualified_type (r, TYPE_QUALS (t));
+ return cp_build_qualified_type_real (r, TYPE_QUALS (t),
+ complain);
}
else
/* This is not a template type, so there's nothing to do. */
@@ -6208,18 +6210,9 @@ tsubst (t, args, complain, in_decl)
{
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (arg))
== 't', 0);
-
- /* If we're not COMPLAINing, don't let an attempt
- to qualify a FUNCTION_TYPE reach
- cp_build_qualified_type. That will result in
- an error message. */
- if (!complain
- && TREE_CODE (arg) == FUNCTION_TYPE
- && CP_TYPE_QUALS (t) != TYPE_UNQUALIFIED)
- return error_mark_node;
-
- return cp_build_qualified_type
- (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t));
+ return cp_build_qualified_type_real
+ (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t),
+ complain);
}
else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
{
@@ -6244,7 +6237,9 @@ tsubst (t, args, complain, in_decl)
argvec, in_decl,
DECL_CONTEXT (arg),
/*entering_scope=*/0);
- return cp_build_qualified_type (r, TYPE_QUALS (t));
+ return cp_build_qualified_type_real (r,
+ TYPE_QUALS (t),
+ complain);
}
else
/* We are processing a template argument list. */
@@ -6411,7 +6406,7 @@ tsubst (t, args, complain, in_decl)
r = build_pointer_type (type);
else
r = build_reference_type (type);
- r = cp_build_qualified_type (r, TYPE_QUALS (t));
+ r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
/* Will this ever be needed for TYPE_..._TO values? */
layout_type (r);
@@ -6553,9 +6548,10 @@ tsubst (t, args, complain, in_decl)
f = make_typename_type (ctx, f);
if (f == error_mark_node)
return f;
- return cp_build_qualified_type (f,
- CP_TYPE_QUALS (f)
- | CP_TYPE_QUALS (t));
+ return cp_build_qualified_type_real (f,
+ CP_TYPE_QUALS (f)
+ | CP_TYPE_QUALS (t),
+ complain);
}
case INDIRECT_REF:
@@ -7388,6 +7384,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
{
tree parms;
tree fntype;
+ int result;
my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
@@ -7446,9 +7443,25 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
because the standard doesn't seem to explicitly prohibit it. Our
callers must be ready to deal with unification failures in any
event. */
- return type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
- targs, parms, args, /*subr=*/0,
- strict, /*allow_incomplete*/1);
+ result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+ targs, parms, args, /*subr=*/0,
+ strict, /*allow_incomplete*/1);
+
+ if (result == 0)
+ /* All is well so far. Now, check:
+
+ [temp.deduct]
+
+ When all template arguments have been deduced, all uses of
+ template parameters in nondeduced contexts are replaced with
+ the corresponding deduced argument values. If the
+ substitution results in an invalid type, as described above,
+ type deduction fails. */
+ if (tsubst (TREE_TYPE (fn), targs, /*complain=*/0, NULL_TREE)
+ == error_mark_node)
+ return 1;
+
+ return result;
}
/* Adjust types before performing type deduction, as described in
@@ -8040,11 +8053,6 @@ check_cv_quals_for_unify (strict, arg, parm)
&& !at_least_as_qualified_p (parm, arg))
return 0;
- /* Don't allow unification to create a qualified function type. */
- if (TREE_CODE (arg) == FUNCTION_TYPE
- && CP_TYPE_QUALS (parm) != TYPE_UNQUALIFIED)
- return 0;
-
return 1;
}
@@ -8198,9 +8206,12 @@ unify (tparms, targs, parm, arg, strict)
/* Consider the case where ARG is `const volatile int' and
PARM is `const T'. Then, T should be `volatile int'. */
arg =
- cp_build_qualified_type (arg,
- CP_TYPE_QUALS (arg)
- & ~CP_TYPE_QUALS (parm));
+ cp_build_qualified_type_real (arg,
+ CP_TYPE_QUALS (arg)
+ & ~CP_TYPE_QUALS (parm),
+ /*complain=*/0);
+ if (arg == error_mark_node)
+ return 1;
}
/* Simple cases: Value already set, does match or doesn't. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a305cb5ca2c..9d77217e0a8 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -407,6 +407,9 @@ build_cplus_array_type_1 (elt_type, index_type)
register struct obstack *ambient_saveable_obstack = saveable_obstack;
tree t;
+ if (elt_type == error_mark_node || index_type == error_mark_node)
+ return error_mark_node;
+
/* We need a new one. If both ELT_TYPE and INDEX_TYPE are permanent,
make this permanent too. */
if (TREE_PERMANENT (elt_type)
@@ -454,13 +457,18 @@ build_cplus_array_type (elt_type, index_type)
return t;
}
-/* Make a variant type in the proper way for C/C++, propagating qualifiers
- down to the element type of an array. */
+/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles
+ arrays correctly. In particular, if TYPE is an array of T's, and
+ TYPE_QUALS is non-empty, returns an array of qualified T's. If
+ at attempt is made to qualify a type illegally, and COMPLAIN is
+ non-zero, an error is issued. If COMPLAIN is zero, error_mark_node
+ is returned. */
tree
-cp_build_qualified_type (type, type_quals)
+cp_build_qualified_type_real (type, type_quals, complain)
tree type;
int type_quals;
+ int complain;
{
if (type == error_mark_node)
return type;
@@ -468,29 +476,40 @@ cp_build_qualified_type (type, type_quals)
/* A restrict-qualified pointer type must be a pointer (or reference)
to object or incomplete type. */
if ((type_quals & TYPE_QUAL_RESTRICT)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM
&& (!POINTER_TYPE_P (type)
|| TYPE_PTRMEM_P (type)
|| TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
{
- cp_error ("`%T' cannot be `restrict'-qualified", type);
+ if (complain)
+ cp_error ("`%T' cannot be `restrict'-qualified", type);
+ else
+ return error_mark_node;
+
type_quals &= ~TYPE_QUAL_RESTRICT;
}
if (type_quals != TYPE_UNQUALIFIED
&& TREE_CODE (type) == FUNCTION_TYPE)
{
- cp_error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type);
+ if (complain)
+ cp_error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type);
+ else
+ return error_mark_node;
type_quals = TYPE_UNQUALIFIED;
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{
tree real_main_variant = TYPE_MAIN_VARIANT (type);
-
+ tree element_type = cp_build_qualified_type_real (TREE_TYPE (type),
+ type_quals,
+ complain);
push_obstacks (TYPE_OBSTACK (real_main_variant),
TYPE_OBSTACK (real_main_variant));
- type = build_cplus_array_type_1 (cp_build_qualified_type
- (TREE_TYPE (type), type_quals),
+ type = build_cplus_array_type_1 (element_type,
TYPE_DOMAIN (type));
+ if (type == error_mark_node)
+ return error_mark_node;
/* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not,
make a copy. (TYPE might have come from the hash table and