Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
faae18ab
Commit
faae18ab
authored
Apr 03, 1995
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
62nd Cygnus<->FSF merge
From-SVN: r9298
parent
684cfb6b
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
724 additions
and
362 deletions
+724
-362
gcc/cp/ChangeLog
+113
-0
gcc/cp/Make-lang.in
+1
-1
gcc/cp/Makefile.in
+2
-1
gcc/cp/call.c
+2
-8
gcc/cp/cp-tree.h
+27
-8
gcc/cp/cvt.c
+1
-4
gcc/cp/decl.c
+68
-150
gcc/cp/decl2.c
+25
-23
gcc/cp/except.c
+88
-68
gcc/cp/lex.c
+2
-1
gcc/cp/method.c
+2
-1
gcc/cp/parse.y
+2
-0
gcc/cp/pt.c
+52
-26
gcc/cp/repo.c
+278
-0
gcc/cp/search.c
+4
-0
gcc/cp/typeck.c
+57
-71
No files found.
gcc/cp/ChangeLog
View file @
faae18ab
Sun Apr 2 23:43:51 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* search.c (compute_access): Don't try to do access control on
nested types.
Fri Mar 31 10:14:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* repo.c: New file to handle things repo.
* pt.c (instantiate_template): Call repo_template_used if the
definition is accessible.
(mark_function_instantiated): Split out from
do_function_instantiation.
(mark_class_instantiated): Split out from do_type_instantiation.
* parse.y (template_instantiate_once): Call repo_template_used.
* lex.c (lang_init): Call init_repo.
* decl2.c: Handle flag_use_repository.
(finish_file): Call finish_repo.
* decl.c (start_method): Call repo_template_used if this is a
template method.
* Makefile.in (CXX_OBJS): Add repo.o.
(repo.o): Add dependencies.
* Make-lang.in (CXX_SRCS): Add repo.c.
* decl.c (start_function): If DECL_INTERFACE_KNOWN and
DECL_NOT_REALLY_EXTERN are both set, unset DECL_EXTERNAL.
* typeck.c (build_binary_op_nodefault): Identify the invalid operand
types used.
* decl.c (duplicate_decls): Propagate DECL_NOT_REALLY_EXTERN.
Thu Mar 30 17:54:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault): Tidy up use of build_type
and result_type. When checking for comparison between signed
and unsigned, use result_type rather than the (possibly shortened)
type of op0. Also, don't warn about equality comparison of a
signed operand to an unsigned constant that fits in the signed
type.
* method.c (do_build_copy_constructor): Reverse
current_base_init_list after we've built it up.
Thu Mar 30 14:35:18 1995 Mike Stump <mrs@cygnus.com>
* except.c (build_throw): Never warn about the value of throw not
being used.
Thu Mar 30 13:16:54 1995 Mike Stump <mrs@cygnus.com>
* except.c (expand_start_catch_block): Check for bad catch parameter
declarations.
Thu Mar 30 13:06:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl.c (finish_function): Only set DECL_NOT_REALLY_EXTERN if
DECL_EXTERNAL is not already set.
Thu Mar 30 11:26:24 1995 Mike Stump <mrs@cygnus.com>
* method.c (emit_thunk): Let poplevel know that the last level is
for a function so it can create a BLOCK_NODE and set DECL_INITIAL.
Thu Mar 30 11:15:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (import_export_inline): Don't set DECL_NOT_REALLY_EXTERN
here.
* decl.c (grokdeclarator): OK, don't abort if we see a decl with
METHOD_TYPE.
(finish_function): Set DECL_EXTERNAL and DECL_NOT_REALLY_EXTERN on
all deferred inlines.
Wed Mar 29 19:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* cp-tree.h (DECL_THIS_INLINE): New macro.
(DECL_NOT_REALLY_EXTERN): New macro.
(DECL_THIS_STATIC): New macro.
* decl.c: Lose all references to current_extern_inline. Break
inline semantics into DECL_INLINE for actual inlining and
DECL_THIS_INLINE for the linkage wierdness. Use DECL_THIS_STATIC.
* decl2.c: Use DECL_NOT_REALLY_EXTERN to indicate that we want to
emit an inline here. Associated changes.
* lex.c: Ditto.
* pt.c: Ditto.
* typeck.c: Ditto.
* call.c (build_method_call): Don't bother trying to handle inlines
specially.
* cvt.c (convert_to_aggr): Ditto.
* pt.c (do_function_instantiation): Handle instantiation of
public inlines, too.
Wed Mar 29 16:04:25 1995 Mike Stump <mrs@cygnus.com>
* except.c (init_exception_processing): Change the interface for
__throw_type_match and add decl for new rtti matching routine
__throw_type_match_rtti.
(build_eh_type): New routine to build a run time descriptor for the
expression given.
(expand_start_catch_block): Update to use new calling convention for
the matcher.
(expand_throw): Update to use build_eh_type.
Mon Mar 27 07:14:33 1995 Warner Losh <imp@village.org>
* g++.c: Removed __NetBSD__ from conditional.
...
...
gcc/cp/Make-lang.in
View file @
faae18ab
...
...
@@ -76,7 +76,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)
/cp/errfn.c
$(srcdir)
/cp/gc.c
$(srcdir)
/cp/method.c
\
$(srcdir)
/cp/search.c
$(srcdir)
/cp/typeck.c
$(srcdir)
/cp/decl.c
\
$(srcdir)
/cp/error.c
$(srcdir)
/cp/init.c
$(srcdir)
/cp/parse.y
\
$(srcdir)
/cp/sig.c
$(srcdir)
/cp/typeck2.c
$(srcdir)
/cp/sig.c
$(srcdir)
/cp/typeck2.c
$(srcdir)
/cp/repo.c
cc1plus
:
$(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o
cd
cp
;
$(MAKE)
$(FLAGS_TO_PASS)
$(CXX_FLAGS_TO_PASS)
../cc1plus
...
...
gcc/cp/Makefile.in
View file @
faae18ab
...
...
@@ -159,7 +159,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config
CXX_OBJS
=
call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o
\
class.o decl2.o error.o gc.o lex.o parse.o ptree.o spew.o typeck.o cvt.o
\
edsel.o except.o init.o method.o search.o tree.o xref.o
edsel.o except.o init.o method.o search.o tree.o xref.o
repo.o
# Language-independent object files.
OBJS
=
`
cat
../stamp-objlist
`
../c-common.o ../c-pragma.o
...
...
@@ -247,6 +247,7 @@ pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H)
error.o
:
error.c $(CONFIG_H) $(CXX_TREE_H)
errfn.o
:
errfn.c $(CONFIG_H) $(CXX_TREE_H)
sig.o
:
sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
repo.o
:
repo.c $(CONFIG.H) $(CXX_TREE_H)
# These exist for maintenance purposes.
...
...
gcc/cp/call.c
View file @
faae18ab
...
...
@@ -2575,14 +2575,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
if
(
TREE_CODE
(
function
)
==
FUNCTION_DECL
)
{
is_constructor
=
DECL_CONSTRUCTOR_P
(
function
);
if
(
DECL_INLINE
(
function
))
function
=
build1
(
ADDR_EXPR
,
build_pointer_type
(
fntype
),
function
);
else
{
assemble_external
(
function
);
TREE_USED
(
function
)
=
1
;
function
=
default_conversion
(
function
);
}
TREE_USED
(
function
)
=
1
;
function
=
default_conversion
(
function
);
}
else
{
...
...
gcc/cp/cp-tree.h
View file @
faae18ab
...
...
@@ -954,9 +954,11 @@ struct lang_decl_flags
unsigned
saved_inline
:
1
;
unsigned
use_template
:
2
;
unsigned
declared
_static
:
1
;
unsigned
c
_static
:
1
;
unsigned
nonconverting
:
1
;
unsigned
dummy
:
6
;
unsigned
declared_inline
:
1
;
unsigned
not_really_extern
:
1
;
unsigned
dummy
:
4
;
tree
access
;
tree
context
;
...
...
@@ -1234,10 +1236,14 @@ struct lang_decl
#define DELTA2_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, 0, 0), delta2_identifier, 0, 0))
#define PFN_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, 0, 0), pfn_identifier, 0, 0))
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern
al
' was
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
specified in its declaration. */
#define DECL_THIS_EXTERN(NODE) (DECL_LANG_FLAG_2(NODE))
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was
specified in its declaration. */
#define DECL_THIS_STATIC(NODE) (DECL_LANG_FLAG_6(NODE))
/* Nonzero for SAVE_EXPR if used to initialize a PARM_DECL. */
#define PARM_DECL_EXPR(NODE) (TREE_LANG_FLAG_2(NODE))
...
...
@@ -1338,13 +1344,26 @@ struct lang_decl
/* We know what we're doing with this decl now. */
#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
/* This decl was declared to have internal linkage. */
#define DECL_DECLARED_STATIC(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_static)
/* This decl was declared or deduced to have internal linkage. This is
only meaningful if TREE_PUBLIC is set. */
#define DECL_C_STATIC(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.c_static)
/* This function was declared inline. This flag controls the linkage
semantics of 'inline'; whether or not the function is inlined is
controlled by DECL_INLINE. */
#define DECL_THIS_INLINE(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_inline)
/* DECL_EXTERNAL must be set on a decl until the decl is actually emitted,
so that assemble_external will work properly. So we have this flag to
tell us whether the decl is really not external. */
#define DECL_NOT_REALLY_EXTERN(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern)
#define DECL_PUBLIC(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL
? ! DECL_DECLARED_STATIC (NODE)
\
: TREE_PUBLIC (NODE))
(TREE_CODE (NODE) == FUNCTION_DECL \
? ! DECL_C_STATIC (NODE)
: TREE_PUBLIC (NODE))
#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i)
...
...
gcc/cp/cvt.c
View file @
faae18ab
...
...
@@ -1090,10 +1090,7 @@ convert_to_aggr (type, expr, msgp, protect)
return
NULL_TREE
;
fntype
=
TREE_TYPE
(
function
);
if
(
DECL_INLINE
(
function
)
&&
TREE_CODE
(
function
)
==
FUNCTION_DECL
)
function
=
build1
(
ADDR_EXPR
,
build_pointer_type
(
fntype
),
function
);
else
function
=
default_conversion
(
function
);
function
=
default_conversion
(
function
);
result
=
build_nt
(
CALL_EXPR
,
function
,
convert_arguments
(
NULL_TREE
,
TYPE_ARG_TYPES
(
fntype
),
...
...
gcc/cp/decl.c
View file @
faae18ab
...
...
@@ -406,10 +406,6 @@ tree current_function_return_value;
static
int
warn_about_return_type
;
/* Nonzero when starting a function declared `extern inline'. */
static
int
current_extern_inline
;
/* Nonzero means give `double' the same size as `float'. */
extern
int
flag_short_double
;
...
...
@@ -2082,13 +2078,11 @@ warn_extern_redeclared_static (newdecl, olddecl)
=
"`%D' was declared implicitly `extern' and later `static'"
;
if
(
flag_traditional
||
TREE_CODE
(
newdecl
)
==
TYPE_DECL
||
(
!
warn_extern_inline
&&
DECL_INLINE
(
newdecl
)))
||
TREE_CODE
(
newdecl
)
==
TYPE_DECL
)
return
;
name
=
DECL_ASSEMBLER_NAME
(
newdecl
);
if
(
TREE_PUBLIC
(
name
)
&&
!
DECL_PUBL
IC
(
newdecl
))
if
(
TREE_PUBLIC
(
name
)
&&
DECL_THIS_STAT
IC
(
newdecl
))
{
/* It's okay to redeclare an ANSI built-in function as static,
or to declare a non-ANSI built-in function as anything. */
...
...
@@ -2516,8 +2510,9 @@ duplicate_decls (newdecl, olddecl)
if
(
TREE_CODE
(
newdecl
)
==
FUNCTION_DECL
)
{
DECL_
DECLARED_STATIC
(
newdecl
)
=
DECL_DECLARED
_STATIC
(
olddecl
);
DECL_
C_STATIC
(
newdecl
)
=
DECL_C
_STATIC
(
olddecl
);
DECL_INTERFACE_KNOWN
(
newdecl
)
=
DECL_INTERFACE_KNOWN
(
olddecl
);
DECL_NOT_REALLY_EXTERN
(
newdecl
)
=
DECL_NOT_REALLY_EXTERN
(
olddecl
);
}
}
else
...
...
@@ -2537,14 +2532,16 @@ duplicate_decls (newdecl, olddecl)
}
}
/* If either decl says `inline', this fn is inline,
unless its definition was passed already. */
if
(
DECL_INLINE
(
newdecl
)
&&
DECL_INITIAL
(
olddecl
)
==
NULL_TREE
)
DECL_INLINE
(
olddecl
)
=
1
;
DECL_INLINE
(
newdecl
)
=
DECL_INLINE
(
olddecl
);
if
(
TREE_CODE
(
newdecl
)
==
FUNCTION_DECL
)
{
DECL_THIS_INLINE
(
newdecl
)
|=
DECL_THIS_INLINE
(
olddecl
);
/* If either decl says `inline', this fn is inline, unless its
definition was passed already. */
if
(
DECL_INLINE
(
newdecl
)
&&
DECL_INITIAL
(
olddecl
)
==
NULL_TREE
)
DECL_INLINE
(
olddecl
)
=
1
;
DECL_INLINE
(
newdecl
)
=
DECL_INLINE
(
olddecl
);
if
(
!
types_match
)
{
DECL_LANGUAGE
(
olddecl
)
=
DECL_LANGUAGE
(
newdecl
);
...
...
@@ -2968,7 +2965,7 @@ pushdecl (x)
/* If this is an extern function declaration, see if we
have a global definition or declaration for the function. */
if
(
oldlocal
==
NULL_TREE
&&
DECL_EXTERNAL
(
x
)
&&
!
DECL_INLINE
(
x
)
&&
DECL_EXTERNAL
(
x
)
&&
oldglobal
!=
NULL_TREE
&&
TREE_CODE
(
x
)
==
FUNCTION_DECL
&&
TREE_CODE
(
oldglobal
)
==
FUNCTION_DECL
)
...
...
@@ -3454,11 +3451,7 @@ redeclaration_error_message (newdecl, olddecl)
/* defining the same name twice is no good. */
if
(
DECL_INITIAL
(
olddecl
)
!=
NULL_TREE
&&
DECL_INITIAL
(
newdecl
)
!=
NULL_TREE
/* However, defining once as extern inline and a second
time in another way is ok. */
&&
!
(
DECL_INLINE
(
olddecl
)
&&
DECL_EXTERNAL
(
olddecl
)
&&
!
(
DECL_INLINE
(
newdecl
)
&&
DECL_EXTERNAL
(
newdecl
))))
&&
DECL_INITIAL
(
newdecl
)
!=
NULL_TREE
)
{
if
(
DECL_NAME
(
olddecl
)
==
NULL_TREE
)
return
"`%#D' not declared in class"
;
...
...
@@ -6393,55 +6386,7 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags)
signature_error
(
decl
,
TREE_TYPE
(
type
));
if
(
TREE_CODE
(
decl
)
==
FUNCTION_DECL
)
{
#if 0
/* C++: Handle overloaded functions with default parameters. */
if (DECL_OVERLOADED (decl))
{
tree parmtypes = TYPE_ARG_TYPES (type);
tree prev = NULL_TREE;
tree original_name = DECL_NAME (decl);
struct lang_decl *tmp_lang_decl = DECL_LANG_SPECIFIC (decl);
/* All variants will share an uncollectible lang_decl. */
copy_decl_lang_specific (decl);
while (parmtypes && parmtypes != void_list_node)
{
/* The default value for the parameter in parmtypes is
stored in the TREE_PURPOSE of the TREE_LIST. */
if (TREE_PURPOSE (parmtypes))
{
tree fnname, fndecl;
tree *argp;
argp = prev ? & TREE_CHAIN (prev)
: & TYPE_ARG_TYPES (type);
*argp = NULL_TREE;
fnname = build_decl_overload (original_name,
TYPE_ARG_TYPES (type), 0);
*argp = parmtypes;
fndecl = build_decl (FUNCTION_DECL, fnname, type);
DECL_EXTERNAL (fndecl) = DECL_EXTERNAL (decl);
TREE_PUBLIC (fndecl) = TREE_PUBLIC (decl);
DECL_INLINE (fndecl) = DECL_INLINE (decl);
/* Keep G++ from thinking this function is unused.
It is only used to speed up search in name space. */
TREE_USED (fndecl) = 1;
TREE_ASM_WRITTEN (fndecl) = 1;
DECL_INITIAL (fndecl) = NULL_TREE;
DECL_LANG_SPECIFIC (fndecl) = DECL_LANG_SPECIFIC (decl);
fndecl = pushdecl (fndecl);
DECL_INITIAL (fndecl) = error_mark_node;
DECL_RTL (fndecl) = DECL_RTL (decl);
}
prev = parmtypes;
parmtypes = TREE_CHAIN (parmtypes);
}
DECL_LANG_SPECIFIC (decl) = tmp_lang_decl;
}
#endif
}
;
else
if
(
DECL_EXTERNAL
(
decl
))
;
else
if
(
TREE_STATIC
(
decl
)
&&
type
!=
error_mark_node
)
...
...
@@ -6775,13 +6720,13 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
not look, and -1 if we should not call `grokclassfn' at all. */
static
tree
grokfndecl
(
ctype
,
type
,
declarator
,
virtualp
,
flags
,
quals
,
raises
,
check
,
publicp
)
raises
,
check
,
publicp
,
inlinep
)
tree
ctype
,
type
;
tree
declarator
;
int
virtualp
;
enum
overload_flags
flags
;
tree
quals
,
raises
;
int
check
,
publicp
;
int
check
,
publicp
,
inlinep
;
{
tree
cname
,
decl
;
int
staticp
=
ctype
&&
TREE_CODE
(
type
)
==
FUNCTION_TYPE
;
...
...
@@ -6814,10 +6759,21 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
definition or EOF) if appropriate. */
TREE_PUBLIC
(
decl
)
=
1
;
if
(
publicp
)
;
else
DECL_DECLARED_STATIC
(
decl
)
=
1
;
if
(
ctype
==
NULL_TREE
&&
!
strcmp
(
IDENTIFIER_POINTER
(
declarator
),
"main"
))
{
if
(
inlinep
)
error
(
"cannot declare `main' to be inline"
);
else
if
(
!
publicp
)
error
(
"cannot declare `main' to be static"
);
inlinep
=
0
;
publicp
=
1
;
}
if
(
!
publicp
)
DECL_C_STATIC
(
decl
)
=
1
;
if
(
inlinep
)
DECL_THIS_INLINE
(
decl
)
=
DECL_INLINE
(
decl
)
=
1
;
DECL_EXTERNAL
(
decl
)
=
1
;
if
(
quals
!=
NULL_TREE
&&
TREE_CODE
(
type
)
==
FUNCTION_TYPE
)
...
...
@@ -9060,37 +9016,30 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
}
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
publicp
=
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
)
||
(
ctype
!=
NULL_TREE
&&
funcdef_flag
>=
0
&&
RIDBIT_NOTSETP
(
RID_INLINE
,
specbits
))
||
(
friendp
&&
!
funcdef_flag
&&
RIDBIT_NOTSETP
(
RID_STATIC
,
specbits
)
&&
RIDBIT_NOTSETP
(
RID_INLINE
,
specbits
)));
publicp
=
(
!
friendp
||
RIDBIT_SETP
(
RID_EXTERN
,
specbits
)
||
!
(
funcdef_flag
<
0
||
inlinep
));
decl
=
grokfndecl
(
ctype
,
type
,
declarator
,
virtualp
,
flags
,
quals
,
raises
,
friendp
?
-
1
:
0
,
publicp
);
raises
,
friendp
?
-
1
:
0
,
publicp
,
inlinep
);
if
(
decl
==
NULL_TREE
)
return
NULL_TREE
;
decl
=
build_decl_attribute_variant
(
decl
,
decl_machine_attr
);
if
(
explicitp
==
2
)
DECL_NONCONVERTING_P
(
decl
)
=
1
;
DECL_INLINE
(
decl
)
=
inlinep
;
}
else
if
(
TREE_CODE
(
type
)
==
METHOD_TYPE
)
{
/* We only get here for friend declarations of
members of other classes. */
/* All method decls are public, so tell grokfndecl to set
TREE_PUBLIC, also. */
decl
=
grokfndecl
(
ctype
,
type
,
declarator
,
virtualp
,
flags
,
quals
,
raises
,
friendp
?
-
1
:
0
,
1
);
raises
,
friendp
?
-
1
:
0
,
1
,
0
);
if
(
decl
==
NULL_TREE
)
return
NULL_TREE
;
DECL_INLINE
(
decl
)
=
inlinep
;
}
else
if
(
TYPE_SIZE
(
type
)
==
NULL_TREE
&&
!
staticp
&&
(
TREE_CODE
(
type
)
!=
ARRAY_TYPE
||
initialized
==
0
))
...
...
@@ -9255,16 +9204,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
type
=
build_cplus_method_type
(
build_type_variant
(
ctype
,
constp
,
volatilep
),
TREE_TYPE
(
type
),
TYPE_ARG_TYPES
(
type
));
/* Record presence of `static'. In C++, `inline' i
s like
`static'. */
publicp
=
!
(
RIDBIT_SETP
(
RID_STATIC
,
specbits
)
||
RIDBIT_SETP
(
RID_INLINE
,
specbits
));
/* Record presence of `static'. In C++, `inline' i
mplies
`static'. */
publicp
=
(
ctype
!=
NULL_TREE
||
(
!
RIDBIT_SETP
(
RID_STATIC
,
specbits
)
&&
!
RIDBIT_SETP
(
RID_INLINE
,
specbits
)
));
decl
=
grokfndecl
(
ctype
,
type
,
original_name
,
virtualp
,
flags
,
quals
,
raises
,
processing_template_decl
?
0
:
friendp
?
2
:
1
,
publicp
);
publicp
,
inlinep
);
if
(
decl
==
NULL_TREE
)
return
NULL_TREE
;
...
...
@@ -9282,14 +9231,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
cp_pedwarn
(
"cannot declare member function `%D' to have static linkage"
,
decl
);
illegal_static
=
1
;
}
else
if
(
!
ctype
&&
IDENTIFIER_LENGTH
(
original_name
)
==
4
&&
IDENTIFIER_POINTER
(
original_name
)[
0
]
==
'm'
&&
!
strcmp
(
IDENTIFIER_POINTER
(
original_name
),
"main"
))
{
error
(
"cannot declare function `main' to have static linkage"
);
illegal_static
=
1
;
}
else
if
(
current_function_decl
)
{
/* FIXME need arm citation */
...
...
@@ -9303,28 +9244,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
RIDBIT_RESET
(
RID_STATIC
,
specbits
);
}
}
/* Record presence of `inline', if it is reasonable. */
if
(
inlinep
)
{
tree
last
=
tree_last
(
TYPE_ARG_TYPES
(
type
));
if
(
!
ctype
&&
!
strcmp
(
IDENTIFIER_POINTER
(
original_name
),
"main"
))
error
(
"cannot inline function `main'"
);
else
if
(
last
&&
last
!=
void_list_node
)
cp_warning
(
"cannot inline function `%D' which takes `...'"
,
original_name
);
else
/* Assume that otherwise the function can be inlined. */
DECL_INLINE
(
decl
)
=
1
;
if
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
))
{
current_extern_inline
=
1
;
if
(
pedantic
)
pedwarn
(
"ANSI C++ does not permit `extern inline'"
);
}
}
}
else
{
...
...
@@ -9398,6 +9317,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if
(
RIDBIT_SETP
(
RID_EXTERN
,
specbits
))
DECL_THIS_EXTERN
(
decl
)
=
1
;
if
(
RIDBIT_SETP
(
RID_STATIC
,
specbits
))
DECL_THIS_STATIC
(
decl
)
=
1
;
/* Record constancy and volatility. */
if
(
constp
)
...
...
@@ -10723,7 +10645,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
current_function_returns_value
=
0
;
current_function_returns_null
=
0
;
warn_about_return_type
=
0
;
current_extern_inline
=
0
;
current_function_assigns_this
=
0
;
current_function_just_assigned_this
=
0
;
current_function_parms_stored
=
0
;
...
...
@@ -10781,11 +10702,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
doing_friend
=
1
;
}
if
(
!
(
DECL_VINDEX
(
decl1
)
&&
write_virtuals
>=
2
&&
CLASSTYPE_VTABLE_NEEDS_WRITING
(
ctype
)))
current_extern_inline
=
DECL_THIS_EXTERN
(
decl1
)
&&
DECL_INLINE
(
decl1
);
raises
=
TYPE_RAISES_EXCEPTIONS
(
fntype
);
/* In a fcn definition, arg types must be complete. */
...
...
@@ -10890,18 +10806,21 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
TREE_STATIC
(
decl1
)
=
1
;
if
(
DECL_INTERFACE_KNOWN
(
decl1
))
/* We know. */
;
{
if
(
DECL_NOT_REALLY_EXTERN
(
decl1
))
DECL_EXTERNAL
(
decl1
)
=
0
;
}
/* If this function belongs to an interface, it is public.
If it belongs to someone else's interface, it is also external.
It doesn't matter whether it's inline or not. */
else
if
(
interface_unknown
==
0
)
{
if
(
DECL_
DECLARED_STATIC
(
decl1
)
||
DECL_TEMPLATE_INSTANTIATION
(
decl1
))
if
(
DECL_
THIS_INLINE
(
decl1
)
||
DECL_TEMPLATE_INSTANTIATION
(
decl1
))
DECL_EXTERNAL
(
decl1
)
=
(
interface_only
||
(
DECL_INLINE
(
decl1
)
&&
!
flag_implement_inlines
));
||
(
DECL_
THIS_
INLINE
(
decl1
)
&&
!
flag_implement_inlines
));
else
DECL_EXTERNAL
(
decl1
)
=
current_extern_inline
;
DECL_EXTERNAL
(
decl1
)
=
0
;
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
}
else
...
...
@@ -10909,19 +10828,15 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
/* This is a definition, not a reference.
So clear DECL_EXTERNAL. */
DECL_EXTERNAL
(
decl1
)
=
0
;
if
(
DECL_INLINE
(
decl1
)
&&
(
DECL_FUNCTION_MEMBER_P
(
decl1
)
||
DECL_TEMPLATE_INSTANTIATION
(
decl1
)
||
current_extern_inline
))
/* We know nothing yet */
;
if
(
DECL_THIS_INLINE
(
decl1
)
&&
!
DECL_C_STATIC
(
decl1
))
DECL_DEFER_OUTPUT
(
decl1
)
=
1
;
else
{
DECL_INTERFACE_KNOWN
(
decl1
)
=
1
;
if
(
DECL_
DECLARED
_STATIC
(
decl1
))
if
(
DECL_
C
_STATIC
(
decl1
))
TREE_PUBLIC
(
decl1
)
=
0
;
}
DECL_DEFER_OUTPUT
(
decl1
)
=
!
DECL_INTERFACE_KNOWN
(
decl1
);
}
/* Record the decl so that the function name is defined.
...
...
@@ -11728,9 +11643,10 @@ finish_function (lineno, call_poplevel, nested)
if
(
DECL_SAVED_INSNS
(
fndecl
)
&&
!
TREE_ASM_WRITTEN
(
fndecl
))
{
/* Set DECL_EXTERNAL so that assemble_external will be called as
necessary. We'll clear it again in import_export_inline. */
if
(
TREE_PUBLIC
(
fndecl
))
DECL_EXTERNAL
(
fndecl
)
=
1
;
necessary. We'll clear it again in finish_file. */
if
(
!
DECL_EXTERNAL
(
fndecl
))
DECL_NOT_REALLY_EXTERN
(
fndecl
)
=
1
;
DECL_EXTERNAL
(
fndecl
)
=
1
;
mark_inline_for_output
(
fndecl
);
}
...
...
@@ -11857,11 +11773,16 @@ start_method (declspecs, declarator, raises)
return
void_type_node
;
}
DECL_THIS_INLINE
(
fndecl
)
=
1
;
if
(
flag_default_inline
)
DECL_INLINE
(
fndecl
)
=
1
;
if
(
processing_template_defn
)
SET_DECL_IMPLICIT_INSTANTIATION
(
fndecl
);
{
SET_DECL_IMPLICIT_INSTANTIATION
(
fndecl
);
repo_template_used
(
fndecl
);
}
/* We read in the parameters on the maybepermanent_obstack,
but we won't be getting back to them until after we
...
...
@@ -12207,7 +12128,6 @@ struct cp_function
int
returns_value
;
int
returns_null
;
int
warn_about_return_type
;
int
extern_inline
;
int
assigns_this
;
int
just_assigned_this
;
int
parms_stored
;
...
...
@@ -12247,7 +12167,6 @@ push_cp_function_context (context)
p
->
returns_value
=
current_function_returns_value
;
p
->
returns_null
=
current_function_returns_null
;
p
->
warn_about_return_type
=
warn_about_return_type
;
p
->
extern_inline
=
current_extern_inline
;
p
->
binding_level
=
current_binding_level
;
p
->
ctor_label
=
ctor_label
;
p
->
dtor_label
=
dtor_label
;
...
...
@@ -12295,7 +12214,6 @@ pop_cp_function_context (context)
current_function_returns_value
=
p
->
returns_value
;
current_function_returns_null
=
p
->
returns_null
;
warn_about_return_type
=
p
->
warn_about_return_type
;
current_extern_inline
=
p
->
extern_inline
;
current_binding_level
=
p
->
binding_level
;
ctor_label
=
p
->
ctor_label
;
dtor_label
=
p
->
dtor_label
;
...
...
gcc/cp/decl2.c
View file @
faae18ab
...
...
@@ -148,6 +148,10 @@ int warn_ctor_dtor_privacy = 1;
int
flag_vtable_thunks
;
/* True if we want to deal with repository information. */
int
flag_use_repository
;
/* Nonzero means give string constants the type `const char *'
to get extra warnings from them. These warnings will be too numerous
to be useful, except in thoroughly ANSIfied programs. */
...
...
@@ -399,7 +403,8 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{
"nonansi-builtins"
,
&
flag_no_nonansi_builtin
,
0
},
{
"gnu-keywords"
,
&
flag_no_gnu_keywords
,
0
},
{
"operator-names"
,
&
flag_operator_names
,
1
},
{
"check-new"
,
&
flag_check_new
,
1
}
{
"check-new"
,
&
flag_check_new
,
1
},
{
"repo"
,
&
flag_use_repository
,
1
}
};
/* Decode the string P as a language-specific option.
...
...
@@ -2466,13 +2471,7 @@ mark_vtable_entries (decl)
fnaddr
=
TREE_VALUE
(
entries
);
TREE_OPERAND
(
fnaddr
,
0
)
=
fn
=
abort_fndecl
;
}
if
(
TREE_PUBLIC
(
fn
)
&&
!
TREE_ASM_WRITTEN
(
fn
))
{
int
save_extern
=
DECL_EXTERNAL
(
fn
);
DECL_EXTERNAL
(
fn
)
=
1
;
assemble_external
(
fn
);
DECL_EXTERNAL
(
fn
)
=
save_extern
;
}
assemble_external
(
fn
);
}
}
...
...
@@ -2513,12 +2512,11 @@ import_export_vtable (decl, type, final)
if
(
!
found
&&
!
final
)
{
/* This check only works before the method definitions are seen,
since DECL_INLINE may get bashed. */
tree
method
;
for
(
method
=
CLASSTYPE_METHODS
(
type
);
method
!=
NULL_TREE
;
method
=
DECL_NEXT_METHOD
(
method
))
if
(
DECL_VINDEX
(
method
)
!=
NULL_TREE
&&
!
DECL_INLINE
(
method
)
if
(
DECL_VINDEX
(
method
)
!=
NULL_TREE
&&
!
DECL_THIS_INLINE
(
method
)
&&
!
DECL_ABSTRACT_VIRTUAL_P
(
method
))
{
found
=
1
;
...
...
@@ -2528,15 +2526,17 @@ import_export_vtable (decl, type, final)
if
(
final
||
!
found
)
{
#ifdef ASSEMBLE_EXTERNAL
if
(
TREE_PUBLIC
(
decl
))
cp_error
(
"all virtual functions redeclared inline"
);
#endif
TREE_PUBLIC
(
decl
)
=
0
;
DECL_EXTERNAL
(
decl
)
=
0
;
DECL_INTERFACE_KNOWN
(
decl
)
=
1
;
}
else
{
TREE_PUBLIC
(
decl
)
=
1
;
DECL_EXTERNAL
(
decl
)
=
1
;
DECL_INTERFACE_KNOWN
(
decl
)
=
0
;
}
}
}
...
...
@@ -2570,7 +2570,7 @@ finish_prevtable_vardecl (prev, vars)
method
=
DECL_NEXT_METHOD
(
method
))
{
if
(
DECL_VINDEX
(
method
)
!=
NULL_TREE
&&
!
DECL_
DECLARED_STATIC
(
method
)
&&
!
DECL_
THIS_INLINE
(
method
)
&&
!
DECL_ABSTRACT_VIRTUAL_P
(
method
))
{
SET_CLASSTYPE_INTERFACE_KNOWN
(
ctype
);
...
...
@@ -2747,23 +2747,21 @@ import_export_inline (decl)
if
(
DECL_INTERFACE_KNOWN
(
decl
))
return
;
DECL_EXTERNAL
(
decl
)
=
0
;
if
(
DECL_TEMPLATE_INSTANTIATION
(
decl
))
{
if
(
DECL_IMPLICIT_INSTANTIATION
(
decl
)
&&
flag_implicit_templates
)
TREE_PUBLIC
(
decl
)
=
0
;
else
DECL_
EXTERNAL
(
decl
)
=
1
;
DECL_
NOT_REALLY_EXTERN
(
decl
)
=
0
;
}
else
if
(
DECL_FUNCTION_MEMBER_P
(
decl
))
{
tree
ctype
=
DECL_CLASS_CONTEXT
(
decl
);
if
(
CLASSTYPE_INTERFACE_KNOWN
(
ctype
))
{
DECL_
EXTERNAL
(
decl
)
=
(
CLASSTYPE_INTERFACE_ONLY
(
ctype
)
||
(
DECL
_INLINE
(
decl
)
&&
!
flag_implement_inlines
));
DECL_
NOT_REALLY_EXTERN
(
decl
)
=
!
(
CLASSTYPE_INTERFACE_ONLY
(
ctype
)
||
(
DECL_THIS
_INLINE
(
decl
)
&&
!
flag_implement_inlines
));
}
else
TREE_PUBLIC
(
decl
)
=
0
;
...
...
@@ -3045,6 +3043,8 @@ finish_file ()
assemble_constructor
(
IDENTIFIER_POINTER
(
fnname
));
}
permanent_allocation
(
1
);
/* Done with C language context needs. */
pop_lang_context
();
...
...
@@ -3115,8 +3115,9 @@ finish_file ()
{
TREE_CHAIN
(
last
)
=
TREE_CHAIN
(
place
);
if
(
!
DECL_EXTERNAL
(
decl
))
if
(
DECL_NOT_REALLY_EXTERN
(
decl
))
{
DECL_EXTERNAL
(
decl
)
=
0
;
reconsider
=
1
;
temporary_allocation
();
output_inline_function
(
decl
);
...
...
@@ -3142,7 +3143,7 @@ finish_file ()
emit_thunk
(
vars
);
else
if
(
TREE_CODE
(
vars
)
==
FUNCTION_DECL
&&
!
DECL_INTERFACE_KNOWN
(
vars
)
&&
DECL_
DECLARED
_STATIC
(
vars
))
&&
DECL_
C
_STATIC
(
vars
))
TREE_PUBLIC
(
vars
)
=
0
;
}
...
...
@@ -3162,7 +3163,8 @@ finish_file ()
}
}
permanent_allocation
(
1
);
finish_repo
();
this_time
=
get_run_time
();
parse_time
-=
this_time
-
start_time
;
varconst_time
+=
this_time
-
start_time
;
...
...
gcc/cp/except.c
View file @
faae18ab
...
...
@@ -780,9 +780,14 @@ init_exception_processing ()
push_lang_context
(
lang_name_c
);
catch_match_fndecl
=
define_function
(
"__throw_type_match"
,
build_function_type
(
integer_type_node
,
tree_cons
(
NULL_TREE
,
string_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
))),
define_function
(
flag_rtti
?
"__throw_type_match_rtti"
:
"__throw_type_match"
,
build_function_type
(
ptr_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
)))),
NOT_BUILT_IN
,
pushdecl
,
0
);
...
...
@@ -1131,6 +1136,31 @@ expand_leftover_cleanups ()
}
}
/* Build a type value for use at runtime for a exp that is thrown or
matched against by the exception handling system. */
static
tree
build_eh_type
(
exp
)
tree
exp
;
{
char
*
typestring
;
tree
type
;
if
(
flag_rtti
)
{
exp
=
build_typeid
(
exp
);
return
build1
(
ADDR_EXPR
,
ptr_type_node
,
exp
);
}
type
=
TREE_TYPE
(
exp
);
/* peel back references, so they match. */
if
(
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
type
=
TREE_TYPE
(
type
);
typestring
=
build_overload_name
(
type
,
1
,
1
);
exp
=
combine_strings
(
build_string
(
strlen
(
typestring
)
+
1
,
typestring
));
return
build1
(
ADDR_EXPR
,
ptr_type_node
,
exp
);
}
/* call this to start a catch block. Typename is the typename, and identifier
is the variable to place the object in or NULL if the variable doesn't
matter. If typename is NULL, that means its a "catch (...)" or catch
...
...
@@ -1142,8 +1172,7 @@ expand_start_catch_block (declspecs, declarator)
{
rtx
false_label_rtx
;
rtx
protect_label_rtx
;
tree
type
;
tree
decl
;
tree
decl
=
NULL_TREE
;
tree
init
;
if
(
!
doing_eh
(
1
))
...
...
@@ -1152,33 +1181,6 @@ expand_start_catch_block (declspecs, declarator)
/* Create a binding level for the parm. */
expand_start_bindings
(
0
);
if
(
declspecs
)
{
tree
init_type
;
decl
=
grokdeclarator
(
declarator
,
declspecs
,
CATCHPARM
,
1
,
NULL_TREE
);
/* Figure out the type that the initializer is. */
init_type
=
TREE_TYPE
(
decl
);
if
(
TREE_CODE
(
init_type
)
!=
REFERENCE_TYPE
)
init_type
=
build_reference_type
(
init_type
);
init
=
convert_from_reference
(
save_expr
(
make_tree
(
init_type
,
saved_throw_value
)));
/* Do we need the below two lines? */
/* Let `finish_decl' know that this initializer is ok. */
DECL_INITIAL
(
decl
)
=
init
;
/* This needs to be preallocated under the try block,
in a union of all catch variables. */
pushdecl
(
decl
);
type
=
TREE_TYPE
(
decl
);
/* peel back references, so they match. */
if
(
TREE_CODE
(
type
)
==
REFERENCE_TYPE
)
type
=
TREE_TYPE
(
type
);
}
else
type
=
NULL_TREE
;
/* These are saved for the exception table. */
push_rtl_perm
();
false_label_rtx
=
gen_label_rtx
();
...
...
@@ -1187,34 +1189,50 @@ expand_start_catch_block (declspecs, declarator)
push_label_entry
(
&
false_label_stack
,
false_label_rtx
);
push_label_entry
(
&
false_label_stack
,
protect_label_rtx
);
if
(
type
)
if
(
declspecs
)
{
tree
params
;
char
*
typestring
;
tree
exp
;
rtx
call_rtx
,
return_value_rtx
;
tree
catch_match_fcall
;
tree
catchmatch_arg
,
argval
;
typestring
=
build_overload_name
(
type
,
1
,
1
);
params
=
tree_cons
(
NULL_TREE
,
combine_strings
(
build_string
(
strlen
(
typestring
)
+
1
,
typestring
)),
tree_cons
(
NULL_TREE
,
make_tree
(
ptr_type_node
,
saved_throw_type
),
NULL_TREE
));
catch_match_fcall
=
build_function_call
(
CatchMatch
,
params
);
call_rtx
=
expand_call
(
catch_match_fcall
,
NULL_RTX
,
0
);
tree
init_type
;
decl
=
grokdeclarator
(
declarator
,
declspecs
,
CATCHPARM
,
1
,
NULL_TREE
);
if
(
decl
==
NULL_TREE
)
{
error
(
"invalid catch parameter"
);
return
;
}
/* Figure out the type that the initializer is. */
init_type
=
TREE_TYPE
(
decl
);
if
(
TREE_CODE
(
init_type
)
!=
REFERENCE_TYPE
)
init_type
=
build_reference_type
(
init_type
);
exp
=
make_tree
(
ptr_type_node
,
saved_throw_value
);
exp
=
tree_cons
(
NULL_TREE
,
build_eh_type
(
decl
),
tree_cons
(
NULL_TREE
,
make_tree
(
ptr_type_node
,
saved_throw_type
),
tree_cons
(
NULL_TREE
,
exp
,
NULL_TREE
)));
exp
=
build_function_call
(
CatchMatch
,
exp
);
call_rtx
=
expand_call
(
exp
,
NULL_RTX
,
0
);
assemble_external
(
TREE_OPERAND
(
CatchMatch
,
0
));
return_value_rtx
=
hard_function_value
(
integer_type_node
,
catch_match_fcall
);
return_value_rtx
=
hard_function_value
(
ptr_type_node
,
exp
);
/* did the throw type match function return TRUE? */
emit_cmp_insn
(
return_value_rtx
,
const0_rtx
,
NE
,
NULL_RTX
,
emit_cmp_insn
(
return_value_rtx
,
const0_rtx
,
EQ
,
NULL_RTX
,
GET_MODE
(
return_value_rtx
),
0
,
0
);
/* if it returned FALSE, jump over the catch block, else fall into it */
emit_jump_insn
(
gen_bne
(
false_label_rtx
));
emit_jump_insn
(
gen_beq
(
false_label_rtx
));
init
=
convert_from_reference
(
save_expr
(
make_tree
(
init_type
,
call_rtx
)));
/* Do we need the below two lines? */
/* Let `finish_decl' know that this initializer is ok. */
DECL_INITIAL
(
decl
)
=
init
;
decl
=
pushdecl
(
decl
);
finish_decl
(
decl
,
init
,
NULL_TREE
,
0
,
LOOKUP_ONLYCONVERTING
);
}
else
...
...
@@ -1535,7 +1553,6 @@ expand_throw (exp)
tree
exp
;
{
rtx
label
;
tree
type
;
if
(
!
doing_eh
(
1
))
return
;
...
...
@@ -1548,26 +1565,28 @@ expand_throw (exp)
if
(
exp
)
{
tree
throw_type
;
rtx
throw_type_rtx
;
rtx
throw_value_rtx
;
/* throw expression */
/* First, decay it. */
exp
=
default_conversion
(
exp
);
type
=
TREE_TYPE
(
exp
);
{
char
*
typestring
=
build_overload_name
(
type
,
1
,
1
);
tree
throw_type
=
build1
(
ADDR_EXPR
,
ptr_type_node
,
combine_strings
(
build_string
(
strlen
(
typestring
)
+
1
,
typestring
)));
rtx
throw_type_rtx
=
expand_expr
(
throw_type
,
NULL_RTX
,
VOIDmode
,
0
);
rtx
throw_value_rtx
;
/* Make a copy of the thrown object. WP 15.1.5 */
exp
=
build_new
(
NULL_TREE
,
type
,
build_tree_list
(
NULL_TREE
,
exp
),
0
);
if
(
exp
==
error_mark_node
)
error
(
" in thrown expression"
);
throw_value_rtx
=
expand_expr
(
exp
,
NULL_RTX
,
VOIDmode
,
0
);
emit_move_insn
(
saved_throw_value
,
throw_value_rtx
);
emit_move_insn
(
saved_throw_type
,
throw_type_rtx
);
}
/* Make a copy of the thrown object. WP 15.1.5 */
exp
=
build_new
(
NULL_TREE
,
TREE_TYPE
(
exp
),
build_tree_list
(
NULL_TREE
,
exp
),
0
);
if
(
exp
==
error_mark_node
)
error
(
" in thrown expression"
);
throw_type
=
build_eh_type
(
build_indirect_ref
(
exp
,
NULL_PTR
));
throw_type_rtx
=
expand_expr
(
throw_type
,
NULL_RTX
,
VOIDmode
,
0
);
throw_value_rtx
=
expand_expr
(
exp
,
NULL_RTX
,
VOIDmode
,
0
);
emit_move_insn
(
saved_throw_value
,
throw_value_rtx
);
emit_move_insn
(
saved_throw_type
,
throw_type_rtx
);
}
else
{
...
...
@@ -1665,6 +1684,7 @@ build_throw (e)
{
e
=
build1
(
THROW_EXPR
,
void_type_node
,
e
);
TREE_SIDE_EFFECTS
(
e
)
=
1
;
TREE_USED
(
e
)
=
1
;
}
return
e
;
}
gcc/cp/lex.c
View file @
faae18ab
...
...
@@ -362,6 +362,7 @@ lang_init ()
if
(
flag_cadillac
)
cadillac_start
();
if
(
flag_gnu_xref
)
GNU_xref_begin
(
input_filename
);
init_repo
(
input_filename
);
}
void
...
...
@@ -1448,7 +1449,7 @@ store_pending_inline (decl, t)
punt them now, or output them now if we're doing implementations
and we know no overrides will exist. Otherwise, we delay until
end-of-file, to see if the definition is really required. */
if
(
DECL_INLINE
(
decl
))
if
(
DECL_
THIS_
INLINE
(
decl
))
/* delay_to_eof == 0 */
;
else
if
(
current_class_type
&&
!
interface_unknown
)
{
...
...
gcc/cp/method.c
View file @
faae18ab
...
...
@@ -1936,7 +1936,7 @@ emit_thunk (thunk_fndecl)
emit_insn
(
gen_rtx
(
USE
,
VOIDmode
,
need_use
[
--
need_use_count
]));
expand_end_bindings
(
NULL
,
1
,
0
);
poplevel
(
0
,
0
,
0
);
poplevel
(
0
,
0
,
1
);
/* From now on, allocate rtl in current_obstack, not in saveable_obstack.
Note that that may have been done above, in save_for_inline_copying.
...
...
@@ -2122,6 +2122,7 @@ do_build_copy_constructor (fndecl)
=
tree_cons
(
DECL_NAME
(
fields
),
init
,
current_member_init_list
);
}
current_member_init_list
=
nreverse
(
current_member_init_list
);
current_base_init_list
=
nreverse
(
current_base_init_list
);
setup_vtbl_ptr
();
}
...
...
gcc/cp/parse.y
View file @
faae18ab
...
...
@@ -897,6 +897,8 @@ template_instantiate_once:
pop_obstacks ();
end_template_instantiation ($1);
repo_template_used (t);
/* Now go after the methods & class data. */
instantiate_member_templates ($1);
...
...
gcc/cp/pt.c
View file @
faae18ab
...
...
@@ -1450,6 +1450,7 @@ tsubst (t, args, nargs, in_decl)
TREE_STATIC
(
r
)
=
0
;
DECL_INTERFACE_KNOWN
(
r
)
=
0
;
DECL_INLINE
(
r
)
=
DECL_INLINE
(
t
);
DECL_THIS_INLINE
(
r
)
=
DECL_THIS_INLINE
(
t
);
{
#if 0 /* Maybe later. -jason */
struct tinst_level *til = tinst_for_decl();
...
...
@@ -1751,6 +1752,7 @@ instantiate_template (tmpl, targ_ptr)
else
if
(
t
->
text
)
{
SET_DECL_IMPLICIT_INSTANTIATION
(
fndecl
);
repo_template_used
(
fndecl
);
p
=
(
struct
pending_inline
*
)
permalloc
(
sizeof
(
struct
pending_inline
));
p
->
parm_vec
=
t
->
parm_vec
;
p
->
bindings
=
targs
;
...
...
@@ -2384,7 +2386,7 @@ do_pending_expansions ()
DECIDE
(
0
);
if
(
DECL_EXPLICIT_INSTANTIATION
(
t
))
DECIDE
(
!
DECL_EXTERNAL
(
t
));
DECIDE
(
DECL_NOT_REALLY_EXTERN
(
t
));
else
if
(
!
flag_implicit_templates
)
DECIDE
(
0
);
...
...
@@ -2486,6 +2488,22 @@ add_pending_template (pt)
p
->
id
=
pt
;
}
void
mark_function_instantiated
(
result
,
extern_p
)
tree
result
;
int
extern_p
;
{
if
(
DECL_TEMPLATE_INSTANTIATION
(
result
))
SET_DECL_EXPLICIT_INSTANTIATION
(
result
);
TREE_PUBLIC
(
result
)
=
1
;
if
(
!
extern_p
)
{
DECL_INTERFACE_KNOWN
(
result
)
=
1
;
DECL_NOT_REALLY_EXTERN
(
result
)
=
1
;
}
}
/* called from the parser. */
void
do_function_instantiation
(
declspecs
,
declarator
,
storage
)
...
...
@@ -2495,10 +2513,17 @@ do_function_instantiation (declspecs, declarator, storage)
tree
name
=
DECL_NAME
(
decl
);
tree
fn
=
IDENTIFIER_GLOBAL_VALUE
(
name
);
tree
result
=
NULL_TREE
;
int
extern_p
=
0
;
if
(
fn
)
{
for
(
fn
=
get_first_fn
(
fn
);
fn
;
fn
=
DECL_CHAIN
(
fn
))
if
(
TREE_CODE
(
fn
)
==
TEMPLATE_DECL
)
if
(
decls_match
(
fn
,
decl
)
&&
DECL_DEFER_OUTPUT
(
fn
))
{
result
=
fn
;
break
;
}
else
if
(
TREE_CODE
(
fn
)
==
TEMPLATE_DECL
)
{
int
ntparms
=
TREE_VEC_LENGTH
(
DECL_TEMPLATE_PARMS
(
fn
));
tree
*
targs
=
(
tree
*
)
malloc
(
sizeof
(
tree
)
*
ntparms
);
...
...
@@ -2518,28 +2543,41 @@ do_function_instantiation (declspecs, declarator, storage)
}
}
if
(
!
result
)
cp_error
(
"no matching template for `%D' found"
,
decl
);
{
cp_error
(
"no matching template for `%D' found"
,
decl
);
return
;
}
if
(
flag_external_templates
)
return
;
SET_DECL_EXPLICIT_INSTANTIATION
(
result
);
TREE_PUBLIC
(
result
)
=
1
;
if
(
storage
==
NULL_TREE
)
{
DECL_INTERFACE_KNOWN
(
result
)
=
1
;
DECL_EXTERNAL
(
result
)
=
0
;
TREE_STATIC
(
result
)
=
1
;
}
else
if
(
storage
==
ridpointers
[(
int
)
RID_EXTERN
])
;
else
if
(
storage
==
ridpointers
[(
int
)
RID_EXTERN
])
extern_p
=
1
;
else
cp_error
(
"storage class `%D' applied to template instantiation"
,
storage
);
mark_function_instantiated
(
result
,
extern_p
);
}
void
mark_class_instantiated
(
t
,
extern_p
)
tree
t
;
int
extern_p
;
{
SET_CLASSTYPE_EXPLICIT_INSTANTIATION
(
t
);
SET_CLASSTYPE_INTERFACE_KNOWN
(
t
);
CLASSTYPE_INTERFACE_ONLY
(
t
)
=
extern_p
;
CLASSTYPE_VTABLE_NEEDS_WRITING
(
t
)
=
!
extern_p
;
TYPE_DECL_SUPPRESS_DEBUG
(
TYPE_NAME
(
t
))
=
extern_p
;
if
(
!
extern_p
)
{
CLASSTYPE_DEBUG_REQUESTED
(
t
)
=
1
;
rest_of_type_compilation
(
t
,
1
);
}
}
void
do_type_instantiation
(
name
,
storage
)
tree
name
,
storage
;
{
...
...
@@ -2578,18 +2616,7 @@ do_type_instantiation (name, storage)
}
if
(
!
CLASSTYPE_TEMPLATE_SPECIALIZATION
(
t
))
{
SET_CLASSTYPE_EXPLICIT_INSTANTIATION
(
t
);
SET_CLASSTYPE_INTERFACE_KNOWN
(
t
);
CLASSTYPE_INTERFACE_ONLY
(
t
)
=
extern_p
;
CLASSTYPE_VTABLE_NEEDS_WRITING
(
t
)
=
!
extern_p
;
TYPE_DECL_SUPPRESS_DEBUG
(
TYPE_NAME
(
t
))
=
extern_p
;
if
(
!
extern_p
)
{
CLASSTYPE_DEBUG_REQUESTED
(
t
)
=
1
;
rest_of_type_compilation
(
t
,
1
);
}
}
mark_class_instantiated
(
t
,
extern_p
);
{
tree
tmp
;
...
...
@@ -2615,8 +2642,7 @@ do_type_instantiation (name, storage)
if
(
!
extern_p
)
{
DECL_INTERFACE_KNOWN
(
tmp
)
=
1
;
DECL_EXTERNAL
(
tmp
)
=
0
;
TREE_STATIC
(
tmp
)
=
1
;
DECL_NOT_REALLY_EXTERN
(
tmp
)
=
1
;
}
}
...
...
gcc/cp/repo.c
0 → 100644
View file @
faae18ab
/* Code to maintain a C++ template repository.
Copyright (C) 1995 Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com)
This file is part of GNU CC.
GNU CC 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.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* My strategy here is as follows:
Everything should be emitted in a translation unit where it is used.
The results of the automatic process should be easily reproducible with
explicit code.
I'm thinking of compiling with -frepo, running a Perl script to update
files, and then being able to rebuild everything with -fno-implicit.
Full automation can come later. */
#include <stdio.h>
#include "tree.h"
#include "cp-tree.h"
#include "input.h"
extern
char
*
rindex
();
static
tree
pending_repo
;
static
char
repo_name
[
1024
];
static
FILE
*
repo_file
;
extern
int
flag_use_repository
;
extern
int
errorcount
,
sorrycount
;
static
int
repo_changed
;
#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
/* Record the flags used to compile this translation unit. */
void
repo_compile_flags
(
argc
,
argv
)
int
argc
;
char
**
argv
;
{
}
/* If this template has not been seen before, add a note to the repository
saying where the declaration was. This may be used to find the
definition at link time. */
void
repo_template_declared
(
t
)
tree
t
;
{}
/* Note where the definition of a template lives so that instantiations can
be generated later. */
void
repo_template_defined
(
t
)
tree
t
;
{}
/* Note where the definition of a class lives to that template
instantiations can use it. */
void
repo_class_defined
(
t
)
tree
t
;
{}
/* Note that a template has been used. If we can see the definition, offer
to emit it. */
void
repo_template_used
(
t
)
tree
t
;
{
tree
id
;
if
(
!
flag_use_repository
)
return
;
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
t
))
==
't'
)
{
id
=
DECL_ASSEMBLER_NAME
(
TYPE_MAIN_DECL
(
t
));
if
(
IDENTIFIER_REPO_CHOSEN
(
id
))
mark_class_instantiated
(
t
,
0
);
}
else
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
t
))
==
'd'
)
{
id
=
DECL_ASSEMBLER_NAME
(
t
);
if
(
IDENTIFIER_REPO_CHOSEN
(
id
))
mark_function_instantiated
(
t
,
0
);
}
else
my_friendly_abort
(
1
);
if
(
!
IDENTIFIER_REPO_USED
(
id
))
{
repo_changed
=
1
;
IDENTIFIER_REPO_USED
(
id
)
=
1
;
}
pending_repo
=
perm_tree_cons
(
NULL_TREE
,
t
,
pending_repo
);
}
/* Note that the vtable for a class has been used, and offer to emit it. */
void
repo_vtable_used
(
t
)
tree
t
;
{
if
(
!
flag_use_repository
)
return
;
pending_repo
=
perm_tree_cons
(
NULL_TREE
,
t
,
pending_repo
);
}
/* Note that an inline with external linkage has been used, and offer to
emit it. */
void
repo_inline_used
(
fn
)
tree
fn
;
{
if
(
!
flag_use_repository
)
return
;
/* Member functions of polymorphic classes go with their vtables. */
if
(
DECL_FUNCTION_MEMBER_P
(
fn
)
&&
TYPE_VIRTUAL_P
(
DECL_CLASS_CONTEXT
(
fn
)))
{
repo_vtable_used
(
DECL_CLASS_CONTEXT
(
fn
));
return
;
}
pending_repo
=
perm_tree_cons
(
NULL_TREE
,
fn
,
pending_repo
);
}
/* Note that a particular typeinfo node has been used, and offer to
emit it. */
void
repo_tinfo_used
(
ti
)
tree
ti
;
{
}
static
void
open_repo_file
(
filename
)
char
*
filename
;
{
register
char
*
p
,
*
q
;
char
*
file
=
filename
;
char
*
s
=
rindex
(
file
,
'/'
);
if
(
s
==
NULL
)
s
=
file
;
else
++
s
;
for
(
p
=
repo_name
,
q
=
file
;
q
<
s
;
)
*
p
++
=
*
q
++
;
*
p
++
=
'.'
;
strcpy
(
p
,
q
);
strcat
(
p
,
".repo"
);
repo_file
=
fopen
(
repo_name
,
"r"
);
}
void
init_repo
(
filename
)
char
*
filename
;
{
char
buf
[
1024
];
if
(
!
flag_use_repository
)
return
;
open_repo_file
(
filename
);
if
(
repo_file
==
0
)
return
;
while
(
fgets
(
buf
,
1024
,
repo_file
))
{
int
len
=
strlen
(
buf
)
-
1
;
if
(
buf
[
len
]
!=
'\n'
)
error
(
"repository info line too long in %s"
,
repo_name
);
buf
[
len
]
=
'\0'
;
switch
(
buf
[
0
])
{
case
'A'
:
case
'M'
:
break
;
case
'C'
:
case
'O'
:
{
tree
id
=
get_identifier
(
&
buf
[
2
]);
IDENTIFIER_REPO_USED
(
id
)
=
1
;
if
(
buf
[
0
]
==
'C'
)
IDENTIFIER_REPO_CHOSEN
(
id
)
=
1
;
}
break
;
default
:
error
(
"mysterious repository information in %s"
,
repo_name
);
}
}
}
static
void
reopen_repo_file_for_write
()
{
if
(
repo_file
)
fclose
(
repo_file
);
repo_file
=
fopen
(
repo_name
,
"w"
);
if
(
repo_file
==
0
)
{
error
(
"man't create repository information file `%s'"
,
repo_name
);
flag_use_repository
=
0
;
}
}
/* Emit any pending repos. */
void
finish_repo
()
{
tree
t
;
int
changed
=
0
;
if
(
!
flag_use_repository
)
return
;
/* Do we have to write out a new info file? */
if
(
!
repo_changed
||
errorcount
||
sorrycount
)
goto
out
;
reopen_repo_file_for_write
();
if
(
repo_file
==
0
)
goto
out
;
for
(
t
=
pending_repo
;
t
;
t
=
TREE_CHAIN
(
t
))
{
tree
val
=
TREE_VALUE
(
t
);
char
type
;
if
(
TREE_CODE_CLASS
(
TREE_CODE
(
val
))
==
't'
)
val
=
TYPE_MAIN_DECL
(
val
);
val
=
DECL_ASSEMBLER_NAME
(
val
);
if
(
!
IDENTIFIER_REPO_USED
(
val
))
continue
;
IDENTIFIER_REPO_USED
(
val
)
=
0
;
type
=
IDENTIFIER_REPO_CHOSEN
(
val
)
?
'C'
:
'O'
;
fprintf
(
repo_file
,
"%c %s
\n
"
,
type
,
IDENTIFIER_POINTER
(
val
));
}
out
:
if
(
repo_file
)
fclose
(
repo_file
);
}
gcc/cp/search.c
View file @
faae18ab
...
...
@@ -793,6 +793,10 @@ compute_access (basetype_path, field)
}
#endif
/* We don't currently support access control on nested types. */
if
(
TREE_CODE
(
field
)
==
TYPE_DECL
)
return
access_public
;
previous_scope
=
current_scope
();
context
=
DECL_CLASS_CONTEXT
(
field
);
...
...
gcc/cp/typeck.c
View file @
faae18ab
...
...
@@ -2880,7 +2880,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
tree
build_type
=
0
;
/* Nonzero means after finally constructing the expression
give it this type. Otherwise, give it type RESULT_TYPE
. */
convert it to this type
. */
tree
final_type
=
0
;
/* Nonzero if this is an operation like MIN or MAX which can
...
...
@@ -3155,34 +3155,39 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
if
(
result_type
==
NULL_TREE
)
result_type
=
ptr_type_node
;
}
else
if
(
code0
==
POINTER_TYPE
&&
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
integer_zerop
(
op1
))
op1
=
null_pointer_node
;
result_type
=
type0
;
else
if
(
code1
==
POINTER_TYPE
&&
TREE_CODE
(
op0
)
==
INTEGER_CST
&&
integer_zerop
(
op0
))
op0
=
null_pointer_node
;
result_type
=
type1
;
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
INTEGER_TYPE
)
{
result_type
=
type0
;
error
(
"ANSI C++ forbids comparison between pointer and integer"
);
op1
=
convert
(
TREE_TYPE
(
op0
),
op1
);
}
else
if
(
code0
==
INTEGER_TYPE
&&
code1
==
POINTER_TYPE
)
{
result_type
=
type1
;
error
(
"ANSI C++ forbids comparison between pointer and integer"
);
op0
=
convert
(
TREE_TYPE
(
op1
),
op0
);
}
else
if
(
TYPE_PTRMEMFUNC_P
(
type0
)
&&
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
integer_zerop
(
op1
))
{
op0
=
build_component_ref
(
op0
,
index_identifier
,
0
,
0
);
op1
=
integer_zero_node
;
result_type
=
TREE_TYPE
(
op0
);
}
else
if
(
TYPE_PTRMEMFUNC_P
(
type1
)
&&
TREE_CODE
(
op0
)
==
INTEGER_CST
&&
integer_zerop
(
op0
))
{
op0
=
build_component_ref
(
op1
,
index_identifier
,
0
,
0
);
op1
=
integer_zero_node
;
result_type
=
TREE_TYPE
(
op0
);
}
else
if
(
TYPE_PTRMEMFUNC_P
(
type0
)
&&
TYPE_PTRMEMFUNC_P
(
type1
)
&&
(
TYPE_PTRMEMFUNC_FN_TYPE
(
type0
)
...
...
@@ -3258,11 +3263,6 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
{
return
build_binary_op
(
code
,
op1
,
op0
,
1
);
}
type0
=
TREE_TYPE
(
op0
);
type1
=
TREE_TYPE
(
op1
);
if
(
result_type
==
NULL_TREE
)
result_type
=
type0
;
break
;
case
MAX_EXPR
:
...
...
@@ -3272,29 +3272,15 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
shorten
=
1
;
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
POINTER_TYPE
)
{
if
(
!
comp_target_types
(
type0
,
type1
,
1
))
if
(
comp_target_types
(
type0
,
type1
,
1
))
result_type
=
common_type
(
type0
,
type1
);
else
{
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
result_type
=
ptr_type_node
;
}
#if 0
else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
!= (TYPE_SIZE (TREE_TYPE (type1)) != 0))
cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
TYPE_SIZE (TREE_TYPE (type0)) == 0 ? "in" : "",
TYPE_SIZE (TREE_TYPE (type1)) == 0 ? "in" : "",
type0, type1);
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
#endif
else
result_type
=
common_type
(
type0
,
type1
);
}
if
(
result_type
==
NULL_TREE
)
result_type
=
type0
;
break
;
case
LE_EXPR
:
...
...
@@ -3307,50 +3293,37 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
short_compare
=
1
;
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
POINTER_TYPE
)
{
if
(
!
comp_target_types
(
type0
,
type1
,
1
))
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
#if 0
else if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
!= (TYPE_SIZE (TREE_TYPE (type1)) != 0))
cp_pedwarn ("comparison of %scomplete and %scomplete pointers",
TYPE_SIZE (TREE_TYPE (type0)) == 0 ? "in" : "",
TYPE_SIZE (TREE_TYPE (type1)) == 0 ? "in" : "",
type0, type1);
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C++ forbids ordered comparisons of pointers to functions");
#endif
else
if
(
comp_target_types
(
type0
,
type1
,
1
))
result_type
=
common_type
(
type0
,
type1
);
else
{
cp_pedwarn
(
"comparison of distinct pointer types `%T' and `%T' lacks a cast"
,
type0
,
type1
);
result_type
=
ptr_type_node
;
}
}
else
if
(
code0
==
POINTER_TYPE
&&
TREE_CODE
(
op1
)
==
INTEGER_CST
&&
integer_zerop
(
op1
))
op1
=
null_pointer_node
;
result_type
=
type0
;
else
if
(
code1
==
POINTER_TYPE
&&
TREE_CODE
(
op0
)
==
INTEGER_CST
&&
integer_zerop
(
op0
))
op0
=
null_pointer_node
;
result_type
=
type1
;
else
if
(
code0
==
POINTER_TYPE
&&
code1
==
INTEGER_TYPE
)
{
result_type
=
type0
;
if
(
pedantic
)
pedwarn
(
"ANSI C++ forbids comparison between pointer and integer"
);
else
if
(
!
flag_traditional
)
warning
(
"comparison between pointer and integer"
);
op1
=
convert
(
TREE_TYPE
(
op0
),
op1
);
}
else
if
(
code0
==
INTEGER_TYPE
&&
code1
==
POINTER_TYPE
)
{
result_type
=
type1
;
if
(
pedantic
)
pedwarn
(
"ANSI C++ forbids comparison between pointer and integer"
);
else
if
(
!
flag_traditional
)
warning
(
"comparison between pointer and integer"
);
op0
=
convert
(
TREE_TYPE
(
op1
),
op0
);
}
type0
=
TREE_TYPE
(
op0
);
type1
=
TREE_TYPE
(
op1
);
if
(
result_type
==
NULL_TREE
)
result_type
=
type0
;
break
;
}
...
...
@@ -3496,26 +3469,38 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
int
op0_signed
=
!
TREE_UNSIGNED
(
TREE_TYPE
(
orig_op0
));
int
op1_signed
=
!
TREE_UNSIGNED
(
TREE_TYPE
(
orig_op1
));
tree
comp_type
=
TREE_TYPE
(
op0
);
int
unsignedp0
,
unsignedp1
;
tree
primop0
=
get_narrower
(
op0
,
&
unsignedp0
);
tree
primop1
=
get_narrower
(
op1
,
&
unsignedp1
);
/* Give warnings for comparisons between signed and unsigned
quantities that may fail. Do not warn if the signed quantity
is an unsuffixed integer literal (or some static constant
expression involving such literals) and it is positive.
Do not warn if the comparison is being done in a signed type,
since the signed type will only be chosen if it can represent
all the values of the unsigned type. */
quantities that may fail. */
/* Do the checking based on the original operand trees, so that
casts will be considered, but default promotions won't be. */
if
(
TREE_UNSIGNED
(
comp_type
)
&&
((
op0_signed
&&
(
TREE_CODE
(
orig_op0
)
!=
INTEGER_CST
||
tree_int_cst_sgn
(
orig_op0
)
==
-
1
))
||
(
op1_signed
&&
(
TREE_CODE
(
orig_op1
)
!=
INTEGER_CST
||
tree_int_cst_sgn
(
orig_op1
)
==
-
1
))))
/* Do not warn if the comparison is being done in a signed type,
since the signed type will only be chosen if it can represent
all the values of the unsigned type. */
if
(
!
TREE_UNSIGNED
(
result_type
))
/* OK */
;
/* Do not warn if the signed quantity is an unsuffixed
integer literal (or some static constant expression
involving such literals) and it is non-negative. */
else
if
((
op0_signed
&&
TREE_CODE
(
orig_op0
)
==
INTEGER_CST
&&
tree_int_cst_sgn
(
orig_op0
)
>=
0
)
||
(
op1_signed
&&
TREE_CODE
(
orig_op1
)
==
INTEGER_CST
&&
tree_int_cst_sgn
(
orig_op1
)
>=
0
))
/* OK */
;
/* Do not warn if the comparison is an equality operation,
the unsigned quantity is an integral constant and it does
not use the most significant bit of result_type. */
else
if
((
resultcode
==
EQ_EXPR
||
resultcode
==
NE_EXPR
)
&&
((
op0_signed
&&
TREE_CODE
(
orig_op1
)
==
INTEGER_CST
&&
int_fits_type_p
(
orig_op1
,
signed_type
(
result_type
))
||
(
op1_signed
&&
TREE_CODE
(
orig_op0
)
==
INTEGER_CST
&&
int_fits_type_p
(
orig_op0
,
signed_type
(
result_type
))))))
/* OK */
;
else
warning
(
"comparison between signed and unsigned"
);
/* Warn if two unsigned values are being compared in a size
...
...
@@ -3526,8 +3511,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
have all bits set that are set in the ~ operand when it is
extended. */
else
if
(
TREE_CODE
(
primop0
)
==
BIT_NOT_EXPR
^
TREE_CODE
(
primop1
)
==
BIT_NOT_EXPR
)
if
(
TREE_CODE
(
primop0
)
==
BIT_NOT_EXPR
^
TREE_CODE
(
primop1
)
==
BIT_NOT_EXPR
)
{
if
(
TREE_CODE
(
primop0
)
==
BIT_NOT_EXPR
)
primop0
=
get_narrower
(
TREE_OPERAND
(
op0
,
0
),
&
unsignedp0
);
...
...
@@ -3556,7 +3541,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
}
bits
=
TYPE_PRECISION
(
TREE_TYPE
(
primop
));
if
(
bits
<
TYPE_PRECISION
(
comp
_type
)
if
(
bits
<
TYPE_PRECISION
(
result
_type
)
&&
bits
<
HOST_BITS_PER_LONG
&&
unsignedp
)
{
mask
=
(
~
(
HOST_WIDE_INT
)
0
)
<<
bits
;
...
...
@@ -3566,9 +3551,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
}
else
if
(
unsignedp0
&&
unsignedp1
&&
(
TYPE_PRECISION
(
TREE_TYPE
(
primop0
))
<
TYPE_PRECISION
(
comp
_type
))
<
TYPE_PRECISION
(
result
_type
))
&&
(
TYPE_PRECISION
(
TREE_TYPE
(
primop1
))
<
TYPE_PRECISION
(
comp
_type
)))
<
TYPE_PRECISION
(
result
_type
)))
warning
(
"comparison of promoted ~unsigned with unsigned"
);
}
}
...
...
@@ -3582,7 +3567,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
if
(
!
result_type
)
{
binary_op_error
(
error_code
);
cp_error
(
"invalid operands `%T' and `%T' to binary `%O'"
,
TREE_TYPE
(
orig_op0
),
TREE_TYPE
(
orig_op1
),
error_code
);
return
error_mark_node
;
}
...
...
@@ -4467,7 +4453,7 @@ mark_addressable (exp)
be non-zero in the case of processing a default function.
The second may be non-zero in the case of a template function. */
x
=
DECL_MAIN_VARIANT
(
x
);
if
((
DECL_INLINE
(
x
)
||
DECL_PENDING_INLINE_INFO
(
x
))
if
((
DECL_
THIS_
INLINE
(
x
)
||
DECL_PENDING_INLINE_INFO
(
x
))
&&
(
DECL_CONTEXT
(
x
)
==
NULL_TREE
||
TREE_CODE_CLASS
(
TREE_CODE
(
DECL_CONTEXT
(
x
)))
!=
't'
||
!
CLASSTYPE_INTERFACE_ONLY
(
DECL_CONTEXT
(
x
))))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment