summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/xlint/Makefile5
-rw-r--r--usr.bin/xlint/PSD.doc/Makefile11
-rw-r--r--usr.bin/xlint/PSD.doc/lint.ms1101
-rw-r--r--usr.bin/xlint/README30
-rw-r--r--usr.bin/xlint/lint1/Makefile16
-rw-r--r--usr.bin/xlint/lint1/cgram.y1726
-rw-r--r--usr.bin/xlint/lint1/decl.c3140
-rw-r--r--usr.bin/xlint/lint1/emit.c224
-rw-r--r--usr.bin/xlint/lint1/emit1.c589
-rw-r--r--usr.bin/xlint/lint1/err.c547
-rw-r--r--usr.bin/xlint/lint1/externs.h56
-rw-r--r--usr.bin/xlint/lint1/externs1.h287
-rw-r--r--usr.bin/xlint/lint1/func.c1287
-rw-r--r--usr.bin/xlint/lint1/init.c486
-rw-r--r--usr.bin/xlint/lint1/lint.h131
-rw-r--r--usr.bin/xlint/lint1/lint1.h399
-rw-r--r--usr.bin/xlint/lint1/main1.c170
-rw-r--r--usr.bin/xlint/lint1/mem.c77
-rw-r--r--usr.bin/xlint/lint1/mem1.c328
-rw-r--r--usr.bin/xlint/lint1/op.h123
-rw-r--r--usr.bin/xlint/lint1/param.h88
-rw-r--r--usr.bin/xlint/lint1/scan.l1484
-rw-r--r--usr.bin/xlint/lint1/tree.c3966
-rw-r--r--usr.bin/xlint/lint2/Makefile14
-rw-r--r--usr.bin/xlint/lint2/chk.c1412
-rw-r--r--usr.bin/xlint/lint2/emit2.c235
-rw-r--r--usr.bin/xlint/lint2/externs2.h88
-rw-r--r--usr.bin/xlint/lint2/hash.c117
-rw-r--r--usr.bin/xlint/lint2/lint2.h178
-rw-r--r--usr.bin/xlint/lint2/main2.c180
-rw-r--r--usr.bin/xlint/lint2/mem2.c93
-rw-r--r--usr.bin/xlint/lint2/msg.c135
-rw-r--r--usr.bin/xlint/lint2/read.c1132
-rw-r--r--usr.bin/xlint/llib/Makefile21
-rw-r--r--usr.bin/xlint/llib/llib-lposix410
-rw-r--r--usr.bin/xlint/llib/llib-lstdc254
-rw-r--r--usr.bin/xlint/xlint/Makefile19
-rw-r--r--usr.bin/xlint/xlint/lint.1513
-rw-r--r--usr.bin/xlint/xlint/pathnames.h39
-rw-r--r--usr.bin/xlint/xlint/xlint.c763
40 files changed, 0 insertions, 21874 deletions
diff --git a/usr.bin/xlint/Makefile b/usr.bin/xlint/Makefile
deleted file mode 100644
index 78522e050b1..00000000000
--- a/usr.bin/xlint/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# $OpenBSD: Makefile,v 1.3 1997/09/21 11:52:12 deraadt Exp $
-
-SUBDIR= lint1 lint2 xlint llib
-
-.include <bsd.subdir.mk>
diff --git a/usr.bin/xlint/PSD.doc/Makefile b/usr.bin/xlint/PSD.doc/Makefile
deleted file mode 100644
index 69fda41be1c..00000000000
--- a/usr.bin/xlint/PSD.doc/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# OpenBSD$
-
-DIR= psd/09.lint
-SRCS= lint.ms
-MACROS= -ms
-REFER= refer -e -p /usr/doc/run/Ind
-
-paper.${PRINTER}: ${SRCS}
- ${REFER} ${SRCS} | ${ROFF} > ${.TARGET}
-
-.include <bsd.doc.mk>
diff --git a/usr.bin/xlint/PSD.doc/lint.ms b/usr.bin/xlint/PSD.doc/lint.ms
deleted file mode 100644
index 79f59bf4cff..00000000000
--- a/usr.bin/xlint/PSD.doc/lint.ms
+++ /dev/null
@@ -1,1101 +0,0 @@
-.\" $OpenBSD: lint.ms,v 1.1 2003/06/26 16:30:10 mickey Exp $
-.\"
-.\" Copyright (C) Caldera International Inc. 2001-2002.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code and documentation must retain the above
-.\" copyright notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed or owned by Caldera
-.\" International, Inc.
-.\" 4. Neither the name of Caldera International, Inc. nor the names of other
-.\" contributors may be used to endorse or promote products derived from
-.\" this software without specific prior written permission.
-.\"
-.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
-.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
-.\" INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" @(#)lint.ms 6.2 (Berkeley) 4/17/91
-.\"
-.EH 'PS1:9-%''Lint, a C Program Checker'
-.OH 'Lint, a C Program Checker''PS1:9-%'
-.\".RP
-.ND "July 26, 1978"
-.OK
-.\"Program Portability
-.\"Strong Type Checking
-.TL
-Lint, a C Program Checker
-.AU "MH 2C-559" 3968
-S. C. Johnson
-.AI
-.MH
-.AB
-.PP
-.I Lint
-is a command which examines C source programs,
-detecting
-a number of bugs and obscurities.
-It enforces the type rules of C more strictly than
-the C compilers.
-It may also be used to enforce a number of portability
-restrictions involved in moving
-programs between different machines and/or operating systems.
-Another option detects a number of wasteful, or error prone, constructions
-which nevertheless are, strictly speaking, legal.
-.PP
-.I Lint
-accepts multiple input files and library specifications, and checks them for consistency.
-.PP
-The separation of function between
-.I lint
-and the C compilers has both historical and practical
-rationale.
-The compilers turn C programs into executable files rapidly
-and efficiently.
-This is possible in part because the
-compilers do not do sophisticated
-type checking, especially between
-separately compiled programs.
-.I Lint
-takes a more global, leisurely view of the program,
-looking much more carefully at the compatibilities.
-.PP
-This document discusses the use of
-.I lint ,
-gives an overview of the implementation, and gives some hints on the
-writing of machine independent C code.
-.AE
-.CS 10 2 12 0 0 5
-.SH
-Introduction and Usage
-.PP
-Suppose there are two C
-.[
-Kernighan Ritchie Programming Prentice 1978
-.]
-source files,
-.I file1. c
-and
-.I file2.c ,
-which are ordinarily compiled and loaded together.
-Then the command
-.DS
-lint file1.c file2.c
-.DE
-produces messages describing inconsistencies and inefficiencies
-in the programs.
-The program enforces the typing rules of C
-more strictly than the C compilers
-(for both historical and practical reasons)
-enforce them.
-The command
-.DS
-lint \-p file1.c file2.c
-.DE
-will produce, in addition to the above messages, additional messages
-which relate to the portability of the programs to other operating
-systems and machines.
-Replacing the
-.B \-p
-by
-.B \-h
-will produce messages about various error-prone or wasteful constructions
-which, strictly speaking, are not bugs.
-Saying
-.B \-hp
-gets the whole works.
-.PP
-The next several sections describe the major messages;
-the document closes with sections
-discussing the implementation and giving suggestions
-for writing portable C.
-An appendix gives a summary of the
-.I lint
-options.
-.SH
-A Word About Philosophy
-.PP
-Many of the facts which
-.I lint
-needs may be impossible to
-discover.
-For example, whether a given function in a program ever gets called
-may depend on the input data.
-Deciding whether
-.I exit
-is ever called is equivalent to solving the famous ``halting problem,'' known to be
-recursively undecidable.
-.PP
-Thus, most of the
-.I lint
-algorithms are a compromise.
-If a function is never mentioned, it can never be called.
-If a function is mentioned,
-.I lint
-assumes it can be called; this is not necessarily so, but in practice is quite reasonable.
-.PP
-.I Lint
-tries to give information with a high degree of relevance.
-Messages of the form ``\fIxxx\fR might be a bug''
-are easy to generate, but are acceptable only in proportion
-to the fraction of real bugs they uncover.
-If this fraction of real bugs is too small, the messages lose their credibility
-and serve merely to clutter up the output,
-obscuring the more important messages.
-.PP
-Keeping these issues in mind, we now consider in more detail
-the classes of messages which
-.I lint
-produces.
-.SH
-Unused Variables and Functions
-.PP
-As sets of programs evolve and develop,
-previously used variables and arguments to
-functions may become unused;
-it is not uncommon for external variables, or even entire
-functions, to become unnecessary, and yet
-not be removed from the source.
-These ``errors of commission'' rarely cause working programs to fail, but they are a source
-of inefficiency, and make programs harder to understand
-and change.
-Moreover, information about such unused variables and functions can occasionally
-serve to discover bugs; if a function does a necessary job, and
-is never called, something is wrong!
-.PP
-.I Lint
-complains about variables and functions which are defined but not otherwise
-mentioned.
-An exception is variables which are declared through explicit
-.B extern
-statements but are never referenced; thus the statement
-.DS
-extern float sin(\|);
-.DE
-will evoke no comment if
-.I sin
-is never used.
-Note that this agrees with the semantics of the C compiler.
-In some cases, these unused external declarations might be of some interest; they
-can be discovered by adding the
-.B \-x
-flag to the
-.I lint
-invocation.
-.PP
-Certain styles of programming
-require many functions to be written with similar interfaces;
-frequently, some of the arguments may be unused
-in many of the calls.
-The
-.B \-v
-option is available to suppress the printing of
-complaints about unused arguments.
-When
-.B \-v
-is in effect, no messages are produced about unused
-arguments except for those
-arguments which are unused and also declared as
-register arguments; this can be considered
-an active (and preventable) waste of the register
-resources of the machine.
-.PP
-There is one case where information about unused, or
-undefined, variables is more distracting
-than helpful.
-This is when
-.I lint
-is applied to some, but not all, files out of a collection
-which are to be loaded together.
-In this case, many of the functions and variables defined
-may not be used, and, conversely,
-many functions and variables defined elsewhere may be used.
-The
-.B \-u
-flag may be used to suppress the spurious messages which might otherwise appear.
-.SH
-Set/Used Information
-.PP
-.I Lint
-attempts to detect cases where a variable is used before it is set.
-This is very difficult to do well;
-many algorithms take a good deal of time and space,
-and still produce messages about perfectly valid programs.
-.I Lint
-detects local variables (automatic and register storage classes)
-whose first use appears physically earlier in the input file than the first assignment to the variable.
-It assumes that taking the address of a variable constitutes a ``use,'' since the actual use
-may occur at any later time, in a data dependent fashion.
-.PP
-The restriction to the physical appearance of variables in the file makes the
-algorithm very simple and quick to implement,
-since the true flow of control need not be discovered.
-It does mean that
-.I lint
-can complain about some programs which are legal,
-but these programs would probably be considered bad on stylistic grounds (e.g. might
-contain at least two \fBgoto\fR's).
-Because static and external variables are initialized to 0,
-no meaningful information can be discovered about their uses.
-The algorithm deals correctly, however, with initialized automatic variables, and variables
-which are used in the expression which first sets them.
-.PP
-The set/used information also permits recognition of those local variables which are set
-and never used; these form a frequent source of inefficiencies, and may also be symptomatic of bugs.
-.SH
-Flow of Control
-.PP
-.I Lint
-attempts to detect unreachable portions of the programs which it processes.
-It will complain about unlabeled statements immediately following
-\fBgoto\fR, \fBbreak\fR, \fBcontinue\fR, or \fBreturn\fR statements.
-An attempt is made to detect loops which can never be left at the bottom, detecting the
-special cases
-\fBwhile\fR( 1 ) and \fBfor\fR(;;) as infinite loops.
-.I Lint
-also complains about loops which cannot be entered at the top;
-some valid programs may have such loops, but at best they are bad style,
-at worst bugs.
-.PP
-.I Lint
-has an important area of blindness in the flow of control algorithm:
-it has no way of detecting functions which are called and never return.
-Thus, a call to
-.I exit
-may cause unreachable code which
-.I lint
-does not detect; the most serious effects of this are in the
-determination of returned function values (see the next section).
-.PP
-One form of unreachable statement is not usually complained about by
-.I lint;
-a
-.B break
-statement that cannot be reached causes no message.
-Programs generated by
-.I yacc ,
-.[
-Johnson Yacc 1975
-.]
-and especially
-.I lex ,
-.[
-Lesk Lex
-.]
-may have literally hundreds of unreachable
-.B break
-statements.
-The
-.B \-O
-flag in the C compiler will often eliminate the resulting object code inefficiency.
-Thus, these unreached statements are of little importance,
-there is typically nothing the user can do about them, and the
-resulting messages would clutter up the
-.I lint
-output.
-If these messages are desired,
-.I lint
-can be invoked with the
-.B \-b
-option.
-.SH
-Function Values
-.PP
-Sometimes functions return values which are never used;
-sometimes programs incorrectly use function ``values''
-which have never been returned.
-.I Lint
-addresses this problem in a number of ways.
-.PP
-Locally, within a function definition,
-the appearance of both
-.DS
-return( \fIexpr\fR );
-.DE
-and
-.DS
-return ;
-.DE
-statements is cause for alarm;
-.I lint
-will give the message
-.DS
-function \fIname\fR contains return(e) and return
-.DE
-The most serious difficulty with this is detecting when a function return is implied
-by flow of control reaching the end of the function.
-This can be seen with a simple example:
-.DS
-.ta .5i 1i 1.5i
-\fRf ( a ) {
- if ( a ) return ( 3 );
- g (\|);
- }
-.DE
-Notice that, if \fIa\fR tests false, \fIf\fR will call \fIg\fR and then return
-with no defined return value; this will trigger a complaint from
-.I lint .
-If \fIg\fR, like \fIexit\fR, never returns,
-the message will still be produced when in fact nothing is wrong.
-.PP
-In practice, some potentially serious bugs have been discovered by this feature;
-it also accounts for a substantial fraction of the ``noise'' messages produced
-by
-.I lint .
-.PP
-On a global scale,
-.I lint
-detects cases where a function returns a value, but this value is sometimes,
-or always, unused.
-When the value is always unused, it may constitute an inefficiency in the function definition.
-When the value is sometimes unused, it may represent bad style (e.g., not testing for
-error conditions).
-.PP
-The dual problem, using a function value when the function does not return one,
-is also detected.
-This is a serious problem.
-Amazingly, this bug has been observed on a couple of occasions
-in ``working'' programs; the desired function value just happened to have been computed
-in the function return register!
-.SH
-Type Checking
-.PP
-.I Lint
-enforces the type checking rules of C more strictly than the compilers do.
-The additional checking is in four major areas:
-across certain binary operators and implied assignments,
-at the structure selection operators,
-between the definition and uses of functions,
-and in the use of enumerations.
-.PP
-There are a number of operators which have an implied balancing between types of the operands.
-The assignment, conditional ( ?\|: ), and relational operators
-have this property; the argument
-of a \fBreturn\fR statement,
-and expressions used in initialization also suffer similar conversions.
-In these operations,
-\fBchar\fR, \fBshort\fR, \fBint\fR, \fBlong\fR, \fBunsigned\fR, \fBfloat\fR, and \fBdouble\fR types may be freely intermixed.
-The types of pointers must agree exactly,
-except that arrays of \fIx\fR's can, of course, be intermixed with pointers to \fIx\fR's.
-.PP
-The type checking rules also require that, in structure references, the
-left operand of the \(em> be a pointer to structure, the left operand of the \fB.\fR
-be a structure, and the right operand of these operators be a member
-of the structure implied by the left operand.
-Similar checking is done for references to unions.
-.PP
-Strict rules apply to function argument and return value
-matching.
-The types \fBfloat\fR and \fBdouble\fR may be freely matched,
-as may the types \fBchar\fR, \fBshort\fR, \fBint\fR, and \fBunsigned\fR.
-Also, pointers can be matched with the associated arrays.
-Aside from this, all actual arguments must agree in type with their declared counterparts.
-.PP
-With enumerations, checks are made that enumeration variables or members are not mixed
-with other types, or other enumerations,
-and that the only operations applied are =, initialization, ==, !=, and function arguments and return values.
-.SH
-Type Casts
-.PP
-The type cast feature in C was introduced largely as an aid
-to producing more portable programs.
-Consider the assignment
-.DS
-p = 1 ;
-.DE
-where
-.I p
-is a character pointer.
-.I Lint
-will quite rightly complain.
-Now, consider the assignment
-.DS
-p = (char \(**)1 ;
-.DE
-in which a cast has been used to
-convert the integer to a character pointer.
-The programmer obviously had a strong motivation
-for doing this, and has clearly signaled his intentions.
-It seems harsh for
-.I lint
-to continue to complain about this.
-On the other hand, if this code is moved to another
-machine, such code should be looked at carefully.
-The
-.B \-c
-flag controls the printing of comments about casts.
-When
-.B \-c
-is in effect, casts are treated as though they were assignments
-subject to complaint; otherwise, all legal casts are passed without comment,
-no matter how strange the type mixing seems to be.
-.SH
-Nonportable Character Use
-.PP
-On the PDP-11, characters are signed quantities, with a range
-from \-128 to 127.
-On most of the other C implementations, characters take on only positive
-values.
-Thus,
-.I lint
-will flag certain comparisons and assignments as being
-illegal or nonportable.
-For example, the fragment
-.DS
-char c;
- ...
-if( (c = getchar(\|)) < 0 ) ....
-.DE
-works on the PDP-11, but
-will fail on machines where characters always take
-on positive values.
-The real solution is to declare
-.I c
-an integer, since
-.I getchar
-is actually returning
-integer values.
-In any case,
-.I lint
-will say
-``nonportable character comparison''.
-.PP
-A similar issue arises with bitfields; when assignments
-of constant values are made to bitfields, the field may
-be too small to hold the value.
-This is especially true because
-on some machines bitfields are considered as signed
-quantities.
-While it may seem unintuitive to consider
-that a two bit field declared of type
-.B int
-cannot hold the value 3, the problem disappears
-if the bitfield is declared to have type
-.B unsigned .
-.SH
-Assignments of longs to ints
-.PP
-Bugs may arise from the assignment of
-.B long
-to
-an
-.B int ,
-which loses accuracy.
-This may happen in programs
-which have been incompletely converted to use
-.B typedefs .
-When a
-.B typedef
-variable
-is changed from \fBint\fR to \fBlong\fR,
-the program can stop working because
-some intermediate results may be assigned
-to \fBints\fR, losing accuracy.
-Since there are a number of legitimate reasons for
-assigning \fBlongs\fR to \fBints\fR, the detection
-of these assignments is enabled
-by the
-.B \-a
-flag.
-.SH
-Strange Constructions
-.PP
-Several perfectly legal, but somewhat strange, constructions
-are flagged by
-.I lint;
-the messages hopefully encourage better code quality, clearer style, and
-may even point out bugs.
-The
-.B \-h
-flag is used to enable these checks.
-For example, in the statement
-.DS
-\(**p++ ;
-.DE
-the \(** does nothing; this provokes the message ``null effect'' from
-.I lint .
-The program fragment
-.DS
-unsigned x ;
-if( x < 0 ) ...
-.DE
-is clearly somewhat strange; the
-test will never succeed.
-Similarly, the test
-.DS
-if( x > 0 ) ...
-.DE
-is equivalent to
-.DS
-if( x != 0 )
-.DE
-which may not be the intended action.
-.I Lint
-will say ``degenerate unsigned comparison'' in these cases.
-If one says
-.DS
-if( 1 != 0 ) ....
-.DE
-.I lint
-will report
-``constant in conditional context'', since the comparison
-of 1 with 0 gives a constant result.
-.PP
-Another construction
-detected by
-.I lint
-involves
-operator precedence.
-Bugs which arise from misunderstandings about the precedence
-of operators can be accentuated by spacing and formatting,
-making such bugs extremely hard to find.
-For example, the statements
-.DS
-if( x&077 == 0 ) ...
-.DE
-or
-.DS
-x<\h'-.3m'<2 + 40
-.DE
-probably do not do what was intended.
-The best solution is to parenthesize such expressions,
-and
-.I lint
-encourages this by an appropriate message.
-.PP
-Finally, when the
-.B \-h
-flag is in force
-.I lint
-complains about variables which are redeclared in inner blocks
-in a way that conflicts with their use in outer blocks.
-This is legal, but is considered by many (including the author) to
-be bad style, usually unnecessary, and frequently a bug.
-.SH
-Ancient History
-.PP
-There are several forms of older syntax which are being officially
-discouraged.
-These fall into two classes, assignment operators and initialization.
-.PP
-The older forms of assignment operators (e.g., =+, =\-, . . . )
-could cause ambiguous expressions, such as
-.DS
-a =\-1 ;
-.DE
-which could be taken as either
-.DS
-a =\- 1 ;
-.DE
-or
-.DS
-a = \-1 ;
-.DE
-The situation is especially perplexing if this
-kind of ambiguity arises as the result of a macro substitution.
-The newer, and preferred operators (+=, \-=, etc. )
-have no such ambiguities.
-To spur the abandonment of the older forms,
-.I lint
-complains about these old fashioned operators.
-.PP
-A similar issue arises with initialization.
-The older language allowed
-.DS
-int x \fR1 ;
-.DE
-to initialize
-.I x
-to 1.
-This also caused syntactic difficulties: for example,
-.DS
-int x ( \-1 ) ;
-.DE
-looks somewhat like the beginning of a function declaration:
-.DS
-int x ( y ) { . . .
-.DE
-and the compiler must read a fair ways past
-.I x
-in order to sure what the declaration really is..
-Again, the problem is even more perplexing when the
-initializer involves a macro.
-The current syntax places an equals sign between the
-variable and the initializer:
-.DS
-int x = \-1 ;
-.DE
-This is free of any possible syntactic ambiguity.
-.SH
-Pointer Alignment
-.PP
-Certain pointer assignments may be reasonable on some machines,
-and illegal on others, due entirely to
-alignment restrictions.
-For example, on the PDP-11, it is reasonable
-to assign integer pointers to double pointers, since
-double precision values may begin on any integer boundary.
-On the Honeywell 6000, double precision values must begin
-on even word boundaries;
-thus, not all such assignments make sense.
-.I Lint
-tries to detect cases where pointers are assigned to other
-pointers, and such alignment problems might arise.
-The message ``possible pointer alignment problem''
-results from this situation whenever either the
-.B \-p
-or
-.B \-h
-flags are in effect.
-.SH
-Multiple Uses and Side Effects
-.PP
-In complicated expressions, the best order in which to evaluate
-subexpressions may be highly machine dependent.
-For example, on machines (like the PDP-11) in which the stack
-runs backwards, function arguments will probably be best evaluated
-from right-to-left; on machines with a stack running forward,
-left-to-right seems most attractive.
-Function calls embedded as arguments of other functions
-may or may not be treated similarly to ordinary arguments.
-Similar issues arise with other operators which have side effects,
-such as the assignment operators and the increment and decrement operators.
-.PP
-In order that the efficiency of C on a particular machine not be
-unduly compromised, the C language leaves the order
-of evaluation of complicated expressions up to the
-local compiler, and, in fact, the various C compilers have considerable
-differences in the order in which they will evaluate complicated
-expressions.
-In particular, if any variable is changed by a side effect, and
-also used elsewhere in the same expression, the result is explicitly undefined.
-.PP
-.I Lint
-checks for the important special case where
-a simple scalar variable is affected.
-For example, the statement
-.DS
-\fIa\fR[\fIi\|\fR] = \fIb\fR[\fIi\fR++] ;
-.DE
-will draw the complaint:
-.DS
-warning: \fIi\fR evaluation order undefined
-.DE
-.SH
-Implementation
-.PP
-.I Lint
-consists of two programs and a driver.
-The first program is a version of the
-Portable C Compiler
-.[
-Johnson Ritchie BSTJ Portability Programs System
-.]
-.[
-Johnson portable compiler 1978
-.]
-which is the basis of the
-IBM 370, Honeywell 6000, and Interdata 8/32 C compilers.
-This compiler does lexical and syntax analysis on the input text,
-constructs and maintains symbol tables, and builds trees for expressions.
-Instead of writing an intermediate file which is passed to
-a code generator, as the other compilers
-do,
-.I lint
-produces an intermediate file which consists of lines of ascii text.
-Each line contains an external variable name,
-an encoding of the context in which it was seen (use, definition, declaration, etc.),
-a type specifier, and a source file name and line number.
-The information about variables local to a function or file
-is collected
-by accessing the symbol table, and examining the expression trees.
-.PP
-Comments about local problems are produced as detected.
-The information about external names is collected
-onto an intermediate file.
-After all the source files and library descriptions have
-been collected, the intermediate file is sorted
-to bring all information collected about a given external
-name together.
-The second, rather small, program then reads the lines
-from the intermediate file and compares all of the
-definitions, declarations, and uses for consistency.
-.PP
-The driver controls this
-process, and is also responsible for making the options available
-to both passes of
-.I lint .
-.SH
-Portability
-.PP
-C on the Honeywell and IBM systems is used, in part, to write system code for the host operating system.
-This means that the implementation of C tends to follow local conventions rather than
-adhere strictly to
-.UX
-system conventions.
-Despite these differences, many C programs have been successfully moved to GCOS and the various IBM
-installations with little effort.
-This section describes some of the differences between the implementations, and
-discusses the
-.I lint
-features which encourage portability.
-.PP
-Uninitialized external variables are treated differently in different
-implementations of C.
-Suppose two files both contain a declaration without initialization, such as
-.DS
-int a ;
-.DE
-outside of any function.
-The
-.UX
-loader will resolve these declarations, and cause only a single word of storage
-to be set aside for \fIa\fR.
-Under the GCOS and IBM implementations, this is not feasible (for various stupid reasons!)
-so each such declaration causes a word of storage to be set aside and called \fIa\fR.
-When loading or library editing takes place, this causes fatal conflicts which prevent
-the proper operation of the program.
-If
-.I lint
-is invoked with the \fB\-p\fR flag,
-it will detect such multiple definitions.
-.PP
-A related difficulty comes from the amount of information retained about external names during the
-loading process.
-On the
-.UX
-system, externally known names have seven significant characters, with the upper/lower
-case distinction kept.
-On the IBM systems, there are eight significant characters, but the case distinction
-is lost.
-On GCOS, there are only six characters, of a single case.
-This leads to situations where programs run on the
-.UX
-system, but encounter loader
-problems on the IBM or GCOS systems.
-.I Lint
-.B \-p
-causes all external symbols to be mapped to one case and truncated to six characters,
-providing a worst-case analysis.
-.PP
-A number of differences arise in the area of character handling: characters in the
-.UX
-system are eight bit ascii, while they are eight bit ebcdic on the IBM, and
-nine bit ascii on GCOS.
-Moreover, character strings go from high to low bit positions (``left to right'')
-on GCOS and IBM, and low to high (``right to left'') on the PDP-11.
-This means that code attempting to construct strings
-out of character constants, or attempting to use characters as indices
-into arrays, must be looked at with great suspicion.
-.I Lint
-is of little help here, except to flag multi-character character constants.
-.PP
-Of course, the word sizes are different!
-This causes less trouble than might be expected, at least when
-moving from the
-.UX
-system (16 bit words) to the IBM (32 bits) or GCOS (36 bits).
-The main problems are likely to arise in shifting or masking.
-C now supports a bit-field facility, which can be used to write much of
-this code in a reasonably portable way.
-Frequently, portability of such code can be enhanced by
-slight rearrangements in coding style.
-Many of the incompatibilities seem to have the flavor of writing
-.DS
-x &= 0177700 ;
-.DE
-to clear the low order six bits of \fIx\fR.
-This suffices on the PDP-11, but fails badly on GCOS and IBM.
-If the bit field feature cannot be used, the same effect can be obtained by
-writing
-.DS
-x &= \(ap 077 ;
-.DE
-which will work on all these machines.
-.PP
-The right shift operator is arithmetic shift on the PDP-11, and logical shift on most
-other machines.
-To obtain a logical shift on all machines, the left operand can be
-typed \fBunsigned\fR.
-Characters are considered signed integers on the PDP-11, and unsigned on the other machines.
-This persistence of the sign bit may be reasonably considered a bug in the PDP-11 hardware
-which has infiltrated itself into the C language.
-If there were a good way to discover the programs which would be affected, C could be changed;
-in any case,
-.I lint
-is no help here.
-.PP
-The above discussion may have made the problem of portability seem
-bigger than it in fact is.
-The issues involved here are rarely subtle or mysterious, at least to the
-implementor of the program, although they can involve some work to straighten out.
-The most serious bar to the portability of
-.UX
-system utilities has been the inability to mimic
-essential
-.UX
-system functions on the other systems.
-The inability to seek to a random character position in a text file, or to establish a pipe
-between processes, has involved far more rewriting
-and debugging than any of the differences in C compilers.
-On the other hand,
-.I lint
-has been very helpful
-in moving the
-.UX
-operating system and associated
-utility programs to other machines.
-.SH
-Shutting Lint Up
-.PP
-There are occasions when
-the programmer is smarter than
-.I lint .
-There may be valid reasons for ``illegal'' type casts,
-functions with a variable number of arguments, etc.
-Moreover, as specified above, the flow of control information
-produced by
-.I lint
-often has blind spots, causing occasional spurious
-messages about perfectly reasonable programs.
-Thus, some way of communicating with
-.I lint ,
-typically to shut it up, is desirable.
-.PP
-The form which this mechanism should take is not at all clear.
-New keywords would require current and old compilers to
-recognize these keywords, if only to ignore them.
-This has both philosophical and practical problems.
-New preprocessor syntax suffers from similar problems.
-.PP
-What was finally done was to cause a number of words
-to be recognized by
-.I lint
-when they were embedded in comments.
-This required minimal preprocessor changes;
-the preprocessor just had to agree to pass comments
-through to its output, instead of deleting them
-as had been previously done.
-Thus,
-.I lint
-directives are invisible to the compilers, and
-the effect on systems with the older preprocessors
-is merely that the
-.I lint
-directives don't work.
-.PP
-The first directive is concerned with flow of control information;
-if a particular place in the program cannot be reached,
-but this is not apparent to
-.I lint ,
-this can be asserted by the directive
-.DS
-/* NOTREACHED */
-.DE
-at the appropriate spot in the program.
-Similarly, if it is desired to turn off
-strict type checking for
-the next expression, the directive
-.DS
-/* NOSTRICT */
-.DE
-can be used; the situation reverts to the
-previous default after the next expression.
-The
-.B \-v
-flag can be turned on for one function by the directive
-.DS
-/* ARGSUSED */
-.DE
-Complaints about variable number of arguments in calls to a function
-can be turned off by the directive
-.DS
-/* VARARGS */
-.DE
-preceding the function definition.
-In some cases, it is desirable to check the
-first several arguments, and leave the later arguments unchecked.
-This can be done by following the VARARGS keyword immediately
-with a digit giving the number of arguments which should be checked; thus,
-.DS
-/* VARARGS2 */
-.DE
-will cause the first two arguments to be checked, the others unchecked.
-Finally, the directive
-.DS
-/* LINTLIBRARY */
-.DE
-at the head of a file identifies this file as
-a library declaration file; this topic is worth a
-section by itself.
-.SH
-Library Declaration Files
-.PP
-.I Lint
-accepts certain library directives, such as
-.DS
-\-ly
-.DE
-and tests the source files for compatibility with these libraries.
-This is done by accessing library description files whose
-names are constructed from the library directives.
-These files all begin with the directive
-.DS
-/* LINTLIBRARY */
-.DE
-which is followed by a series of dummy function
-definitions.
-The critical parts of these definitions
-are the declaration of the function return type,
-whether the dummy function returns a value, and
-the number and types of arguments to the function.
-The VARARGS and ARGSUSED directives can
-be used to specify features of the library functions.
-.PP
-.I Lint
-library files are processed almost exactly like ordinary
-source files.
-The only difference is that functions which are defined on a library file,
-but are not used on a source file, draw no complaints.
-.I Lint
-does not simulate a full library search algorithm,
-and complains if the source files contain a redefinition of
-a library routine (this is a feature!).
-.PP
-By default,
-.I lint
-checks the programs it is given against a standard library
-file, which contains descriptions of the programs which
-are normally loaded when
-a C program
-is run.
-When the
-.B -p
-flag is in effect, another file is checked containing
-descriptions of the standard I/O library routines
-which are expected to be portable across various machines.
-The
-.B -n
-flag can be used to suppress all library checking.
-.SH
-Bugs, etc.
-.PP
-.I Lint
-was a difficult program to write, partially
-because it is closely connected with matters of programming style,
-and partially because users usually don't notice bugs which cause
-.I lint
-to miss errors which it should have caught.
-(By contrast, if
-.I lint
-incorrectly complains about something that is correct, the
-programmer reports that immediately!)
-.PP
-A number of areas remain to be further developed.
-The checking of structures and arrays is rather inadequate;
-size
-incompatibilities go unchecked,
-and no attempt is made to match up structure and union
-declarations across files.
-Some stricter checking of the use of the
-.B typedef
-is clearly desirable, but what checking is appropriate, and how
-to carry it out, is still to be determined.
-.PP
-.I Lint
-shares the preprocessor with the C compiler.
-At some point it may be appropriate for a
-special version of the preprocessor to be constructed
-which checks for things such as unused macro definitions,
-macro arguments which have side effects which are
-not expanded at all, or are expanded more than once, etc.
-.PP
-The central problem with
-.I lint
-is the packaging of the information which it collects.
-There are many options which
-serve only to turn off, or slightly modify,
-certain features.
-There are pressures to add even more of these options.
-.PP
-In conclusion, it appears that the general notion of having two
-programs is a good one.
-The compiler concentrates on quickly and accurately turning the
-program text into bits which can be run;
-.I lint
-concentrates on issues
-of portability, style, and efficiency.
-.I Lint
-can afford to be wrong, since incorrectness and over-conservatism
-are merely annoying, not fatal.
-The compiler can be fast since it knows that
-.I lint
-will cover its flanks.
-Finally, the programmer can
-concentrate at one stage
-of the programming process solely on the algorithms,
-data structures, and correctness of the
-program, and then later retrofit,
-with the aid of
-.I lint ,
-the desirable properties of universality and portability.
-.SG MH-1273-SCJ-unix
-.\".bp
-.[
-$LIST$
-.]
-.bp
-.SH
-Appendix: Current Lint Options
-.PP
-The command currently has the form
-.DS
-lint\fR [\fB\-\fRoptions ] files... library-descriptors...
-.DE
-The options are
-.IP \fBh\fR
-Perform heuristic checks
-.IP \fBp\fR
-Perform portability checks
-.IP \fBv\fR
-Don't report unused arguments
-.IP \fBu\fR
-Don't report unused or undefined externals
-.IP \fBb\fR
-Report unreachable
-.B break
-statements.
-.IP \fBx\fR
-Report unused external declarations
-.IP \fBa\fR
-Report assignments of
-.B long
-to
-.B int
-or shorter.
-.IP \fBc\fR
-Complain about questionable casts
-.IP \fBn\fR
-No library checking is done
-.IP \fBs\fR
-Same as
-.B h
-(for historical reasons)
diff --git a/usr.bin/xlint/README b/usr.bin/xlint/README
deleted file mode 100644
index 0692d6f77c2..00000000000
--- a/usr.bin/xlint/README
+++ /dev/null
@@ -1,30 +0,0 @@
-lint is divided into 3 separate programs: lint, lint1, and
-lint2 (the latter two programs reside in /usr/libexec).
-
-lint calls /usr/libexec/cpp to preprocess the program, then passes
-the output to lint1, which does most of the work. lint1 then outputs
-a .ln file, which is parsed by lint2 to do more holistic checks. all
-of this is driven by /usr/bin/lint, which is like a wrapper program.
-
-lint1 implements its own C parser. it is incapable of parsing some
-weird gcc things, such as __attribute__ and so on. OpenBSD's source
-tree already does a good job of removing gcc'isms when parsers other
-than gcc are detected.
-
-lint1 keeps a symbol table for the current context, which always
-includes global symbols for the current translation unit, as well as
-locals (inside a function definition). When it parses a function
-definition, it pushes a symbol table context onto the stack, and
-then pops it off when the function definition ends.
-
-lint1 does the vast majority of its checks one expression at a time.
-It uses the symbol table (which contains types of symbols) and almost
-nothing else when doing type conversions. All of the checks happen at
-parse time. lint1 does not really build an abstract syntax tree (AST)
-to represent the entire program; it only keeps track of the symbols
-in the current context, and some minimal information about the types
-of enclosing control blocks (loops, switch statements, etc). When lint1
-is finished parsing an expression, you will not see any more warnings
-regarding that expression.
-
-$OpenBSD: README,v 1.2 2007/09/24 19:56:34 jmc Exp $
diff --git a/usr.bin/xlint/lint1/Makefile b/usr.bin/xlint/lint1/Makefile
deleted file mode 100644
index 4bf5b7a432c..00000000000
--- a/usr.bin/xlint/lint1/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# $OpenBSD: Makefile,v 1.10 2006/11/03 16:27:52 otto Exp $
-# $NetBSD: Makefile,v 1.3 1995/07/04 01:53:05 cgd Exp $
-
-PROG= lint1
-SRCS= cgram.y scan.l mem1.c mem.c err.c main1.c decl.c tree.c func.c \
- init.c emit.c emit1.c
-NOMAN=
-LDADD+= -ll
-DPADD+= ${LIBL}
-YFLAGS= -d
-CFLAGS+=-I. -I${.CURDIR}
-LINTFLAGS=-aehpz
-
-BINDIR= /usr/libexec
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/xlint/lint1/cgram.y b/usr.bin/xlint/lint1/cgram.y
deleted file mode 100644
index ed83d88aba0..00000000000
--- a/usr.bin/xlint/lint1/cgram.y
+++ /dev/null
@@ -1,1726 +0,0 @@
-%{
-/* $OpenBSD: cgram.y,v 1.24 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <limits.h>
-
-#include "lint1.h"
-
-/*
- * Contains the level of current declaration. 0 is extern.
- * Used for symbol table entries.
- */
-int blklev;
-
-/*
- * level for memory allocation. Normaly the same as blklev.
- * An exception is the declaration of arguments in prototypes. Memory
- * for these can't be freed after the declaration, but symbols must
- * be removed from the symbol table after the declaration.
- */
-int mblklev;
-
-/*
- * Is the statement empty?
- */
-int estmnt;
-
-static int toicon(tnode_t *);
-static void idecl(sym_t *, int);
-static void ignuptorp(void);
-
-%}
-
-%union {
- int y_int;
- val_t *y_val;
- sbuf_t *y_sb;
- sym_t *y_sym;
- op_t y_op;
- scl_t y_scl;
- tspec_t y_tspec;
- tqual_t y_tqual;
- type_t *y_type;
- tnode_t *y_tnode;
- strg_t *y_strg;
- pqinf_t *y_pqinf;
-};
-
-%token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
-%token <y_op> T_STROP
-%token <y_op> T_UNOP
-%token <y_op> T_INCDEC
-%token T_SIZEOF
-%token <y_op> T_MULT
-%token <y_op> T_DIVOP
-%token <y_op> T_ADDOP
-%token <y_op> T_SHFTOP
-%token <y_op> T_RELOP
-%token <y_op> T_EQOP
-%token <y_op> T_AND
-%token <y_op> T_XOR
-%token <y_op> T_OR
-%token <y_op> T_LOGAND
-%token <y_op> T_LOGOR
-%token T_QUEST
-%token T_COLON
-%token <y_op> T_ASSIGN
-%token <y_op> T_OPASS
-%token T_COMMA
-%token T_SEMI
-%token T_ELLIPSE
-
-/* storage classes (extern, static, auto, register and typedef) */
-%token <y_scl> T_SCLASS
-
-/* types (char, int, short, long, unsigned, signed, float, double, void) */
-%token <y_tspec> T_TYPE
-
-/* qualifiers (const, volatile, restrict) */
-%token <y_tqual> T_QUAL
-
-/* struct or union */
-%token <y_tspec> T_SOU
-
-/* enum */
-%token T_ENUM
-
-/* remaining keywords */
-%token T_CASE
-%token T_DEFAULT
-%token T_IF
-%token T_ELSE
-%token T_SWITCH
-%token T_DO
-%token T_WHILE
-%token T_FOR
-%token T_GOTO
-%token T_CONTINUE
-%token T_BREAK
-%token T_RETURN
-%token T_ASM
-%token T_LEQUAL
-%token T_ATTRIBUTE
-
-%left T_COMMA
-%right T_ASSIGN T_OPASS
-%right T_QUEST T_COLON
-%left T_LOGOR
-%left T_LOGAND
-%left T_OR
-%left T_XOR
-%left T_AND
-%left T_EQOP
-%left T_RELOP
-%left T_SHFTOP
-%left T_ADDOP
-%left T_MULT T_DIVOP
-%right T_UNOP T_INCDEC T_SIZEOF
-%left T_LPARN T_LBRACK T_STROP
-
-%token <y_sb> T_NAME
-%token <y_sb> T_TYPENAME
-%token <y_val> T_CON
-%token <y_strg> T_STRING
-
-%type <y_sym> func_decl
-%type <y_sym> notype_decl
-%type <y_sym> type_decl
-%type <y_type> typespec
-%type <y_type> clrtyp_typespec
-%type <y_type> notype_typespec
-%type <y_type> struct_spec
-%type <y_type> enum_spec
-%type <y_sym> struct_tag
-%type <y_sym> enum_tag
-%type <y_tspec> struct
-%type <y_sym> struct_declaration
-%type <y_sb> identifier
-%type <y_sym> member_declaration_list_with_rbrace
-%type <y_sym> member_declaration_list
-%type <y_sym> member_declaration
-%type <y_sym> notype_member_decls
-%type <y_sym> type_member_decls
-%type <y_sym> notype_member_decl
-%type <y_sym> type_member_decl
-%type <y_tnode> constant
-%type <y_sym> enum_declaration
-%type <y_sym> enums_with_opt_comma
-%type <y_sym> enums
-%type <y_sym> enumerator
-%type <y_sym> ename
-%type <y_sym> notype_direct_decl
-%type <y_sym> type_direct_decl
-%type <y_pqinf> pointer
-%type <y_pqinf> asterisk
-%type <y_sym> param_decl
-%type <y_sym> param_list
-%type <y_sym> abs_decl_param_list
-%type <y_sym> direct_param_decl
-%type <y_sym> notype_param_decl
-%type <y_sym> direct_notype_param_decl
-%type <y_pqinf> type_qualifier_list
-%type <y_pqinf> type_qualifier
-%type <y_sym> identifier_list
-%type <y_sym> abs_decl
-%type <y_sym> direct_abs_decl
-%type <y_sym> vararg_parameter_type_list
-%type <y_sym> parameter_type_list
-%type <y_sym> parameter_declaration
-%type <y_tnode> expr
-%type <y_tnode> term
-%type <y_tnode> func_arg_list
-%type <y_op> point_or_arrow
-%type <y_type> type_name
-%type <y_sym> abstract_declaration
-%type <y_tnode> do_while_expr
-%type <y_tnode> opt_expr
-%type <y_strg> string
-%type <y_strg> string2
-
-
-%%
-
-program:
- /* empty */ {
- if (sflag) {
- /* empty translation unit */
- error(272);
- } else {
- /* empty translation unit */
- warning(272);
- }
- }
- | translation_unit
- ;
-
-translation_unit:
- ext_decl
- | translation_unit ext_decl
- ;
-
-ext_decl:
- func_def {
- glclup(0);
- clrwflgs();
- }
- | data_def {
- glclup(0);
- clrwflgs();
- }
- | T_LEQUAL T_LPARN identifier T_COMMA identifier T_RPARN T_SEMI {
- sym_t *new, *old;
-
- if ($5->sb_sym && $3->sb_sym /*== NULL*/) {
- new = getsym($5);
- old = $3->sb_sym;
- new->s_dpos = old->s_dpos;
- new->s_spos = old->s_spos;
- new->s_upos = old->s_upos;
- new->s_kind = old->s_kind;
- new->s_keyw = old->s_keyw;
- new->s_field = old->s_field;
- new->s_set = old->s_set;
- new->s_used = old->s_used;
- new->s_arg = old->s_arg;
- new->s_reg = old->s_reg;
- new->s_defarg = old->s_defarg;
- new->s_rimpl = old->s_rimpl;
- new->s_osdef = old->s_osdef;
- new->s_inline = old->s_inline;
- new->s_noreturn = old->s_noreturn;
- new->s_def = old->s_def;
- new->s_scl = old->s_scl;
- new->s_blklev = old->s_blklev;
- new->s_type = old->s_type;
- new->s_value = old->s_value;
- new->u = old->u;
-
- /* XXX missing 'r' because do not know return type
- of parent... */
- /* outsym(new, new->s_scl, DEF); */
- outfdef(new, &csrc_pos,
- new->s_rimpl || new->s_type->t_subt->t_tspec != VOID,
- 0, NULL);
- }
-
- }
- ;
-
-data_def: T_SEMI
- | clrtyp deftyp notype_init_decls T_SEMI {
- if (sflag) {
- /* old style declaration; add "int" */
- error(1);
- } else {
- /* old style declaration; add "int" */
- warning(1);
- }
- }
- | declmods deftyp T_SEMI {
- if (dcs->d_scl == TYPEDEF) {
- /* typedef declares no type name */
- warning(72);
- } else {
- /* empty declaration */
- warning(2);
- }
- }
- | declmods deftyp notype_init_decls T_SEMI
- | declspecs deftyp T_SEMI {
- if (dcs->d_scl == TYPEDEF) {
- /* typedef declares no type name */
- warning(72);
- } else if (!dcs->d_nedecl) {
- /* empty declaration */
- warning(2);
- }
- }
- | declspecs deftyp type_init_decls opt_attribute_spec T_SEMI
- | error T_SEMI {
- globclup();
- }
- | error T_RBRACE {
- globclup();
- }
- ;
-
-func_def:
- func_decl {
- if ($1->s_type->t_tspec != FUNC) {
- /* syntax error */
- error(249);
- YYERROR;
- }
- if ($1->s_type->t_typedef) {
- /* ()-less function definition */
- error(64);
- YYERROR;
- }
- funcdef($1);
- blklev++;
- pushdecl(ARG);
- } opt_arg_declaration_list {
- popdecl();
- blklev--;
- cluparg();
- pushctrl(0);
- } comp_stmnt {
- funcend();
- popctrl(0);
- }
- ;
-
-opt_attribute_spec:
- /* empty */
- | T_ATTRIBUTE T_LPARN T_LPARN read_until_rparn T_RPARN
- ;
-
-func_decl:
- clrtyp deftyp notype_decl {
- $$ = $3;
- }
- | declmods deftyp notype_decl {
- $$ = $3;
- }
- | declspecs deftyp type_decl {
- $$ = $3;
- }
- ;
-
-opt_arg_declaration_list:
- /* empty */
- | arg_declaration_list
- ;
-
-arg_declaration_list:
- arg_declaration
- | arg_declaration_list arg_declaration
- /* XXX or better "arg_declaration error" ? */
- | error
- ;
-
-/*
- * "arg_declaration" is separated from "declaration" because it
- * needs other error handling.
- */
-
-arg_declaration:
- declmods deftyp T_SEMI {
- /* empty declaration */
- warning(2);
- }
- | declmods deftyp notype_init_decls T_SEMI
- | declspecs deftyp T_SEMI {
- if (!dcs->d_nedecl) {
- /* empty declaration */
- warning(2);
- } else {
- tspec_t ts = dcs->d_type->t_tspec;
- /* %s declared in argument declaration list */
- warning(3, ts == STRUCT ? "struct" :
- (ts == UNION ? "union" : "enum"));
- }
- }
- | declspecs deftyp type_init_decls T_SEMI {
- if (dcs->d_nedecl) {
- tspec_t ts = dcs->d_type->t_tspec;
- /* %s declared in argument declaration list */
- warning(3, ts == STRUCT ? "struct" :
- (ts == UNION ? "union" : "enum"));
- }
- }
- | declmods error
- | declspecs error
- ;
-
-declaration:
- declmods deftyp T_SEMI {
- if (dcs->d_scl == TYPEDEF) {
- /* typedef declares no type name */
- warning(72);
- } else {
- /* empty declaration */
- warning(2);
- }
- }
- | declmods deftyp notype_init_decls T_SEMI
- | declspecs deftyp T_SEMI {
- if (dcs->d_scl == TYPEDEF) {
- /* typedef declares no type name */
- warning(72);
- } else if (!dcs->d_nedecl) {
- /* empty declaration */
- warning(2);
- }
- }
- | declspecs deftyp type_init_decls T_SEMI
- | error T_SEMI
- ;
-
-clrtyp:
- {
- clrtyp();
- }
- ;
-
-deftyp:
- /* empty */ {
- deftyp();
- }
- ;
-
-declspecs:
- clrtyp_typespec {
- addtype($1);
- }
- | declmods typespec {
- addtype($2);
- }
- | declspecs declmod
- | declspecs notype_typespec {
- addtype($2);
- }
- ;
-
-declmods:
- clrtyp T_QUAL {
- addqual($2);
- }
- | clrtyp T_SCLASS {
- addscl($2);
- }
- | declmods declmod
- ;
-
-declmod:
- T_QUAL {
- addqual($1);
- }
- | T_SCLASS {
- addscl($1);
- }
- ;
-
-clrtyp_typespec:
- clrtyp notype_typespec {
- $$ = $2;
- }
- | T_TYPENAME clrtyp {
- $$ = getsym($1)->s_type;
- }
- ;
-
-typespec:
- notype_typespec {
- $$ = $1;
- }
- | T_TYPENAME {
- $$ = getsym($1)->s_type;
- }
- ;
-
-notype_typespec:
- T_TYPE {
- $$ = gettyp($1);
- }
- | struct_spec {
- popdecl();
- $$ = $1;
- }
- | enum_spec {
- popdecl();
- $$ = $1;
- }
- ;
-
-struct_spec:
- struct struct_tag {
- /*
- * STDC requires that "struct a;" always introduces
- * a new tag if "a" is not declared at current level
- *
- * yychar is valid because otherwise the parser would
- * not been able to deceide if he must shift or reduce
- */
- $$ = mktag($2, $1, 0, yychar == T_SEMI);
- }
- | struct struct_tag {
- dcs->d_tagtyp = mktag($2, $1, 1, 0);
- } struct_declaration {
- $$ = compltag(dcs->d_tagtyp, $4);
- }
- | struct {
- dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
- } struct_declaration {
- $$ = compltag(dcs->d_tagtyp, $3);
- }
- | struct error {
- symtyp = FVFT;
- $$ = gettyp(INT);
- }
- ;
-
-struct:
- T_SOU {
- symtyp = FTAG;
- pushdecl($1 == STRUCT ? MOS : MOU);
- dcs->d_offset = 0;
- dcs->d_stralign = CHAR_BIT;
- $$ = $1;
- }
- ;
-
-struct_tag:
- identifier {
- $$ = getsym($1);
- }
- ;
-
-struct_declaration:
- struct_decl_lbrace member_declaration_list_with_rbrace {
- $$ = $2;
- }
- ;
-
-struct_decl_lbrace:
- T_LBRACE {
- symtyp = FVFT;
- }
- ;
-
-member_declaration_list_with_rbrace:
- member_declaration_list T_SEMI T_RBRACE {
- $$ = $1;
- }
- | member_declaration_list T_RBRACE {
- if (sflag) {
- /* syntax req. ";" after last struct/union member */
- error(66);
- } else {
- /* syntax req. ";" after last struct/union member */
- warning(66);
- }
- $$ = $1;
- }
- | T_RBRACE {
- $$ = NULL;
- }
- ;
-
-member_declaration_list:
- member_declaration {
- $$ = $1;
- }
- | member_declaration_list T_SEMI member_declaration {
- $$ = lnklst($1, $3);
- }
- ;
-
-member_declaration:
- noclass_declmods deftyp {
- /* too late, i know, but getsym() compensates it */
- symtyp = FMOS;
- } notype_member_decls {
- symtyp = FVFT;
- $$ = $4;
- }
- | noclass_declspecs deftyp {
- symtyp = FMOS;
- } type_member_decls {
- symtyp = FVFT;
- $$ = $4;
- }
- | noclass_declmods deftyp {
- /* struct or union member must be named */
- warning(49);
- $$ = NULL;
- }
- | noclass_declspecs deftyp {
- /* struct or union member must be named */
- warning(49);
- $$ = NULL;
- }
- | error {
- symtyp = FVFT;
- $$ = NULL;
- }
- ;
-
-noclass_declspecs:
- clrtyp_typespec {
- addtype($1);
- }
- | noclass_declmods typespec {
- addtype($2);
- }
- | noclass_declspecs T_QUAL {
- addqual($2);
- }
- | noclass_declspecs notype_typespec {
- addtype($2);
- }
- ;
-
-noclass_declmods:
- clrtyp T_QUAL {
- addqual($2);
- }
- | noclass_declmods T_QUAL {
- addqual($2);
- }
- ;
-
-notype_member_decls:
- notype_member_decl {
- $$ = decl1str($1);
- }
- | notype_member_decls {
- symtyp = FMOS;
- } T_COMMA type_member_decl {
- $$ = lnklst($1, decl1str($4));
- }
- ;
-
-type_member_decls:
- type_member_decl {
- $$ = decl1str($1);
- }
- | type_member_decls {
- symtyp = FMOS;
- } T_COMMA type_member_decl {
- $$ = lnklst($1, decl1str($4));
- }
- ;
-
-notype_member_decl:
- notype_decl {
- $$ = $1;
- }
- | notype_decl T_COLON constant {
- $$ = bitfield($1, toicon($3));
- }
- | {
- symtyp = FVFT;
- } T_COLON constant {
- $$ = bitfield(NULL, toicon($3));
- }
- ;
-
-type_member_decl:
- type_decl {
- $$ = $1;
- }
- | type_decl T_COLON constant {
- $$ = bitfield($1, toicon($3));
- }
- | {
- symtyp = FVFT;
- } T_COLON constant {
- $$ = bitfield(NULL, toicon($3));
- }
- ;
-
-enum_spec:
- enum enum_tag {
- $$ = mktag($2, ENUM, 0, 0);
- }
- | enum enum_tag {
- dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
- } enum_declaration {
- $$ = compltag(dcs->d_tagtyp, $4);
- }
- | enum {
- dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
- } enum_declaration {
- $$ = compltag(dcs->d_tagtyp, $3);
- }
- | enum error {
- symtyp = FVFT;
- $$ = gettyp(INT);
- }
- ;
-
-enum:
- T_ENUM {
- symtyp = FTAG;
- pushdecl(ENUMCON);
- }
- ;
-
-enum_tag:
- identifier {
- $$ = getsym($1);
- }
- ;
-
-enum_declaration:
- enum_decl_lbrace enums_with_opt_comma T_RBRACE {
- $$ = $2;
- }
- ;
-
-enum_decl_lbrace:
- T_LBRACE {
- symtyp = FVFT;
- enumval = 0;
- }
- ;
-
-enums_with_opt_comma:
- enums {
- $$ = $1;
- }
- | enums T_COMMA {
- $$ = $1;
- }
- ;
-
-enums:
- enumerator {
- $$ = $1;
- }
- | enums T_COMMA enumerator {
- $$ = lnklst($1, $3);
- }
- | error {
- $$ = NULL;
- }
- ;
-
-enumerator:
- ename {
- $$ = ename($1, enumval, 1);
- }
- | ename T_ASSIGN constant {
- $$ = ename($1, toicon($3), 0);
- }
- ;
-
-ename:
- identifier {
- $$ = getsym($1);
- }
- ;
-
-
-notype_init_decls:
- notype_init_decl
- | notype_init_decls T_COMMA type_init_decl
- ;
-
-type_init_decls:
- type_init_decl
- | type_init_decls T_COMMA type_init_decl
- ;
-
-notype_init_decl:
- notype_decl opt_attribute_spec opt_asm_spec {
- idecl($1, 0);
- chksz($1);
- }
- | notype_decl opt_asm_spec {
- idecl($1, 1);
- } T_ASSIGN initializer {
- chksz($1);
- }
- ;
-
-type_init_decl:
- type_decl opt_asm_spec {
- idecl($1, 0);
- chksz($1);
- }
- | type_decl opt_asm_spec {
- idecl($1, 1);
- } T_ASSIGN initializer {
- chksz($1);
- }
- ;
-
-notype_decl:
- notype_direct_decl {
- $$ = $1;
- }
- | pointer notype_direct_decl {
- $$ = addptr($2, $1);
- }
- ;
-
-notype_direct_decl:
- T_NAME {
- $$ = dname(getsym($1));
- }
- | T_LPARN type_decl T_RPARN {
- $$ = $2;
- }
- | notype_direct_decl T_LBRACK T_RBRACK {
- $$ = addarray($1, 0, 0);
- }
- | notype_direct_decl T_LBRACK constant T_RBRACK {
- $$ = addarray($1, 1, toicon($3));
- }
- | notype_direct_decl param_list {
- $$ = addfunc($1, $2);
- popdecl();
- blklev--;
- }
- ;
-
-type_decl:
- type_direct_decl {
- $$ = $1;
- }
- | pointer type_direct_decl {
- $$ = addptr($2, $1);
- }
- ;
-
-type_direct_decl:
- identifier {
- $$ = dname(getsym($1));
- }
- | T_LPARN type_decl T_RPARN {
- $$ = $2;
- }
- | type_direct_decl T_LBRACK T_RBRACK {
- $$ = addarray($1, 0, 0);
- }
- | type_direct_decl T_LBRACK constant T_RBRACK {
- $$ = addarray($1, 1, toicon($3));
- }
- | type_direct_decl param_list {
- $$ = addfunc($1, $2);
- popdecl();
- blklev--;
- }
- ;
-
-/*
- * param_decl and notype_param_decl exist to avoid a conflict in
- * argument lists. A typename enclosed in parens should always be
- * treated as a typename, not an argument.
- * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
- * not "typedef int a; f(int a);"
- */
-param_decl:
- direct_param_decl {
- $$ = $1;
- }
- | pointer direct_param_decl {
- $$ = addptr($2, $1);
- }
- ;
-
-direct_param_decl:
- identifier {
- $$ = dname(getsym($1));
- }
- | T_LPARN notype_param_decl T_RPARN {
- $$ = $2;
- }
- | direct_param_decl T_LBRACK T_RBRACK {
- $$ = addarray($1, 0, 0);
- }
- | direct_param_decl T_LBRACK constant T_RBRACK {
- $$ = addarray($1, 1, toicon($3));
- }
- | direct_param_decl param_list {
- $$ = addfunc($1, $2);
- popdecl();
- blklev--;
- }
- ;
-
-notype_param_decl:
- direct_notype_param_decl {
- $$ = $1;
- }
- | pointer direct_notype_param_decl {
- $$ = addptr($2, $1);
- }
- ;
-
-direct_notype_param_decl:
- T_NAME {
- $$ = dname(getsym($1));
- }
- | T_LPARN notype_param_decl T_RPARN {
- $$ = $2;
- }
- | direct_notype_param_decl T_LBRACK T_RBRACK {
- $$ = addarray($1, 0, 0);
- }
- | direct_notype_param_decl T_LBRACK constant T_RBRACK {
- $$ = addarray($1, 1, toicon($3));
- }
- | direct_notype_param_decl param_list {
- $$ = addfunc($1, $2);
- popdecl();
- blklev--;
- }
- ;
-
-pointer:
- asterisk {
- $$ = $1;
- }
- | asterisk type_qualifier_list {
- $$ = mergepq($1, $2);
- }
- | asterisk pointer {
- $$ = mergepq($1, $2);
- }
- | asterisk type_qualifier_list pointer {
- $$ = mergepq(mergepq($1, $2), $3);
- }
- ;
-
-asterisk:
- T_MULT {
- $$ = xcalloc(1, sizeof (pqinf_t));
- $$->p_pcnt = 1;
- }
- ;
-
-type_qualifier_list:
- type_qualifier {
- $$ = $1;
- }
- | type_qualifier_list type_qualifier {
- $$ = mergepq($1, $2);
- }
- ;
-
-type_qualifier:
- T_QUAL {
- $$ = xcalloc(1, sizeof (pqinf_t));
- if ($1 == CONST) {
- $$->p_const = 1;
- } else {
- $$->p_volatile = 1;
- }
- }
- ;
-
-param_list:
- id_list_lparn identifier_list T_RPARN {
- $$ = $2;
- }
- | abs_decl_param_list {
- $$ = $1;
- }
- ;
-
-id_list_lparn:
- T_LPARN {
- blklev++;
- pushdecl(PARG);
- }
- ;
-
-identifier_list:
- T_NAME {
- $$ = iname(getsym($1));
- }
- | identifier_list T_COMMA T_NAME {
- $$ = lnklst($1, iname(getsym($3)));
- }
- | identifier_list error {
- $$ = $1;
- }
- ;
-
-abs_decl_param_list:
- abs_decl_lparn T_RPARN {
- $$ = NULL;
- }
- | abs_decl_lparn vararg_parameter_type_list T_RPARN {
- dcs->d_proto = 1;
- $$ = $2;
- }
- | abs_decl_lparn error T_RPARN {
- $$ = NULL;
- }
- ;
-
-abs_decl_lparn:
- T_LPARN {
- blklev++;
- pushdecl(PARG);
- }
- ;
-
-vararg_parameter_type_list:
- parameter_type_list {
- $$ = $1;
- }
- | parameter_type_list T_COMMA T_ELLIPSE {
- dcs->d_vararg = 1;
- $$ = $1;
- }
- | T_ELLIPSE {
- if (sflag) {
- /* ANSI C requires formal parameter before "..." */
- error(84);
- } else {
- /* ANSI C requires formal parameter before "..." */
- warning(84);
- }
- dcs->d_vararg = 1;
- $$ = NULL;
- }
- ;
-
-parameter_type_list:
- parameter_declaration opt_asm_spec {
- $$ = $1;
- }
- | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
- $$ = lnklst($1, $3);
- }
- ;
-
-parameter_declaration:
- declmods deftyp {
- $$ = decl1arg(aname(), 0);
- }
- | declspecs deftyp {
- $$ = decl1arg(aname(), 0);
- }
- | declmods deftyp notype_param_decl {
- $$ = decl1arg($3, 0);
- }
- /*
- * param_decl is needed because of following conflict:
- * "typedef int a; f(int (a));" could be parsed as
- * "function with argument a of type int", or
- * "function with an abstract argument of type function".
- * This grammar realizes the second case.
- */
- | declspecs deftyp param_decl {
- $$ = decl1arg($3, 0);
- }
- | declmods deftyp abs_decl {
- $$ = decl1arg($3, 0);
- }
- | declspecs deftyp abs_decl {
- $$ = decl1arg($3, 0);
- }
- ;
-
-opt_asm_spec:
- /* empty */
- | T_ASM T_LPARN read_until_rparn
- ;
-
-initializer:
- init_expr
- ;
-
-init_expr:
- expr %prec T_COMMA {
- mkinit($1);
- }
- | init_lbrace init_expr_list init_rbrace
- | init_lbrace init_expr_list T_COMMA init_rbrace
- | init_lbrace init_rbrace
- | error
- ;
-
-init_expr_list:
- init_expr %prec T_COMMA
- | init_expr_list T_COMMA init_expr
- ;
-
-init_lbrace:
- T_LBRACE {
- initlbr();
- }
- ;
-
-init_rbrace:
- T_RBRACE {
- initrbr();
- }
- ;
-
-type_name:
- {
- pushdecl(ABSTRACT);
- } abstract_declaration {
- popdecl();
- $$ = $2->s_type;
- }
- ;
-
-abstract_declaration:
- noclass_declmods deftyp {
- $$ = decl1abs(aname());
- }
- | noclass_declspecs deftyp {
- $$ = decl1abs(aname());
- }
- | noclass_declmods deftyp abs_decl {
- $$ = decl1abs($3);
- }
- | noclass_declspecs deftyp abs_decl {
- $$ = decl1abs($3);
- }
- ;
-
-abs_decl:
- pointer {
- $$ = addptr(aname(), $1);
- }
- | direct_abs_decl {
- $$ = $1;
- }
- | pointer direct_abs_decl {
- $$ = addptr($2, $1);
- }
- ;
-
-direct_abs_decl:
- T_LPARN abs_decl T_RPARN {
- $$ = $2;
- }
- | T_LBRACK T_RBRACK {
- $$ = addarray(aname(), 0, 0);
- }
- | T_LBRACK constant T_RBRACK {
- $$ = addarray(aname(), 1, toicon($2));
- }
- | direct_abs_decl T_LBRACK T_RBRACK {
- $$ = addarray($1, 0, 0);
- }
- | direct_abs_decl T_LBRACK constant T_RBRACK {
- $$ = addarray($1, 1, toicon($3));
- }
- | abs_decl_param_list {
- $$ = addfunc(aname(), $1);
- popdecl();
- blklev--;
- }
- | direct_abs_decl abs_decl_param_list {
- $$ = addfunc($1, $2);
- popdecl();
- blklev--;
- }
- ;
-
-stmnt:
- labeled_stmnt {
- estmnt = 0;
- }
- | expr_stmnt
- | comp_stmnt {
- estmnt = 0;
- }
- | selection_stmnt {
- estmnt = 0;
- }
- | iteration_stmnt {
- estmnt = 0;
- }
- | jump_stmnt {
- estmnt = 0;
- ftflg = 0;
- }
- | asm_stmnt {
- estmnt = 0;
- }
- ;
-
-labeled_stmnt:
- label stmnt
- ;
-
-label:
- identifier T_COLON {
- symtyp = FLAB;
- label(T_NAME, getsym($1), NULL);
- }
- | T_CASE constant T_COLON {
- label(T_CASE, NULL, $2);
- ftflg = 1;
- }
- | T_CASE constant T_ELLIPSE constant T_COLON {
- /* XXX: only using the first value of this gcc-ism */
- label(T_CASE, NULL, $2);
- ftflg = 1;
-
- if (!gflag)
- gnuism(311);
- }
- | T_DEFAULT T_COLON {
- label(T_DEFAULT, NULL, NULL);
- ftflg = 1;
- }
- ;
-
-comp_stmnt:
- compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
- | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
- ;
-
-compstmnt_lbrace:
- T_LBRACE {
- blklev++;
- mblklev++;
- pushdecl(AUTO);
- }
- ;
-
-compstmnt_rbrace:
- T_RBRACE {
- popdecl();
- freeblk();
- mblklev--;
- blklev--;
- ftflg = 0;
- }
- ;
-
-opt_stmnt_list:
- /* empty */
- | stmnt_list
- ;
-
-stmnt_list:
- stmnt {
- clrwflgs();
- }
- | stmnt_list stmnt {
- clrwflgs();
- }
- | stmnt_list error T_SEMI {
- clrwflgs();
- }
- ;
-
-expr_stmnt:
- expr T_SEMI {
- expr($1, 0, 0);
- estmnt = 0;
- ftflg = 0;
- }
- | T_SEMI {
- estmnt = 1;
- ftflg = 0;
- }
- ;
-
-selection_stmnt:
- if_without_else {
- if2();
- if3(0);
- }
- | if_without_else T_ELSE {
- if2();
- } stmnt {
- if (estmnt) {
- /* empty body of the else statement */
- warning(316);
- }
-
- if3(1);
- }
- | if_without_else T_ELSE error {
- if3(0);
- }
- | switch_expr stmnt {
- switch2();
- }
- | switch_expr error {
- switch2();
- }
- ;
-
-if_without_else:
- if_expr stmnt {
- if (estmnt) {
- /* empty body of the if statement */
- warning(315);
- }
- }
- | if_expr error
- ;
-
-if_expr:
- T_IF T_LPARN expr T_RPARN {
- if1($3);
- clrwflgs();
- }
- ;
-
-switch_expr:
- T_SWITCH T_LPARN expr T_RPARN {
- switch1($3);
- clrwflgs();
- }
- ;
-
-iteration_stmnt:
- while_expr stmnt {
- while2();
- }
- | while_expr error {
- while2();
- }
- | do stmnt do_while_expr {
- do2($3);
- ftflg = 0;
- }
- | do error {
- do2(NULL);
- }
- | for_exprs stmnt {
- for2();
- }
- | for_exprs error {
- for2();
- }
- ;
-
-while_expr:
- T_WHILE T_LPARN expr T_RPARN {
- while1($3);
- clrwflgs();
- }
- ;
-
-do:
- T_DO {
- do1();
- }
- ;
-
-do_while_expr:
- T_WHILE T_LPARN expr T_RPARN T_SEMI {
- $$ = $3;
- }
- ;
-
-for_exprs:
- T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
- for1($3, $5, $7);
- clrwflgs();
- }
- ;
-
-opt_expr:
- /* empty */ {
- $$ = NULL;
- }
- | expr {
- $$ = $1;
- }
- ;
-
-jump_stmnt:
- goto identifier T_SEMI {
- dogoto(getsym($2));
- }
- | goto error T_SEMI {
- symtyp = FVFT;
- }
- | T_CONTINUE T_SEMI {
- docont();
- }
- | T_BREAK T_SEMI {
- dobreak();
- }
- | T_RETURN T_SEMI {
- doreturn(NULL);
- }
- | T_RETURN expr T_SEMI {
- doreturn($2);
- }
- ;
-
-goto:
- T_GOTO {
- symtyp = FLAB;
- }
- ;
-
-asm_stmnt:
- T_ASM T_LPARN read_until_rparn T_SEMI {
- setasm();
- }
- | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
- setasm();
- }
- | T_ASM error
- ;
-
-read_until_rparn:
- /* empty */ {
- ignuptorp();
- }
- ;
-
-declaration_list:
- declaration {
- clrwflgs();
- }
- | declaration_list declaration {
- clrwflgs();
- }
- ;
-
-constant:
- expr %prec T_COMMA {
- $$ = $1;
- }
- ;
-
-expr:
- expr T_MULT expr {
- $$ = build(MULT, $1, $3);
- }
- | expr T_DIVOP expr {
- $$ = build($2, $1, $3);
- }
- | expr T_ADDOP expr {
- $$ = build($2, $1, $3);
- }
- | expr T_SHFTOP expr {
- $$ = build($2, $1, $3);
- }
- | expr T_RELOP expr {
- $$ = build($2, $1, $3);
- }
- | expr T_EQOP expr {
- $$ = build($2, $1, $3);
- }
- | expr T_AND expr {
- $$ = build(AND, $1, $3);
- }
- | expr T_XOR expr {
- $$ = build(XOR, $1, $3);
- }
- | expr T_OR expr {
- $$ = build(OR, $1, $3);
- }
- | expr T_LOGAND expr {
- $$ = build(LOGAND, $1, $3);
- }
- | expr T_LOGOR expr {
- $$ = build(LOGOR, $1, $3);
- }
- | expr T_QUEST expr T_COLON expr {
- $$ = build(QUEST, $1, build(COLON, $3, $5));
- }
- | expr T_ASSIGN expr {
- $$ = build(ASSIGN, $1, $3);
- }
- | expr T_OPASS expr {
- $$ = build($2, $1, $3);
- }
- | expr T_COMMA expr {
- $$ = build(COMMA, $1, $3);
- }
- | term {
- $$ = $1;
- }
- ;
-
-term:
- T_NAME {
- /* XXX really necessary? */
- if (yychar < 0)
- yychar = yylex();
- $$ = getnnode(getsym($1), yychar);
- }
- | string {
- $$ = getsnode($1);
- }
- | T_CON {
- $$ = getcnode(gettyp($1->v_tspec), $1);
- }
- | T_LPARN expr T_RPARN {
- if ($2 != NULL)
- $2->tn_parn = 1;
- $$ = $2;
- }
- | term T_INCDEC {
- $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
- }
- | T_INCDEC term {
- $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
- }
- | T_MULT term {
- $$ = build(STAR, $2, NULL);
- }
- | T_AND term {
- $$ = build(AMPER, $2, NULL);
- }
- | T_UNOP term {
- $$ = build($1, $2, NULL);
- }
- | T_ADDOP term {
- $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
- }
- | term T_LBRACK expr T_RBRACK {
- $$ = build(STAR, build(PLUS, $1, $3), NULL);
- }
- | term T_LPARN T_RPARN {
- $$ = funccall($1, NULL);
- }
- | term T_LPARN func_arg_list T_RPARN {
- $$ = funccall($1, $3);
- }
- | term point_or_arrow T_NAME {
- if ($1 != NULL) {
- sym_t *msym;
- /* XXX strmemb should be integrated in build() */
- if ($2 == ARROW) {
- /* must to this before strmemb is called */
- $1 = cconv($1);
- }
- msym = strmemb($1, $2, getsym($3));
- $$ = build($2, $1, getnnode(msym, 0));
- } else {
- $$ = NULL;
- }
- }
- | T_SIZEOF term %prec T_SIZEOF {
- if (($$ = $2 == NULL ? NULL : bldszoftrm($2)) != NULL)
- chkmisc($2, 0, 0, 0, 0, 0, 1);
- }
- | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
- $$ = bldszof($3);
- }
- | T_LPARN type_name T_RPARN term %prec T_UNOP {
- $$ = cast($4, $2);
- }
- ;
-
-string:
- T_STRING {
- $$ = $1;
- }
- | T_STRING string2 {
- $$ = catstrg($1, $2);
- }
- ;
-
-string2:
- T_STRING {
- $$ = $1;
- }
- | string2 T_STRING {
- $$ = catstrg($1, $2);
- }
- ;
-
-func_arg_list:
- expr %prec T_COMMA {
- $$ = funcarg(NULL, $1);
- }
- | func_arg_list T_COMMA expr {
- $$ = funcarg($1, $3);
- }
- ;
-
-point_or_arrow:
- T_STROP {
- symtyp = FMOS;
- $$ = $1;
- }
- ;
-
-identifier:
- T_NAME {
- $$ = $1;
- }
- | T_TYPENAME {
- $$ = $1;
- }
- ;
-
-%%
-
-/* ARGSUSED */
-int
-yyerror(char *msg)
-{
- error(249);
- if (++sytxerr >= 5)
- norecover();
- return (0);
-}
-
-/*
- * Gets a node for a constant and returns the value of this constant
- * as integer.
- * Is the node not constant or too large for int or of type float,
- * a warning will be printed.
- *
- * toicon() should be used only inside declarations. If it is used in
- * expressions, it frees the memory used for the expression.
- */
-static int
-toicon(tnode_t *tn)
-{
- int i;
- tspec_t t;
- val_t *v;
-
- v = constant(tn);
-
- /*
- * Abstract declarations are used inside expression. To free
- * the memory would be a fatal error.
- */
- if (dcs->d_ctx != ABSTRACT)
- tfreeblk();
-
- if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
- i = (int)v->v_ldbl;
- /* integral constant expression expected */
- error(55);
- } else {
- i = (int)v->v_quad;
- if (isutyp(t)) {
- if ((u_quad_t)v->v_quad > UINT_MAX) {
- /* integral constant too large */
- warning(56);
- }
- } else {
- if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
- /* integral constant too large */
- warning(56);
- }
- }
- }
- free(v);
- return (i);
-}
-
-static void
-idecl(sym_t *decl, int initflg)
-{
- initerr = 0;
- initsym = decl;
-
- if (usedflg)
- setuflg(decl, 0, 0);
-
- switch (dcs->d_ctx) {
- case EXTERN:
- decl1ext(decl, initflg);
- break;
- case ARG:
- (void)decl1arg(decl, initflg);
- break;
- case AUTO:
- decl1loc(decl, initflg);
- break;
- default:
- lerror("idecl()");
- }
-
- if (initflg && !initerr)
- prepinit();
-}
-
-/*
- * Discard all input tokens up to and including the next
- * unmatched right paren
- */
-void
-ignuptorp(void)
-{
- int level;
-
- if (yychar < 0)
- yychar = yylex();
- freeyyv(&yylval, yychar);
-
- level = 1;
- while (yychar != T_RPARN || --level > 0) {
- if (yychar == T_LPARN) {
- level++;
- } else if (yychar <= 0) {
- break;
- }
- freeyyv(&yylval, yychar = yylex());
- }
-
- yyclearin;
-}
diff --git a/usr.bin/xlint/lint1/decl.c b/usr.bin/xlint/lint1/decl.c
deleted file mode 100644
index c40ba5b47db..00000000000
--- a/usr.bin/xlint/lint1/decl.c
+++ /dev/null
@@ -1,3140 +0,0 @@
-/* $OpenBSD: decl.c,v 1.30 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <complex.h>
-
-#include "lint1.h"
-
-const char *unnamed = "<unnamed>";
-
-/* contains various information and classification on types */
-ttab_t ttab[NTSPEC];
-
-/* shared type structures for arithmetic types and void */
-static type_t *typetab;
-
-/* value of next enumerator during declaration of enum types */
-int enumval;
-
-/*
- * pointer to top element of a stack which contains informations local
- * to nested declarations
- */
-dinfo_t *dcs;
-
-static type_t *tdeferr(type_t *, tspec_t);
-static void settdsym(type_t *, sym_t *);
-static tspec_t mrgtspec(tspec_t, tspec_t);
-static void align(int, int);
-static sym_t *newtag(sym_t *, scl_t, int, int);
-static int eqargs(type_t *, type_t *, int *);
-static int mnoarg(type_t *, int *);
-static int chkosdef(sym_t *, sym_t *);
-static int chkptdecl(sym_t *, sym_t *);
-static sym_t *nsfunc(sym_t *, sym_t *);
-static void osfunc(sym_t *, sym_t *);
-static void ledecl(sym_t *);
-static int chkinit(sym_t *);
-static void chkausg(int, sym_t *);
-static void chkvusg(int, sym_t *);
-static void chklusg(sym_t *);
-static void chktusg(sym_t *);
-static void chkglvar(sym_t *);
-static void glchksz(sym_t *);
-
-/*
- * initializes all global vars used in declarations
- */
-void
-initdecl(void)
-{
- int i;
- static struct {
- tspec_t it_tspec;
- ttab_t it_ttab;
- } ittab[] = {
- { SIGNED, { 0, 0, 0,
- SIGNED, UNSIGN,
- 0, 0, 0, 0, 0, "signed" } },
- { UNSIGN, { 0, 0, 0,
- SIGNED, UNSIGN,
- 0, 0, 0, 0, 0, "unsigned" } },
- { BOOL, { sizeof (_Bool) * CHAR_BIT, CHAR_BIT, 1,
- BOOL, BOOL,
- 1, 1, 0, 1, 1, "_Bool" } },
- { CHAR, { CHAR_BIT, CHAR_BIT, 20,
- SCHAR, UCHAR,
- 1, 0, 0, 1, 1, "char" } },
- { SCHAR, { CHAR_BIT, CHAR_BIT, 20,
- SCHAR, UCHAR,
- 1, 0, 0, 1, 1, "signed char" } },
- { UCHAR, { CHAR_BIT, CHAR_BIT, 20,
- SCHAR, UCHAR,
- 1, 1, 0, 1, 1, "unsigned char" } },
- { SHORT, { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT, 30,
- SHORT, USHORT,
- 1, 0, 0, 1, 1, "short" } },
- { USHORT, { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT, 30,
- SHORT, USHORT,
- 1, 1, 0, 1, 1, "unsigned short" } },
- { INT, { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
- INT, UINT,
- 1, 0, 0, 1, 1, "int" } },
- { UINT, { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT, 40,
- INT, UINT,
- 1, 1, 0, 1, 1, "unsigned int" } },
- { LONG, { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT, 50,
- LONG, ULONG,
- 1, 0, 0, 1, 1, "long" } },
- { ULONG, { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT, 50,
- LONG, ULONG,
- 1, 1, 0, 1, 1, "unsigned long" } },
- { QUAD, { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
- QUAD, UQUAD,
- 1, 0, 0, 1, 1, "long long" } },
- { UQUAD, { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
- QUAD, UQUAD,
- 1, 1, 0, 1, 1, "unsigned long long" } },
- { FLOAT, { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT, -1,
- FLOAT, FLOAT,
- 0, 0, 1, 1, 1, "float" } },
- { DOUBLE, { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT, -1,
- DOUBLE, DOUBLE,
- 0, 0, 1, 1, 1, "double" } },
- { LDOUBLE, { sizeof (ldbl_t) * CHAR_BIT, 16 * CHAR_BIT, -1,
- LDOUBLE, LDOUBLE,
- 0, 0, 1, 1, 1, "long double" } },
- { COMPLEX, { sizeof (float _Complex) * CHAR_BIT,
- 8 * CHAR_BIT, -1,
- COMPLEX, COMPLEX,
- 0, 0, 1, 1, 3, "float _Complex" } },
- { DCOMPLEX, { sizeof (double _Complex) * CHAR_BIT,
- 16 * CHAR_BIT, -1,
- DCOMPLEX, DCOMPLEX,
- 0, 0, 1, 1, 3, "double _Complex" } },
- { LDCOMPLEX,{ sizeof (long double _Complex) * CHAR_BIT,
- 32 * CHAR_BIT, -1,
- LDCOMPLEX, LDCOMPLEX,
- 0, 0, 1, 1, 3, "long double _Complex" } },
-#if 0
- { IMAGINARY,{ sizeof (float _Imaginary) * CHAR_BIT,
- 4 * CHAR_BIT, -1,
- IMAGINARY, IMAGINARY,
- 0, 0, 1, 1, 2, "float _Imaginary" } },
- { DIMAGINARY,{ sizeof (double _Imaginary) * CHAR_BIT,
- 8 * CHAR_BIT, -1,
- DIMAGINARY, DIMAGINARY,
- 0, 0, 1, 1, 2, "double _Imaginary" } },
- { LDIMAGINARY,{ sizeof (long double _Imaginary) * CHAR_BIT,
- 16 * CHAR_BIT, -1,
- LDIMAGINARY, LDIMAGINARY,
- 0, 0, 1, 1, 2, "long double _Imaginary" } },
-#endif
- { VOID, { -1, -1, -1,
- VOID, VOID,
- 0, 0, 0, 0, 0, "void" } },
- { STRUCT, { -1, -1, -1,
- STRUCT, STRUCT,
- 0, 0, 0, 0, 0, "struct" } },
- { UNION, { -1, -1, -1,
- UNION, UNION,
- 0, 0, 0, 0, 0, "union" } },
- { ENUM, { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
- ENUM, ENUM,
- 1, 0, 0, 1, 1, "enum" } },
- { PTR, { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT, -1,
- PTR, PTR,
- 0, 1, 0, 0, 1, "pointer" } },
- { ARRAY, { -1, -1, -1,
- ARRAY, ARRAY,
- 0, 0, 0, 0, 0, "array" } },
- { FUNC, { -1, -1, -1,
- FUNC, FUNC,
- 0, 0, 0, 0, 0, "function" } },
- };
-
- /* declaration stack */
- dcs = xcalloc(1, sizeof (dinfo_t));
- dcs->d_ctx = EXTERN;
- dcs->d_ldlsym = &dcs->d_dlsyms;
-
- /* type information and classification */
- for (i = 0; i < sizeof (ittab) / sizeof (ittab[0]); i++)
- STRUCT_ASSIGN(ttab[ittab[i].it_tspec], ittab[i].it_ttab);
- if (!pflag) {
- for (i = 0; i < NTSPEC; i++)
- ttab[i].tt_psz = ttab[i].tt_sz;
- }
-
- /* shared type structures */
- typetab = xcalloc(NTSPEC, sizeof (type_t));
- for (i = 0; i < NTSPEC; i++)
- typetab[i].t_tspec = NOTSPEC;
- typetab[BOOL].t_tspec = BOOL;
- typetab[CHAR].t_tspec = CHAR;
- typetab[SCHAR].t_tspec = SCHAR;
- typetab[UCHAR].t_tspec = UCHAR;
- typetab[SHORT].t_tspec = SHORT;
- typetab[USHORT].t_tspec = USHORT;
- typetab[INT].t_tspec = INT;
- typetab[UINT].t_tspec = UINT;
- typetab[LONG].t_tspec = LONG;
- typetab[ULONG].t_tspec = ULONG;
- typetab[QUAD].t_tspec = QUAD;
- typetab[UQUAD].t_tspec = UQUAD;
- typetab[FLOAT].t_tspec = FLOAT;
- typetab[DOUBLE].t_tspec = DOUBLE;
- typetab[LDOUBLE].t_tspec = LDOUBLE;
- typetab[COMPLEX].t_tspec = COMPLEX;
- typetab[DCOMPLEX].t_tspec = DCOMPLEX;
- typetab[LDCOMPLEX].t_tspec = LDCOMPLEX;
- typetab[IMAGINARY].t_tspec = IMAGINARY;
- typetab[DIMAGINARY].t_tspec = DIMAGINARY;
- typetab[LDIMAGINARY].t_tspec = LDIMAGINARY;
- typetab[VOID].t_tspec = VOID;
- /*
- * Next two are not real types. They are only used by the parser
- * to return keywords "signed" and "unsigned"
- */
- typetab[SIGNED].t_tspec = SIGNED;
- typetab[UNSIGN].t_tspec = UNSIGN;
-}
-
-/*
- * Returns a shared type structure for arithmetic types and void.
- *
- * It's important to duplicate this structure (using duptyp() or tduptyp())
- * if it is to be modified (adding qualifiers or anything else).
- */
-type_t *
-gettyp(tspec_t t)
-{
- return (&typetab[t]);
-}
-
-type_t *
-duptyp(const type_t *tp)
-{
- type_t *ntp;
-
- ntp = getblk(sizeof (type_t));
- STRUCT_ASSIGN(*ntp, *tp);
- return (ntp);
-}
-
-/*
- * Use tduptyp() instead of duptyp() inside expressions (if the
- * allocated memory should be freed after the expr).
- */
-type_t *
-tduptyp(const type_t *tp)
-{
- type_t *ntp;
-
- ntp = tgetblk(sizeof (type_t));
- STRUCT_ASSIGN(*ntp, *tp);
- return (ntp);
-}
-
-/*
- * Returns 1 if the argument is void or an incomplete array,
- * struct, union or enum type.
- */
-int
-incompl(type_t *tp)
-{
- tspec_t t;
-
- if ((t = tp->t_tspec) == VOID) {
- return (1);
- } else if (t == ARRAY) {
- return (tp->t_aincompl);
- } else if (t == STRUCT || t == UNION) {
- return (tp->t_str->sincompl);
- } else if (t == ENUM) {
- return (tp->t_enum->eincompl);
- }
- return (0);
-}
-
-/*
- * Set the flag for (in)complete array, struct, union or enum
- * types.
- */
-void
-setcompl(type_t *tp, int ic)
-{
- tspec_t t;
-
- if ((t = tp->t_tspec) == ARRAY) {
- tp->t_aincompl = ic;
- } else if (t == STRUCT || t == UNION) {
- tp->t_str->sincompl = ic;
- } else {
- if (t != ENUM)
- lerror("setcompl() 1");
- tp->t_enum->eincompl = ic;
- }
-}
-
-/*
- * Remember the storage class of the current declaration in dcs->d_scl
- * (the top element of the declaration stack) and detect multiple
- * storage classes.
- */
-void
-addscl(scl_t sc)
-{
- if (sc == INLINE) {
- if (dcs->d_inline)
- /* duplicate '%s' */
- warning(10, "inline");
- dcs->d_inline = 1;
- return;
- }
- if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
- dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) {
- /* storage class after type is obsolescent */
- warning(83);
- }
- if (dcs->d_scl == NOSCL) {
- dcs->d_scl = sc;
- } else {
- /*
- * multiple storage classes. An error will be reported in
- * deftyp().
- */
- dcs->d_mscl = 1;
- }
-}
-
-/*
- * Remember the type, modifier or typedef name returned by the parser
- * in *dcs (top element of decl stack). This information is used in
- * deftyp() to build the type used for all declarators in this
- * declaration.
- *
- * Is tp->t_typedef 1, the type comes from a previously defined typename.
- * Otherwise it comes from a type specifier (int, long, ...) or a
- * struct/union/enum tag.
- */
-void
-addtype(type_t *tp)
-{
- tspec_t t;
-
- if (tp->t_typedef) {
- if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
- dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC ||
- dcs->d_dmod != NOTSPEC) {
- /*
- * something like "typedef int a; int a b;"
- * This should not happen with current grammar.
- */
- lerror("addtype()");
- }
- dcs->d_type = tp;
- return;
- }
-
- t = tp->t_tspec;
-
- if (t == STRUCT || t == UNION || t == ENUM) {
- /*
- * something like "int struct a ..."
- * struct/union/enum with anything else is not allowed
- */
- if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
- dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC ||
- dcs->d_dmod != NOTSPEC) {
- /*
- * remember that an error must be reported in
- * deftyp().
- */
- dcs->d_terr = 1;
- dcs->d_atyp = dcs->d_smod = dcs->d_lmod =
- dcs->d_dmod = NOTSPEC;
- }
- dcs->d_type = tp;
- return;
- }
-
- if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
- /*
- * something like "struct a int"
- * struct/union/enum with anything else is not allowed
- */
- dcs->d_terr = 1;
- return;
- }
-
- if (t == LONG && dcs->d_lmod == LONG) {
- /* "long long" or "long ... long" */
- t = QUAD;
- dcs->d_lmod = NOTSPEC;
- if (!quadflg)
- /* %s C does not support 'long long' */
- (void)gnuism(265, "ANSI");
- }
-
- if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
- /* something like "typedef int a; a long ..." */
- dcs->d_type = tdeferr(dcs->d_type, t);
- return;
- }
-
- /* now it can be only a combination of arithmetic types and void */
- if (t == SIGNED || t == UNSIGN) {
- /* remeber specifiers "signed" and "unsigned" in dcs->d_smod */
- if (dcs->d_smod != NOTSPEC)
- /*
- * more than one "signed" and/or "unsigned"; print
- * an error in deftyp()
- */
- dcs->d_terr = 1;
- dcs->d_smod = t;
- } else if (t == SHORT || t == LONG || t == QUAD) {
- /*
- * remember specifiers "short", "long" and "long long" in
- * dcs->d_lmod
- */
- if (dcs->d_lmod != NOTSPEC)
- /* more than one, print error in deftyp() */
- dcs->d_terr = 1;
- dcs->d_lmod = t;
- } else if (t == COMPLEX || t == IMAGINARY) {
- /*
- * remember specifiers "_Complex" and "_Imaginary" in
- * dcs->d_dmod
- */
- if (dcs->d_dmod != NOTSPEC)
- /* more than one, print error in deftyp() */
- dcs->d_terr = 1;
- dcs->d_dmod = t;
- } else {
- /*
- * remember specifiers "void", "char", "int", "float" or
- * "double" int dcs->d_atyp
- */
- if (dcs->d_atyp != NOTSPEC)
- /* more than one, print error in deftyp() */
- dcs->d_terr = 1;
- dcs->d_atyp = t;
- }
-}
-
-/*
- * called if a list of declaration specifiers contains a typedef name
- * and other specifiers (except struct, union, enum, typedef name)
- */
-static type_t *
-tdeferr(type_t *td, tspec_t t)
-{
- tspec_t t2;
-
- t2 = td->t_tspec;
-
- switch (t) {
- case SIGNED:
- case UNSIGN:
- if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG ||
- t2 == QUAD) {
- /* modifying typedef with ... */
- warning(5, ttab[t].tt_name);
- td = duptyp(gettyp(mrgtspec(t2, t)));
- td->t_typedef = 1;
- return (td);
- }
- break;
- case SHORT:
- if (t2 == INT || t2 == UINT) {
- /* modifying typedef with ... */
- warning(5, "short");
- td = duptyp(gettyp(t2 == INT ? SHORT : USHORT));
- td->t_typedef = 1;
- return (td);
- }
- break;
- case LONG:
- if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
- t2 == FLOAT || t2 == DOUBLE || t2 == COMPLEX ||
- t2 == IMAGINARY) {
- /* modifying typedef with ... */
- warning(5, "long");
- if (t2 == INT) {
- td = gettyp(LONG);
- } else if (t2 == UINT) {
- td = gettyp(ULONG);
- } else if (t2 == LONG) {
- td = gettyp(QUAD);
- } else if (t2 == ULONG) {
- td = gettyp(UQUAD);
- } else if (t2 == FLOAT) {
- td = gettyp(DOUBLE);
- } else if (t2 == DOUBLE) {
- td = gettyp(LDOUBLE);
- } else if (t2 == COMPLEX) {
- td = gettyp(DCOMPLEX);
- } else if (t2 == DCOMPLEX) {
- td = gettyp(LDCOMPLEX);
- } else if (t2 == IMAGINARY) {
- td = gettyp(DIMAGINARY);
- } else if (t2 == DIMAGINARY) {
- td = gettyp(LDIMAGINARY);
- }
- td = duptyp(td);
- td->t_typedef = 1;
- return (td);
- }
- break;
- /* LINTED (enumeration values not handled in switch) */
- }
-
- /* Anything other is not accepted. */
-
- dcs->d_terr = 1;
- return (td);
-}
-
-/*
- * Remember the symbol of a typedef name (2nd arg) in a struct, union
- * or enum tag if the typedef name is the first defined for this tag.
- *
- * If the tag is unnamed, the typdef name is used for identification
- * of this tag in lint2. Although its possible that more than one typedef
- * name is defined for one tag, the first name defined should be unique
- * if the tag is unnamed.
- */
-static void
-settdsym(type_t *tp, sym_t *sym)
-{
- tspec_t t;
-
- if ((t = tp->t_tspec) == STRUCT || t == UNION) {
- if (tp->t_str->stdef == NULL)
- tp->t_str->stdef = sym;
- } else if (t == ENUM) {
- if (tp->t_enum->etdef == NULL)
- tp->t_enum->etdef = sym;
- }
-}
-
-/*
- * Remember a qualifier which is part of the declaration specifiers
- * (and not the declarator) in the top element of the declaration stack.
- * Also detect multiple qualifiers of the same kind.
-
- * The remembered qualifier is used by deftyp() to construct the type
- * for all declarators.
- */
-void
-addqual(tqual_t q)
-{
- if (q == CONST) {
- if (dcs->d_const) {
- /* duplicate "%s" */
- warning(10, "const");
- }
- dcs->d_const = 1;
- } else if (q == VOLATILE) {
- if (dcs->d_volatile) {
- /* duplicate "%s" */
- warning(10, "volatile");
- }
- dcs->d_volatile = 1;
- } else if (q == RESTRICT) {
- if (dcs->d_restrict) {
- /* duplicate "%s" */
- warning(10, "restrict");
- }
- dcs->d_restrict = 1;
- } else
- lerror("addqual() 1");
-}
-
-/*
- * Go to the next declaration level (structs, nested structs, blocks,
- * argument declaration lists ...)
- */
-void
-pushdecl(scl_t sc)
-{
- dinfo_t *di;
-
- if (dflag)
- (void)printf("pushdecl(%d)\n", (int)sc);
-
- /* put a new element on the declaration stack */
- di = xcalloc(1, sizeof (dinfo_t));
- di->d_nxt = dcs;
- dcs = di;
- di->d_ctx = sc;
- di->d_ldlsym = &di->d_dlsyms;
-}
-
-/*
- * Go back to previous declaration level
- */
-void
-popdecl(void)
-{
- dinfo_t *di;
-
- if (dflag)
- (void)printf("popdecl(%d)\n", (int)dcs->d_ctx);
-
- if (dcs->d_nxt == NULL)
- lerror("popdecl() 1");
- di = dcs;
- dcs = di->d_nxt;
- switch (di->d_ctx) {
- case EXTERN:
- /* there is nothing after external declarations */
- lerror("popdecl() 2");
- /* NOTREACHED */
- case MOS:
- case MOU:
- case ENUMCON:
- /*
- * Symbols declared in (nested) structs or enums are
- * part of the next level (they are removed from the
- * symbol table if the symbols of the outher level are
- * removed)
- */
- if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
- dcs->d_ldlsym = di->d_ldlsym;
- break;
- case ARG:
- /*
- * All symbols in dcs->d_dlsyms are introduced in old style
- * argument declarations (it's not clean, but possible).
- * They are appended to the list of symbols declared in
- * an old style argument identifier list or a new style
- * parameter type list.
- */
- if (di->d_dlsyms != NULL) {
- *di->d_ldlsym = dcs->d_fpsyms;
- dcs->d_fpsyms = di->d_dlsyms;
- }
- break;
- case ABSTRACT:
- /*
- * casts and sizeof
- * Append all symbols declared in the abstract declaration
- * to the list of symbols declared in the surounding decl.
- * or block.
- * XXX I'm not sure whether they should be removed from the
- * symbol table now or later.
- */
- if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
- dcs->d_ldlsym = di->d_ldlsym;
- break;
- case AUTO:
- /* check usage of local vars */
- chkusage(di);
- /* FALLTHROUGH */
- case PARG:
- /* usage of arguments will be checked by funcend() */
- rmsyms(di->d_dlsyms);
- break;
- default:
- lerror("popdecl() 3");
- }
- free(di);
-}
-
-/*
- * Set flag d_asm in all declaration stack elements up to the
- * outermost one.
- *
- * This is used to mark compound statements which have, possibly in
- * nested compound statements, asm statements. For these compound
- * statements no warnings about unused or unitialized variables are
- * printed.
- *
- * There is no need to clear d_asm in dinfo structs with context AUTO,
- * because these structs are freed at the end of the compound statement.
- * But it must be cleard in the outermost dinfo struct, which has
- * context EXTERN. This could be done in clrtyp() and would work for
- * C, but not for C++ (due to mixed statements and declarations). Thus
- * we clear it in glclup(), which is used to do some cleanup after
- * global declarations/definitions.
- */
-void
-setasm(void)
-{
- dinfo_t *di;
-
- for (di = dcs; di != NULL; di = di->d_nxt)
- di->d_asm = 1;
-}
-
-/*
- * Clean all elements of the top element of declaration stack which
- * will be used by the next declaration
- */
-void
-clrtyp(void)
-{
- dcs->d_atyp = dcs->d_smod = dcs->d_lmod = dcs->d_dmod = NOTSPEC;
- dcs->d_scl = NOSCL;
- dcs->d_type = NULL;
- dcs->d_const = dcs->d_volatile = 0;
- dcs->d_inline = 0;
- dcs->d_mscl = dcs->d_terr = 0;
- dcs->d_nedecl = 0;
- dcs->d_notyp = 0;
-}
-
-/*
- * Merge the domain (_Complex or _Imaginary) into a type. Returns non-zero
- * if the merge doesn't make sense. e.g., no "int _Complex".
- */
-int
-mergedomain(tspec_t *tp, tspec_t domain)
-{
- if (domain == NOTSPEC)
- return (0);
- if (domain != COMPLEX && domain != IMAGINARY)
- lerror("mergedomain()");
- switch (*tp) {
- case FLOAT:
- *tp = domain;
- break;
- case DOUBLE:
- *tp = domain == COMPLEX ? DCOMPLEX : DIMAGINARY;
- break;
- case LDOUBLE:
- *tp = domain == COMPLEX ? LDCOMPLEX : LDIMAGINARY;
- break;
- default:
- return (1);
- }
- return (0);
-}
-
-/*
- * Create a type structure from the informations gathered in
- * the declaration stack.
- * Complain about storage classes which are not possible in current
- * context.
- */
-void
-deftyp(void)
-{
- tspec_t t, s, l, d;
- type_t *tp;
- scl_t scl;
-
- t = dcs->d_atyp; /* BOOL, CHAR, INT, FLOAT,
- DOUBLE, VOID */
- s = dcs->d_smod; /* SIGNED, UNSIGNED */
- l = dcs->d_lmod; /* SHORT, LONG, QUAD */
- d = dcs->d_dmod; /* COMPLEX, IMAGINARY */
- tp = dcs->d_type;
- scl = dcs->d_scl;
-
- if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && tp == NULL)
- dcs->d_notyp = 1;
-
- if (tp != NULL && (t != NOTSPEC || s != NOTSPEC || l != NOTSPEC)) {
- /* should never happen */
- lerror("deftyp() 1");
- }
-
- if (tp == NULL) {
- switch (t) {
- case NOTSPEC:
- t = INT;
- /* FALLTHROUGH */
- case BOOL:
- break;
- case INT:
- if (s == NOTSPEC)
- s = SIGNED;
- break;
- case CHAR:
- if (l != NOTSPEC) {
- dcs->d_terr = 1;
- l = NOTSPEC;
- }
- break;
- case FLOAT:
- if (l == LONG) {
- l = NOTSPEC;
- t = DOUBLE;
- /* use 'double' instead of ... */
- warning(6);
- }
- break;
- case DOUBLE:
- if (l == LONG) {
- l = NOTSPEC;
- t = LDOUBLE;
- }
- break;
- case VOID:
- break;
- default:
- lerror("deftyp() 2");
- }
- if (mergedomain(&t, d))
- dcs->d_terr = 1;
- if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
- dcs->d_terr = 1;
- l = s = NOTSPEC;
- }
- if (l != NOTSPEC)
- t = l;
- dcs->d_type = gettyp(mrgtspec(t, s));
- }
-
- if (dcs->d_mscl) {
- /* only one storage class allowed */
- error(7);
- }
- if (dcs->d_terr) {
- /* illegal type combination */
- error(4);
- }
-
- if (dcs->d_ctx == EXTERN) {
- if (scl == REG || scl == AUTO) {
- /* illegal storage class */
- error(8);
- scl = NOSCL;
- }
- } else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) {
- if (scl != NOSCL && scl != REG) {
- /* only "register" valid ... */
- error(9);
- scl = NOSCL;
- }
- }
-
- dcs->d_scl = scl;
-
- if (dcs->d_const && dcs->d_type->t_const) {
- if (!dcs->d_type->t_typedef)
- lerror("deftyp() 3");
- /* typedef already qualified with "%s" */
- warning(68, "const");
- }
- if (dcs->d_volatile && dcs->d_type->t_volatile) {
- if (!dcs->d_type->t_typedef)
- lerror("deftyp() 4");
- /* typedef already qualified with "%s" */
- warning(68, "volatile");
- }
-
- if (dcs->d_const || dcs->d_volatile) {
- dcs->d_type = duptyp(dcs->d_type);
- dcs->d_type->t_const |= dcs->d_const;
- dcs->d_type->t_volatile |= dcs->d_volatile;
- }
-}
-
-/*
- * Merge type specifiers (char, ..., long long, signed, unsigned).
- */
-static tspec_t
-mrgtspec(tspec_t t, tspec_t s)
-{
- if (s == SIGNED || s == UNSIGN) {
- if (t == CHAR) {
- t = s == SIGNED ? SCHAR : UCHAR;
- } else if (t == SHORT) {
- t = s == SIGNED ? SHORT : USHORT;
- } else if (t == INT) {
- t = s == SIGNED ? INT : UINT;
- } else if (t == LONG) {
- t = s == SIGNED ? LONG : ULONG;
- } else if (t == QUAD) {
- t = s == SIGNED ? QUAD : UQUAD;
- }
- }
-
- return (t);
-}
-
-/*
- * Return the length of a type in bit.
- *
- * Printing a message if the outhermost dimension of an array is 0 must
- * be done by the caller. All other problems are reported by length()
- * if name is not NULL.
- */
-int
-length(type_t *tp, const char *name)
-{
- int elem, elsz;
-
- elem = 1;
- while (tp && tp->t_tspec == ARRAY) {
- elem *= tp->t_dim;
- tp = tp->t_subt;
- }
- if (tp == NULL)
- return (-1);
-
- switch (tp->t_tspec) {
- case FUNC:
- /* compiler takes size of function */
- lerror(msgs[12]);
- /* NOTREACHED */
- case STRUCT:
- case UNION:
- if (incompl(tp) && name != NULL) {
- /* incomplete structure or union %s: %s */
- error(31, tp->t_str->stag->s_name, name);
- }
- elsz = tp->t_str->size;
- break;
- case ENUM:
- if (incompl(tp) && name != NULL) {
- /* incomplete enum type: %s */
- warning(13, name);
- }
- /* FALLTHROUGH */
- default:
- elsz = size(tp->t_tspec);
- if (elsz <= 0)
- lerror("length()");
- break;
- }
- return (elem * elsz);
-}
-
-/*
- * Get the alignment of the given type in bits.
- */
-int
-getbound(type_t *tp)
-{
- int a;
- tspec_t t;
-
- while (tp && tp->t_tspec == ARRAY)
- tp = tp->t_subt;
-
- if (tp == NULL)
- return (-1);
-
- if ((t = tp->t_tspec) == STRUCT || t == UNION) {
- a = tp->t_str->align;
- } else if (t == FUNC) {
- /* compiler takes alignment of function */
- error(14);
- a = ALIGN(1) * CHAR_BIT;
- } else {
- if ((a = size(t)) == 0) {
- a = CHAR_BIT;
- } else if (a > ALIGN(1) * CHAR_BIT) {
- a = ALIGN(1) * CHAR_BIT;
- }
- }
- if (a < CHAR_BIT || a > ALIGN(1) * CHAR_BIT)
- lerror("getbound() 1");
- return (a);
-}
-
-/*
- * Concatenate two lists of symbols by s_nxt. Used by declarations of
- * struct/union/enum elements and parameters.
- */
-sym_t *
-lnklst(sym_t *l1, sym_t *l2)
-{
- sym_t *l;
-
- if ((l = l1) == NULL)
- return (l2);
- while (l1->s_nxt != NULL)
- l1 = l1->s_nxt;
- l1->s_nxt = l2;
- return (l);
-}
-
-/*
- * Check if the type of the given symbol is valid and print an error
- * message if it is not.
- *
- * Invalid types are:
- * - arrays of incomlete types or functions
- * - functions returning arrays or functions
- * - void types other than type of function or pointer
- */
-void
-chktyp(sym_t *sym)
-{
- tspec_t to, t;
- type_t **tpp, *tp;
-
- tpp = &sym->s_type;
- to = NOTSPEC;
- while ((tp = *tpp) != NULL) {
- t = tp->t_tspec;
- /*
- * If this is the type of an old style function definition,
- * a better warning is printed in funcdef().
- */
- if (t == FUNC && !tp->t_proto &&
- !(to == NOTSPEC && sym->s_osdef)) {
- if (sflag && hflag)
- /* function declaration is not a prototype */
- warning(287);
- }
- if (to == FUNC) {
- if (t == FUNC || t == ARRAY) {
- /* function returns illegal type */
- error(15);
- if (t == FUNC) {
- *tpp = incref(*tpp, PTR);
- } else {
- *tpp = incref((*tpp)->t_subt, PTR);
- }
- return;
- } else if (tp->t_const || tp->t_volatile) {
- if (sflag) {
- /* function cannot return const... */
- warning(228);
- }
- }
- } if (to == ARRAY) {
- if (t == FUNC) {
- /* array of function is illegal */
- error(16);
- *tpp = gettyp(INT);
- return;
- } else if (t == ARRAY && tp->t_dim == 0) {
- /* null dimension */
- error(17);
- return;
- } else if (t == VOID) {
- /* illegal use of void */
- error(18);
- *tpp = gettyp(INT);
-#if 0 /* errors are produced by length() */
- } else if (incompl(tp)) {
- /* array of incomplete type */
- if (sflag) {
- error(301);
- } else {
- warning(301);
- }
-#endif
- }
- } else if (to == NOTSPEC && t == VOID) {
- if (dcs->d_ctx == PARG) {
- if (sym->s_scl != ABSTRACT) {
- if (sym->s_name == unnamed)
- lerror("chktyp()");
- /* void param cannot have name: %s */
- error(61, sym->s_name);
- *tpp = gettyp(INT);
- }
- } else if (dcs->d_ctx == ABSTRACT) {
- /* ok */
- } else if (sym->s_scl != TYPEDEF) {
- /* void type for %s */
- error(19, sym->s_name);
- *tpp = gettyp(INT);
- }
- }
- if (t == VOID && to != PTR) {
- if (tp->t_const || tp->t_volatile || tp->t_restrict) {
- /* inappropriate qualifiers with "void" */
- warning(69);
- tp->t_const = tp->t_volatile = 0;
- tp->t_restrict = 0;
- }
- }
- tpp = &tp->t_subt;
- to = t;
- }
-}
-
-/*
- * Process the declarator of a struct/union element.
- */
-sym_t *
-decl1str(sym_t *dsym)
-{
- type_t *tp;
- tspec_t t;
- int sz, o, len;
- scl_t sc;
-
- if ((sc = dsym->s_scl) != MOS && sc != MOU)
- lerror("decl1str() 1");
-
- if (dcs->d_rdcsym != NULL) {
- if ((sc = dcs->d_rdcsym->s_scl) != MOS && sc != MOU)
- /* should be ensured by storesym() */
- lerror("decl1str() 2");
- if (dsym->s_styp == dcs->d_rdcsym->s_styp) {
- /* duplicate member name: %s */
- error(33, dsym->s_name);
- rmsym(dcs->d_rdcsym);
- }
- }
-
- chktyp(dsym);
-
- t = (tp = dsym->s_type)->t_tspec;
-
- if (dsym->s_field) {
- /*
- * bit field
- *
- * only unsigned and signed int are portable bit-field types
- * (at least in ANSI C, in traditional C only unsigned int)
- */
- if (t == CHAR || t == UCHAR || t == SCHAR ||
- t == SHORT || t == USHORT || t == ENUM) {
- if (sflag) {
- /* bit-field type '%s' invalid in ANSI C */
- warning(273, tyname(tp));
- } else if (pflag) {
- /* nonportable bit-field type */
- warning(34);
- }
- if (isutyp(t))
- tp->t_tspec = UINT;
- else
- tp->t_tspec = INT;
-
- tp->t_isenum = 0;
- } else if (t == INT && dcs->d_smod == NOTSPEC) {
- if (pflag) {
- /* nonportable bit-field type */
- warning(34);
- }
- } else if (t != INT && t != UINT && t != LONG &&
- t != ULONG && t != QUAD && t != UQUAD && t != BOOL) {
- /* illegal bit-field type */
- error(35);
- sz = tp->t_flen;
- dsym->s_type = tp = duptyp(gettyp(t = INT));
- if ((tp->t_flen = sz) > size(t))
- tp->t_flen = size(t);
- }
- if ((len = tp->t_flen) < 0 || len > size(t)) {
- /* illegal bit-field size */
- error(36);
- tp->t_flen = size(t);
- } else if (len == 0 && dsym->s_name != unnamed) {
- /* zero size bit-field */
- error(37);
- tp->t_flen = size(t);
- }
- if (dsym->s_scl == MOU) {
- /* illegal use of bit-field */
- error(41);
- dsym->s_type->t_isfield = 0;
- dsym->s_field = 0;
- }
- } else if (t == FUNC) {
- /* function illegal in structure or union */
- error(38);
- dsym->s_type = tp = incref(tp, t = PTR);
- }
-
- /*
- * bit-fields of length 0 are not warned about because length()
- * does not return the length of the bit-field but the length
- * of the type the bit-field is packed in (its ok)
- */
- if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
- if (t == ARRAY && dsym->s_type->t_dim == 0) {
- /* illegal zero sized structure member: %s */
- warning(39, dsym->s_name);
- }
- }
-
- if (dcs->d_ctx == MOU) {
- o = dcs->d_offset;
- dcs->d_offset = 0;
- }
- if (dsym->s_field) {
- align(getbound(tp), tp->t_flen);
- dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t);
- tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
- dcs->d_offset += tp->t_flen;
- } else {
- align(getbound(tp), 0);
- dsym->s_value.v_quad = dcs->d_offset;
- dcs->d_offset += sz;
- }
- if (dcs->d_ctx == MOU) {
- if (o > dcs->d_offset)
- dcs->d_offset = o;
- }
-
- chkfdef(dsym, 0);
-
- return (dsym);
-}
-
-/*
- * Aligns next structure element as required.
- *
- * al contains the required alignment, len the length of a bit-field.
- */
-static void
-align(int al, int len)
-{
- int no;
-
- /*
- * The alignment of the current element becomes the alignment of
- * the struct/union if it is larger than the current alignment
- * of the struct/union.
- */
- if (al > dcs->d_stralign)
- dcs->d_stralign = al;
-
- no = (dcs->d_offset + (al - 1)) & ~(al - 1);
- if (len == 0 || dcs->d_offset + len > no)
- dcs->d_offset = no;
-}
-
-/*
- * Remember the width of the field in its type structure.
- */
-sym_t *
-bitfield(sym_t *dsym, int len)
-{
- if (dsym == NULL) {
- dsym = getblk(sizeof (sym_t));
- dsym->s_name = unnamed;
- dsym->s_kind = FMOS;
- dsym->s_scl = MOS;
- dsym->s_type = gettyp(INT);
- dsym->s_blklev = -1;
- }
- dsym->s_type = duptyp(dsym->s_type);
- dsym->s_type->t_isfield = 1;
- dsym->s_type->t_proto = 0;
- dsym->s_type->t_isenum = 0;
- dsym->s_type->t_flen = len;
- dsym->s_field = 1;
- return (dsym);
-}
-
-/*
- * Collect informations about a sequence of asterisks and qualifiers
- * in a list of type pqinf_t.
- * Qualifiers refer always to the left asterisk. The rightmost asterisk
- * will be at the top of the list.
- */
-pqinf_t *
-mergepq(pqinf_t *p1, pqinf_t *p2)
-{
- pqinf_t *p;
-
- if (p2->p_pcnt != 0) {
- /* left '*' at the end of the list */
- for (p = p2; p->p_nxt != NULL; p = p->p_nxt) ;
- p->p_nxt = p1;
- return (p2);
- } else {
- if (p2->p_const) {
- if (p1->p_const) {
- /* duplicate %s */
- warning(10, "const");
- }
- p1->p_const = 1;
- }
- if (p2->p_volatile) {
- if (p1->p_volatile) {
- /* duplicate %s */
- warning(10, "volatile");
- }
- p1->p_volatile = 1;
- }
- free(p2);
- return (p1);
- }
-}
-
-/*
- * Followint 3 functions extend the type of a declarator with
- * pointer, function and array types.
- *
- * The current type is the type built by deftyp() (dcs->d_type) and
- * pointer, function and array types already added for this
- * declarator. The new type extension is inserted between both.
- */
-sym_t *
-addptr(sym_t *decl, pqinf_t *pi)
-{
- type_t **tpp, *tp;
- pqinf_t *npi;
-
- tpp = &decl->s_type;
- while (*tpp && *tpp != dcs->d_type)
- tpp = &(*tpp)->t_subt;
- if (*tpp == NULL)
- return (decl);
-
- while (pi != NULL) {
- *tpp = tp = getblk(sizeof (type_t));
- tp->t_tspec = PTR;
- tp->t_const = pi->p_const;
- tp->t_volatile = pi->p_volatile;
- *(tpp = &tp->t_subt) = dcs->d_type;
- npi = pi->p_nxt;
- free(pi);
- pi = npi;
- }
- return (decl);
-}
-
-/*
- * If a dimension was specified, dim is 1, otherwise 0
- * n is the specified dimension
- */
-sym_t *
-addarray(sym_t *decl, int dim, int n)
-{
- type_t **tpp, *tp;
-
- tpp = &decl->s_type;
- while (*tpp && *tpp != dcs->d_type)
- tpp = &(*tpp)->t_subt;
- if (*tpp == NULL)
- return (decl);
-
- *tpp = tp = getblk(sizeof (type_t));
- tp->t_tspec = ARRAY;
- tp->t_subt = dcs->d_type;
- tp->t_dim = n;
-
- if (n < 0) {
- /* zero or negative array dimension */
- error(20);
- n = 0;
- } else if (n == 0 && dim) {
- /* zero or negative array dimension */
- warning(20);
- } else if (n == 0 && !dim) {
- /* is incomplete type */
- setcompl(tp, 1);
- }
-
- return (decl);
-}
-
-sym_t *
-addfunc(sym_t *decl, sym_t *args)
-{
- type_t **tpp, *tp;
-
- if (dcs->d_proto) {
- args = nsfunc(decl, args);
- } else {
- osfunc(decl, args);
- }
-
- /*
- * The symbols are removed from the symbol table by popdecl() after
- * addfunc(). To be able to restore them if this is a function
- * definition, a pointer to the list of all symbols is stored in
- * dcs->d_nxt->d_fpsyms. Also a list of the arguments (concatenated
- * by s_nxt) is stored in dcs->d_nxt->d_fargs.
- * (dcs->d_nxt must be used because *dcs is the declaration stack
- * element created for the list of params and is removed after
- * addfunc())
- */
- if (dcs->d_nxt->d_ctx == EXTERN &&
- decl->s_type == dcs->d_nxt->d_type) {
- dcs->d_nxt->d_fpsyms = dcs->d_dlsyms;
- dcs->d_nxt->d_fargs = args;
- }
-
- tpp = &decl->s_type;
- while (*tpp && *tpp != dcs->d_nxt->d_type)
- tpp = &(*tpp)->t_subt;
- if (*tpp == NULL)
- return (decl);
-
- *tpp = tp = getblk(sizeof (type_t));
- tp->t_tspec = FUNC;
- tp->t_subt = dcs->d_nxt->d_type;
- if ((tp->t_proto = dcs->d_proto) != 0)
- tp->t_args = args;
- tp->t_vararg = dcs->d_vararg;
-
- return (decl);
-}
-
-/*
- * Called for new style function declarations.
- */
-/* ARGSUSED */
-static sym_t *
-nsfunc(sym_t *decl, sym_t *args)
-{
- sym_t *arg, *sym;
- scl_t sc;
- int n;
-
- /*
- * Declarations of structs/unions/enums in param lists are legal,
- * but senseless.
- */
- for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
- sc = sym->s_scl;
- if (sc == STRTAG || sc == UNIONTAG || sc == ENUMTAG) {
- /* dubious tag declaration: %s %s */
- warning(85, scltoa(sc), sym->s_name);
- }
- }
-
- n = 1;
- for (arg = args; arg != NULL; arg = arg->s_nxt) {
- if (arg->s_type->t_tspec == VOID) {
- if (n > 1 || arg->s_nxt != NULL) {
- /* "void" must be sole parameter */
- error(60);
- arg->s_type = gettyp(INT);
- }
- }
- n++;
- }
-
- /* return NULL if first param is VOID */
- return (args != NULL && args->s_type->t_tspec != VOID ? args : NULL);
-}
-
-/*
- * Called for old style function declarations.
- */
-static void
-osfunc(sym_t *decl, sym_t *args)
-{
- /*
- * Remember list of params only if this is really seams to be
- * a function definition.
- */
- if (dcs->d_nxt->d_ctx == EXTERN &&
- decl->s_type == dcs->d_nxt->d_type) {
- /*
- * We assume that this becomes a function definition. If
- * we are wrong, its corrected in chkfdef().
- */
- if (args != NULL) {
- decl->s_osdef = 1;
- decl->s_args = args;
- }
- } else {
- if (args != NULL)
- /* function prototype parameters must have types */
- warning(62);
- }
-}
-
-/*
- * Lists of Identifiers in functions declarations are allowed only if
- * its also a function definition. If this is not the case, print a
- * error message.
- */
-void
-chkfdef(sym_t *sym, int msg)
-{
- if (sym->s_osdef) {
- if (msg) {
- /* incomplete or misplaced function definition */
- error(22);
- }
- sym->s_osdef = 0;
- sym->s_args = NULL;
- }
-}
-
-/*
- * Process the name in a declarator.
- * If the symbol does already exists, a new one is created.
- * The symbol becomes one of the storage classes EXTERN, STATIC, AUTO or
- * TYPEDEF.
- * s_def and s_reg are valid after dname().
- */
-sym_t *
-dname(sym_t *sym)
-{
- scl_t sc = NOSCL;
-
- if (sym->s_scl == NOSCL) {
- dcs->d_rdcsym = NULL;
- } else if (sym->s_defarg) {
- sym->s_defarg = 0;
- dcs->d_rdcsym = NULL;
- } else {
- dcs->d_rdcsym = sym;
- sym = pushdown(sym);
- }
-
- switch (dcs->d_ctx) {
- case MOS:
- case MOU:
- /* Parent setzen */
- sym->s_styp = dcs->d_tagtyp->t_str;
- sym->s_def = DEF;
- sym->s_value.v_tspec = INT;
- sc = dcs->d_ctx;
- break;
- case EXTERN:
- /*
- * static and external symbols without "extern" are
- * considered to be tentative defined, external
- * symbols with "extern" are declared, and typedef names
- * are defined. Tentative defined and declared symbols
- * may become defined if an initializer is present or
- * this is a function definition.
- */
- if ((sc = dcs->d_scl) == NOSCL) {
- sc = EXTERN;
- sym->s_def = TDEF;
- } else if (sc == STATIC) {
- sym->s_def = TDEF;
- } else if (sc == TYPEDEF) {
- sym->s_def = DEF;
- } else if (sc == EXTERN) {
- sym->s_def = DECL;
- } else {
- lerror("dname() 1");
- }
- break;
- case PARG:
- sym->s_arg = 1;
- /* FALLTHROUGH */
- case ARG:
- if ((sc = dcs->d_scl) == NOSCL) {
- sc = AUTO;
- } else if (sc == REG) {
- sym->s_reg = 1;
- sc = AUTO;
- } else {
- lerror("dname() 2");
- }
- sym->s_def = DEF;
- break;
- case AUTO:
- if ((sc = dcs->d_scl) == NOSCL) {
- /*
- * XXX somewhat ugly because we dont know whether
- * this is AUTO or EXTERN (functions). If we are
- * wrong it must be corrected in decl1loc(), where
- * we have the necessary type information.
- */
- sc = AUTO;
- sym->s_def = DEF;
- } else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) {
- sym->s_def = DEF;
- } else if (sc == REG) {
- sym->s_reg = 1;
- sc = AUTO;
- sym->s_def = DEF;
- } else if (sc == EXTERN) {
- sym->s_def = DECL;
- } else {
- lerror("dname() 3");
- }
- break;
- default:
- lerror("dname() 4");
- }
- sym->s_scl = sc;
-
- sym->s_type = dcs->d_type;
-
- dcs->d_fpsyms = NULL;
-
- return (sym);
-}
-
-/*
- * Process a name in the list of formal params in an old style function
- * definition.
- */
-sym_t *
-iname(sym_t *sym)
-{
- if (sym->s_scl != NOSCL) {
- if (blklev == sym->s_blklev) {
- /* redeclaration of formal parameter %s */
- error(21, sym->s_name);
- if (!sym->s_defarg)
- lerror("iname()");
- }
- sym = pushdown(sym);
- }
- sym->s_type = gettyp(INT);
- sym->s_scl = AUTO;
- sym->s_def = DEF;
- sym->s_defarg = sym->s_arg = 1;
- return (sym);
-}
-
-/*
- * Create the type of a tag.
- *
- * tag points to the symbol table entry of the tag
- * kind is the kind of the tag (STRUCT/UNION/ENUM)
- * decl is 1 if the type of the tag will be completed in this declaration
- * (the following token is T_LBRACE)
- * semi is 1 if the following token is T_SEMI
- */
-type_t *
-mktag(sym_t *tag, tspec_t kind, int decl, int semi)
-{
- scl_t scl = NOSCL;
- type_t *tp;
-
- if (kind == STRUCT) {
- scl = STRTAG;
- } else if (kind == UNION) {
- scl = UNIONTAG;
- } else if (kind == ENUM) {
- scl = ENUMTAG;
- } else {
- lerror("mktag()");
- }
-
- if (tag != NULL) {
- if (tag->s_scl != NOSCL) {
- tag = newtag(tag, scl, decl, semi);
- } else {
- /* a new tag, no empty declaration */
- dcs->d_nxt->d_nedecl = 1;
- if (scl == ENUMTAG && !decl) {
- if (sflag || pflag)
- /* forward reference to enum type */
- warning(42);
- }
- }
- if (tag->s_scl == NOSCL) {
- tag->s_scl = scl;
- tag->s_type = tp = getblk(sizeof (type_t));
- } else {
- tp = tag->s_type;
- }
- } else {
- tag = getblk(sizeof (sym_t));
- tag->s_name = unnamed;
- STRUCT_ASSIGN(tag->s_dpos, curr_pos);
- tag->s_kind = FTAG;
- tag->s_scl = scl;
- tag->s_blklev = -1;
- tag->s_type = tp = getblk(sizeof (type_t));
- dcs->d_nxt->d_nedecl = 1;
- }
-
- if (tp->t_tspec == NOTSPEC) {
- tp->t_tspec = kind;
- if (kind != ENUM) {
- tp->t_str = getblk(sizeof (str_t));
- tp->t_str->align = CHAR_BIT;
- tp->t_str->stag = tag;
- } else {
- tp->t_isenum = 1;
- tp->t_enum = getblk(sizeof (enum_t));
- tp->t_enum->etag = tag;
- }
- /* is incomplete type */
- setcompl(tp, 1);
- }
-
- return (tp);
-}
-
-/*
- * Checks all possible cases of tag redeclarations.
- * decl is 1 if T_LBRACE follows
- * semi is 1 if T_SEMI follows
- */
-static sym_t *
-newtag(sym_t *tag, scl_t scl, int decl, int semi)
-{
- if (tag->s_blklev < blklev) {
- if (semi) {
- /* "struct a;" */
- if (!sflag)
- /* decl. introduces new type ... */
- warning(44, scltoa(scl), tag->s_name);
- tag = pushdown(tag);
- dcs->d_nxt->d_nedecl = 1;
- } else if (decl) {
- /* "struct a { ..." */
- if (hflag)
- /* redefinition hides earlier one: %s */
- warning(43, tag->s_name);
- tag = pushdown(tag);
- dcs->d_nxt->d_nedecl = 1;
- } else if (tag->s_scl != scl) {
- /* base type is really "%s %s" */
- warning(45, scltoa(tag->s_scl), tag->s_name);
- /* declaration introduces new type in ANSI C: %s %s */
- if (!sflag)
- warning(44, scltoa(scl), tag->s_name);
- tag = pushdown(tag);
- dcs->d_nxt->d_nedecl = 1;
- }
- } else {
- if (tag->s_scl != scl) {
- /* (%s) tag redeclared */
- error(46, scltoa(tag->s_scl));
- prevdecl(-1, tag);
- tag = pushdown(tag);
- dcs->d_nxt->d_nedecl = 1;
- } else if (decl && !incompl(tag->s_type)) {
- /* (%s) tag redeclared */
- error(46, scltoa(tag->s_scl));
- prevdecl(-1, tag);
- tag = pushdown(tag);
- dcs->d_nxt->d_nedecl = 1;
- } else if (semi || decl) {
- dcs->d_nxt->d_nedecl = 1;
- }
- }
- return (tag);
-}
-
-const char *
-scltoa(scl_t sc)
-{
- const char *s;
-
- switch (sc) {
- case EXTERN: s = "extern"; break;
- case STATIC: s = "static"; break;
- case AUTO: s = "auto"; break;
- case REG: s = "register"; break;
- case TYPEDEF: s = "typedef"; break;
- case STRTAG: s = "struct"; break;
- case UNIONTAG: s = "union"; break;
- case ENUMTAG: s = "enum"; break;
- default: lerror("tagttoa()");
- }
- return (s);
-}
-
-/*
- * Completes the type of a tag in a struct/union/enum declaration.
- * tp points to the type of the, tag, fmem to the list of members/enums.
- */
-type_t *
-compltag(type_t *tp, sym_t *fmem)
-{
- tspec_t t;
- str_t *sp;
- int n;
- sym_t *mem;
-
- /* from now a complete type */
- setcompl(tp, 0);
-
- if ((t = tp->t_tspec) != ENUM) {
- align(dcs->d_stralign, 0);
- sp = tp->t_str;
- sp->align = dcs->d_stralign;
- sp->size = dcs->d_offset;
- sp->memb = fmem;
- if (sp->size == 0) {
- if (sflag) {
- /* zero sized %s */
- warning(47, ttab[t].tt_name);
- }
- } else {
- n = 0;
- for (mem = fmem; mem != NULL; mem = mem->s_nxt) {
- if (mem->s_name != unnamed)
- n++;
- }
- if (n == 0) {
- /* %s has no named members */
- warning(65,
- t == STRUCT ? "structure" : "union");
- }
- }
- } else {
- tp->t_enum->elem = fmem;
- }
- return (tp);
-}
-
-/*
- * Processes the name of an enumerator in en enum declaration.
- *
- * sym points to the enumerator
- * val is the value of the enumerator
- * impl is 1 if the value of the enumerator was not explicitly specified.
- */
-sym_t *
-ename(sym_t *sym, int val, int impl)
-{
- if (sym->s_scl) {
- if (sym->s_blklev == blklev) {
- /* no hflag, because this is illegal!!! */
- if (sym->s_arg) {
- /* enumeration constant hides parameter: %s */
- warning(57, sym->s_name);
- } else {
- /* redeclaration of %s */
- error(27, sym->s_name);
- /*
- * inside blocks it should not too complicated
- * to find the position of the previous
- * declaration
- */
- if (blklev == 0)
- prevdecl(-1, sym);
- }
- } else {
- if (hflag)
- /* redefinition hides earlier one: %s */
- warning(43, sym->s_name);
- }
- sym = pushdown(sym);
- }
- sym->s_scl = ENUMCON;
- sym->s_type = dcs->d_tagtyp;
- sym->s_value.v_tspec = INT;
- sym->s_value.v_quad = val;
- if (impl && val - 1 == INT_MAX) {
- /* overflow in enumeration values: %s */
- warning(48, sym->s_name);
- }
- enumval = val + 1;
- return (sym);
-}
-
-/*
- * Process a single external declarator.
- */
-void
-decl1ext(sym_t *dsym, int initflg)
-{
- int warn, rval, redec;
- sym_t *rdsym;
-
- chkfdef(dsym, 1);
-
- chktyp(dsym);
-
- if (initflg && !(initerr = chkinit(dsym)))
- dsym->s_def = DEF;
-
- /*
- * Declarations of functions are marked as "tentative" in dname().
- * This is wrong because there are no tentative function
- * definitions.
- */
- if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
- dsym->s_def = DECL;
-
- if (dcs->d_inline) {
- if (dsym->s_type->t_tspec == FUNC) {
- dsym->s_inline = 1;
- } else {
- /* variable declared inline: %s */
- warning(268, dsym->s_name);
- }
- }
-
- if (dsym->s_type->t_tspec == FUNC) {
- if (noretflg)
- dsym->s_noreturn = 1;
- }
- noretflg = 0;
-
- /* Write the declaration into the output file */
- if (plibflg && llibflg &&
- dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
- /*
- * With both LINTLIBRARY and PROTOLIB the prototype is
- * written as a function definition to the output file.
- */
- rval = dsym->s_type->t_subt->t_tspec != VOID;
- outfdef(dsym, &dsym->s_dpos, rval, 0, NULL);
- } else {
- outsym(dsym, dsym->s_scl, dsym->s_def);
- }
-
- if ((rdsym = dcs->d_rdcsym) != NULL) {
- /*
- * If the old symbol stems from a old style function definition
- * we have remembered the params in rdsmy->s_args and compare
- * them with the params of the prototype.
- */
- if (rdsym->s_osdef && dsym->s_type->t_proto) {
- redec = chkosdef(rdsym, dsym);
- } else {
- redec = 0;
- }
-
- if (!redec && !isredec(dsym, (warn = 0, &warn))) {
- if (warn) {
- /* redeclaration of %s */
- (*(sflag ? error : warning))(27, dsym->s_name);
- prevdecl(-1, rdsym);
- }
-
- /*
- * Overtake the rememberd params if the new symbol
- * is not a prototype.
- */
- if (rdsym->s_osdef && !dsym->s_type->t_proto) {
- dsym->s_osdef = rdsym->s_osdef;
- dsym->s_args = rdsym->s_args;
- STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
- }
-
- /*
- * Remember the position of the declaration if the
- * old symbol was a prototype and the new is not.
- * Also remember the position if the old symbol
- * was defined and the new is not.
- */
- if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) {
- STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
- } else if (rdsym->s_def == DEF && dsym->s_def != DEF) {
- STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
- }
-
- /*
- * Copy informations about usage of the name into
- * the new symbol.
- */
- cpuinfo(dsym, rdsym);
-
- /* Once a name is defined, it remains defined. */
- if (rdsym->s_def == DEF)
- dsym->s_def = DEF;
-
- /* once a function is inline, it remains inline */
- if (rdsym->s_inline)
- dsym->s_inline = 1;
-
- compltyp(dsym, rdsym);
-
- }
-
- rmsym(rdsym);
- }
-
- if (dsym->s_scl == TYPEDEF) {
- dsym->s_type = duptyp(dsym->s_type);
- dsym->s_type->t_typedef = 1;
- settdsym(dsym->s_type, dsym);
- }
-
-}
-
-/*
- * Copies informations about usage into a new symbol table entry of
- * the same symbol.
- */
-void
-cpuinfo(sym_t *sym, sym_t *rdsym)
-{
- sym->s_spos = rdsym->s_spos;
- sym->s_upos = rdsym->s_upos;
- sym->s_set = rdsym->s_set;
- sym->s_used = rdsym->s_used;
-}
-
-/*
- * Prints an error and returns 1 if a symbol is redeclared/redefined.
- * Otherwise returns 0 and, in some cases of minor problems, prints
- * a warning.
- */
-int
-isredec(sym_t *dsym, int *warn)
-{
- sym_t *rsym;
-
- if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) {
- /* redeclaration of %s */
- error(27, dsym->s_name);
- prevdecl(-1, rsym);
- return (1);
- }
- if (rsym->s_scl == TYPEDEF) {
- /* typedef redeclared: %s */
- error(89, dsym->s_name);
- prevdecl(-1, rsym);
- return (1);
- }
- if (dsym->s_scl == TYPEDEF) {
- /* redeclaration of %s */
- error(27, dsym->s_name);
- prevdecl(-1, rsym);
- return (1);
- }
- if (rsym->s_def == DEF && dsym->s_def == DEF) {
- /* redefinition of %s */
- error(28, dsym->s_name);
- prevdecl(-1, rsym);
- return(1);
- }
- if (!eqtype(rsym->s_type, dsym->s_type, 0, 0, warn)) {
- /* redeclaration of %s */
- error(27, dsym->s_name);
- prevdecl(-1, rsym);
- return(1);
- }
- if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
- return(0);
- if (rsym->s_scl == STATIC && dsym->s_scl == STATIC)
- return(0);
- if (rsym->s_scl == STATIC && dsym->s_def == DECL)
- return(0);
- if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
- /*
- * All cases except "int a = 1; static int a;" are caught
- * above with or without a warning
- */
- /* redeclaration of %s */
- error(27, dsym->s_name);
- prevdecl(-1, rsym);
- return(1);
- }
- if (rsym->s_scl == EXTERN) {
- /* previously declared extern, becomes static: %s */
- warning(29, dsym->s_name);
- prevdecl(-1, rsym);
- return(0);
- }
- /*
- * Now its on of:
- * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
- */
- /* redeclaration of %s; ANSI C requires "static" */
- if (sflag) {
- warning(30, dsym->s_name);
- prevdecl(-1, rsym);
- }
- dsym->s_scl = STATIC;
- return (0);
-}
-
-/*
- * Checks if two types are compatible. Returns 0 if not, otherwise 1.
- *
- * ignqual ignore qualifiers of type; used for function params
- * promot promote left type; used for comparison of params of
- * old style function definitions with params of prototypes.
- * *warn set to 1 if an old style function declaration is not
- * compatible with a prototype
- */
-int
-eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int *warn)
-{
- tspec_t t;
-
- while (tp1 != NULL && tp2 != NULL) {
- t = tp1->t_tspec;
- if (promot) {
- if (t == FLOAT) {
- t = DOUBLE;
- } else if (t == BOOL) {
- t = INT;
- } else if (t == CHAR || t == SCHAR) {
- t = INT;
- } else if (t == UCHAR) {
- t = INT;
- } else if (t == SHORT) {
- t = INT;
- } else if (t == USHORT) {
- /* CONSTCOND */
- t = INT_MAX < USHRT_MAX ? UINT : INT;
- } else if (t == COMPLEX) {
- t = DCOMPLEX;
- } else if (t == IMAGINARY) {
- t = DIMAGINARY;
- }
- }
-
- if (t != tp2->t_tspec)
- return (0);
-
- if (tp1->t_const != tp2->t_const && !ignqual)
- return (0);
-
- if (tp1->t_volatile != tp2->t_volatile && !ignqual)
- return (0);
-
- if (tp1->t_restrict != tp2->t_restrict && !ignqual)
- return (0);
-
- if (t == STRUCT || t == UNION)
- return (tp1->t_str == tp2->t_str);
-
- if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
- if (tp1->t_dim != 0 && tp2->t_dim != 0)
- return (0);
- }
-
- /* dont check prototypes for traditional */
- if (t == FUNC) {
- if (tp1->t_proto && tp2->t_proto) {
- if (!eqargs(tp1, tp2, warn))
- return (0);
- } else if (tp1->t_proto) {
- if (!mnoarg(tp1, warn))
- return (0);
- } else if (tp2->t_proto) {
- if (!mnoarg(tp2, warn))
- return (0);
- }
- }
-
- tp1 = tp1->t_subt;
- tp2 = tp2->t_subt;
- ignqual = promot = 0;
-
- }
-
- return (tp1 == tp2);
-}
-
-/*
- * Compares the parameter types of two prototypes.
- */
-static int
-eqargs(type_t *tp1, type_t *tp2, int *warn)
-{
- sym_t *a1, *a2;
-
- if (tp1->t_vararg != tp2->t_vararg)
- return (0);
-
- a1 = tp1->t_args;
- a2 = tp2->t_args;
-
- while (a1 != NULL && a2 != NULL) {
- if (eqtype(a1->s_type, a2->s_type, 1, 0, warn) == 0)
- return (0);
-
- a1 = a1->s_nxt;
- a2 = a2->s_nxt;
-
- }
-
- return (a1 == a2);
-}
-
-/*
- * mnoarg() (matches functions with no argument type information)
- * returns 1 if all parameters of a prototype are compatible with
- * and old style function declaration.
- * This is the case if following conditions are met:
- * 1. the prototype must have a fixed number of parameters
- * 2. no parameter is of type float
- * 3. no parameter is converted to another type if integer promotion
- * is applied on it
- */
-static int
-mnoarg(type_t *tp, int *warn)
-{
- sym_t *arg;
- tspec_t t;
-
- if (tp->t_vararg) {
- if (warn != NULL)
- *warn = 1;
- }
- for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) {
- if ((t = arg->s_type->t_tspec) == FLOAT || t == BOOL ||
- t == CHAR || t == SCHAR || t == UCHAR ||
- t == SHORT || t == USHORT || t == COMPLEX ||
- t == DCOMPLEX || t == LDCOMPLEX || t == IMAGINARY ||
- t == DIMAGINARY || t == LDIMAGINARY) {
- if (warn != NULL)
- *warn = 1;
- }
- }
- return (1);
-}
-
-/*
- * Compares a prototype declaration with the remembered arguments of
- * a previous old style function definition.
- */
-static int
-chkosdef(sym_t *rdsym, sym_t *dsym)
-{
- sym_t *args, *pargs, *arg, *parg;
- int narg, nparg, n;
- int warn, msg;
-
- args = rdsym->s_args;
- pargs = dsym->s_type->t_args;
-
- msg = 0;
-
- narg = nparg = 0;
- for (arg = args; arg != NULL; arg = arg->s_nxt)
- narg++;
- for (parg = pargs; parg != NULL; parg = parg->s_nxt)
- nparg++;
- if (narg != nparg) {
- /* prototype does not match old-style definition */
- error(63);
- msg = 1;
- goto end;
- }
-
- arg = args;
- parg = pargs;
- n = 1;
- while (narg--) {
- warn = 0;
- /*
- * If it does not match due to promotion and sflag is
- * not set we print only a warning.
- */
- if (!eqtype(arg->s_type, parg->s_type, 1, 1, &warn) || warn) {
- /* prototype does not match old-style def., arg #%d */
- error(299, n);
- msg = 1;
- }
- arg = arg->s_nxt;
- parg = parg->s_nxt;
- n++;
- }
-
- end:
- if (msg)
- /* old style definition */
- prevdecl(300, rdsym);
-
- return (msg);
-}
-
-/*
- * Completes a type by copying the dimension and prototype information
- * from a second compatible type.
- *
- * Following lines are legal:
- * "typedef a[]; a b; a b[10]; a c; a c[20];"
- * "typedef ft(); ft f; f(int); ft g; g(long);"
- * This means that, if a type is completed, the type structure must
- * be duplicated.
- */
-void
-compltyp(sym_t *dsym, sym_t *ssym)
-{
- type_t **dstp, *src;
- type_t *dst;
-
- dstp = &dsym->s_type;
- src = ssym->s_type;
-
- while ((dst = *dstp) != NULL) {
- if (src == NULL || dst->t_tspec != src->t_tspec)
- lerror("compltyp() 1");
- if (dst->t_tspec == ARRAY) {
- if (dst->t_dim == 0 && src->t_dim != 0) {
- *dstp = dst = duptyp(dst);
- dst->t_dim = src->t_dim;
- /* now a complete type */
- setcompl(dst, 0);
- }
- } else if (dst->t_tspec == FUNC) {
- if (!dst->t_proto && src->t_proto) {
- *dstp = dst = duptyp(dst);
- dst->t_proto = 1;
- dst->t_args = src->t_args;
- }
- }
- dstp = &dst->t_subt;
- src = src->t_subt;
- }
-}
-
-/*
- * Completes the declaration of a single argument.
- */
-sym_t *
-decl1arg(sym_t *sym, int initflg)
-{
- tspec_t t;
-
- chkfdef(sym, 1);
-
- chktyp(sym);
-
- if (dcs->d_rdcsym != NULL && dcs->d_rdcsym->s_blklev == blklev) {
- /* redeclaration of formal parameter %s */
- error(237, sym->s_name);
- rmsym(dcs->d_rdcsym);
- sym->s_arg = 1;
- }
-
- if (!sym->s_arg) {
- /* declared argument %s is missing */
- error(53, sym->s_name);
- sym->s_arg = 1;
- }
-
- if (initflg) {
- /* cannot initialize parameter: %s */
- error(52, sym->s_name);
- initerr = 1;
- }
-
- if ((t = sym->s_type->t_tspec) == ARRAY) {
- sym->s_type = incref(sym->s_type->t_subt, PTR);
- } else if (t == FUNC) {
- sym->s_type = incref(sym->s_type, PTR);
- }
-
- if (dcs->d_inline)
- /* argument declared inline: %s */
- warning(269, sym->s_name);
-
- /*
- * Arguments must have complete types. lengths() prints the needed
- * error messages (null dimension is impossible because arrays are
- * converted to pointers).
- */
- if (sym->s_type->t_tspec != VOID)
- (void)length(sym->s_type, sym->s_name);
-
- setsflg(sym);
-
- return (sym);
-}
-
-/*
- * Does some checks for lint directives which apply to functions.
- * Processes arguments in old style function definitions which default
- * to int.
- * Checks compatibility of old style function definition with previous
- * prototype.
- */
-void
-cluparg(void)
-{
- sym_t *args, *arg, *pargs, *parg;
- int narg, nparg, n, msg;
- tspec_t t;
-
- args = funcsym->s_args;
- pargs = funcsym->s_type->t_args;
-
- /* check for illegal combinations of lint directives */
- if (prflstrg != -1 && scflstrg != -1) {
- /* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */
- warning(289);
- prflstrg = scflstrg = -1;
- }
- if (nvararg != -1 && (prflstrg != -1 || scflstrg != -1)) {
- /* dubious use of ** VARARGS ** with ** %s ** */
- warning(288, prflstrg != -1 ? "PRINTFLIKE" : "SCANFLIKE");
- nvararg = -1;
- }
-
- /*
- * check if the argument of a lint directive is compatible with the
- * number of arguments.
- */
- narg = 0;
- for (arg = dcs->d_fargs; arg != NULL; arg = arg->s_nxt)
- narg++;
- if (nargusg > narg) {
- /* argument number mismatch with directive: ** %s ** */
- warning(283, "ARGSUSED");
- nargusg = 0;
- }
- if (nvararg > narg) {
- /* argument number mismatch with directive: ** %s ** */
- warning(283, "VARARGS");
- nvararg = 0;
- }
- if (prflstrg > narg) {
- /* argument number mismatch with directive: ** %s ** */
- warning(283, "PRINTFLIKE");
- prflstrg = -1;
- } else if (prflstrg == 0) {
- prflstrg = -1;
- }
- if (scflstrg > narg) {
- /* argument number mismatch with directive: ** %s ** */
- warning(283, "SCANFLIKE");
- scflstrg = -1;
- } else if (scflstrg == 0) {
- scflstrg = -1;
- }
- if (prflstrg != -1 || scflstrg != -1) {
- narg = prflstrg != -1 ? prflstrg : scflstrg;
- arg = dcs->d_fargs;
- for (n = 1; n < narg; n++)
- arg = arg->s_nxt;
- if (arg->s_type->t_tspec != PTR ||
- ((t = arg->s_type->t_subt->t_tspec) != CHAR &&
- t != UCHAR && t != SCHAR)) {
- /* arg. %d must be 'char *' for PRINTFLIKE/SCANFLIKE */
- warning(293, narg);
- prflstrg = scflstrg = -1;
- }
- }
-
- /*
- * print a warning for each argument of an old style function
- * definition which defaults to int
- */
- for (arg = args; arg != NULL; arg = arg->s_nxt) {
- if (arg->s_defarg) {
- /* argument type defaults to int: %s */
- warning(32, arg->s_name);
- arg->s_defarg = 0;
- setsflg(arg);
- }
- }
-
- /*
- * If this is an old style function definition and a prototype
- * exists, compare the types of arguments.
- */
- if (funcsym->s_osdef && funcsym->s_type->t_proto) {
- /*
- * If the number of arguments does not macht, we need not
- * continue.
- */
- narg = nparg = 0;
- msg = 0;
- for (parg = pargs; parg != NULL; parg = parg->s_nxt)
- nparg++;
- for (arg = args; arg != NULL; arg = arg->s_nxt)
- narg++;
- if (narg != nparg) {
- /* parameter mismatch: %d declared, %d defined */
- error(51, nparg, narg);
- msg = 1;
- } else {
- parg = pargs;
- arg = args;
- while (narg--) {
- msg |= chkptdecl(arg, parg);
- parg = parg->s_nxt;
- arg = arg->s_nxt;
- }
- }
- if (msg)
- /* prototype declaration */
- prevdecl(285, dcs->d_rdcsym);
-
- /* from now the prototype is valid */
- funcsym->s_osdef = 0;
- funcsym->s_args = NULL;
-
- }
-
-}
-
-/*
- * Checks compatibility of an old style function definition with a previous
- * prototype declaration.
- * Returns 1 if the position of the previous declaration should be reported.
- */
-static int
-chkptdecl(sym_t *arg, sym_t *parg)
-{
- type_t *tp, *ptp;
- int warn, msg;
-
- tp = arg->s_type;
- ptp = parg->s_type;
-
- msg = 0;
- warn = 0;
-
- if (!eqtype(tp, ptp, 1, 1, &warn)) {
- if (eqtype(tp, ptp, 1, 0, &warn)) {
- /* type does not match prototype: %s */
- msg = gnuism(58, arg->s_name);
- } else {
- /* type does not match prototype: %s */
- error(58, arg->s_name);
- msg = 1;
- }
- } else if (warn) {
- /* type does not match prototype: %s */
- (*(sflag ? error : warning))(58, arg->s_name);
- msg = 1;
- }
-
- return (msg);
-}
-
-/*
- * Completes a single local declaration/definition.
- */
-void
-decl1loc(sym_t *dsym, int initflg)
-{
- /* Correct a mistake done in dname(). */
- if (dsym->s_type->t_tspec == FUNC) {
- dsym->s_def = DECL;
- if (dcs->d_scl == NOSCL)
- dsym->s_scl = EXTERN;
- }
-
- if (dsym->s_type->t_tspec == FUNC) {
- if (dsym->s_scl == STATIC) {
- /* dubious static function at block level: %s */
- warning(93, dsym->s_name);
- dsym->s_scl = EXTERN;
- } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
- /* function has illegal storage class: %s */
- error(94, dsym->s_name);
- dsym->s_scl = EXTERN;
- }
- }
-
- /*
- * functions may be declared inline at local scope, although
- * this has no effect for a later definition of the same
- * function.
- */
- if (dcs->d_inline) {
- if (dsym->s_type->t_tspec == FUNC) {
- dsym->s_inline = 1;
- } else {
- /* variable declared inline: %s */
- warning(268, dsym->s_name);
- }
- }
-
- chkfdef(dsym, 1);
-
- chktyp(dsym);
-
- if (dcs->d_rdcsym != NULL && dsym->s_scl == EXTERN)
- ledecl(dsym);
-
- if (dsym->s_scl == EXTERN) {
- /*
- * XXX wenn die statische Variable auf Ebene 0 erst
- * spaeter definiert wird, haben wir die Brille auf.
- */
- if (dsym->s_xsym == NULL) {
- outsym(dsym, EXTERN, dsym->s_def);
- } else {
- outsym(dsym, dsym->s_xsym->s_scl, dsym->s_def);
- }
- }
-
- if (dcs->d_rdcsym != NULL) {
- if (dcs->d_rdcsym->s_blklev == 0) {
- switch (dsym->s_scl) {
- case AUTO:
- /* automatic hides external declaration: %s */
- if (hflag)
- warning(86, dsym->s_name);
- break;
- case STATIC:
- /* static hides external declaration: %s */
- if (hflag)
- warning(87, dsym->s_name);
- break;
- case TYPEDEF:
- /* typedef hides external declaration: %s */
- if (hflag)
- warning(88, dsym->s_name);
- break;
- case EXTERN:
- /*
- * Warnings and errors are printed in ledecl()
- */
- break;
- default:
- lerror("decl1loc() 1");
- }
- } else if (dcs->d_rdcsym->s_blklev == blklev) {
- /* no hflag, because its illegal! */
- if (dcs->d_rdcsym->s_arg) {
- /*
- * a "redeclaration of %s" error
- * is produced below
- */
- }
-
- } else if (dcs->d_rdcsym->s_blklev < blklev) {
- if (hflag)
- /* declaration hides earlier one: %s */
- warning(95, dsym->s_name);
- }
-
- if (dcs->d_rdcsym->s_blklev == blklev) {
- /* redeclaration of %s */
- error(27, dsym->s_name);
- rmsym(dcs->d_rdcsym);
- }
- }
-
- if (initflg && !(initerr = chkinit(dsym))) {
- dsym->s_def = DEF;
- setsflg(dsym);
- }
-
- if (dsym->s_scl == TYPEDEF) {
- dsym->s_type = duptyp(dsym->s_type);
- dsym->s_type->t_typedef = 1;
- settdsym(dsym->s_type, dsym);
- }
-
- /*
- * Before we can check the size we must wait for a initialisation
- * which may follow.
- */
-}
-
-/*
- * Processes (re)declarations of external Symbols inside blocks.
- */
-static void
-ledecl(sym_t *dsym)
-{
- int eqt, warn;
- sym_t *esym;
-
- /* look for a symbol with the same name */
- esym = dcs->d_rdcsym;
- while (esym != NULL && esym->s_blklev != 0) {
- while ((esym = esym->s_link) != NULL) {
- if (esym->s_kind != FVFT)
- continue;
- if (strcmp(dsym->s_name, esym->s_name) == 0)
- break;
- }
- }
- if (esym == NULL)
- return;
- if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
- /* gcc accepts this without a warning, pcc prints an error. */
- /* redeclaration of %s */
- warning(27, dsym->s_name);
- prevdecl(-1, esym);
- return;
- }
-
- warn = 0;
- eqt = eqtype(esym->s_type, dsym->s_type, 0, 0, &warn);
-
- if (!eqt || warn) {
- if (esym->s_scl == EXTERN) {
- /* inconsistent redeclaration of extern: %s */
- warning(90, dsym->s_name);
- prevdecl(-1, esym);
- } else {
- /* inconsistent redeclaration of static: %s */
- warning(92, dsym->s_name);
- prevdecl(-1, esym);
- }
- }
-
- if (eqt) {
- /*
- * Remember the external symbol so we can update usage
- * information at the end of the block.
- */
- dsym->s_xsym = esym;
- }
-}
-
-/*
- * Print an error or a warning if the symbol can't be initialized due
- * to type/storage class. Return value is 1 if an error has been
- * detected.
- */
-static int
-chkinit(sym_t *sym)
-{
- int err;
-
- err = 0;
-
- if (sym->s_type->t_tspec == FUNC) {
- /* cannot initialize function: %s */
- error(24, sym->s_name);
- err = 1;
- } else if (sym->s_scl == TYPEDEF) {
- /* cannot initialize typedef: %s */
- error(25, sym->s_name);
- err = 1;
- } else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
- /* cannot initialize "extern" declaration: %s */
- if (dcs->d_ctx == EXTERN) {
- warning(26, sym->s_name);
- } else {
- error(26, sym->s_name);
- err = 1;
- }
- }
-
- return (err);
-}
-
-/*
- * Create a symbole for an abstract declaration.
- */
-sym_t *
-aname(void)
-{
- sym_t *sym;
-
- if (dcs->d_ctx != ABSTRACT && dcs->d_ctx != PARG)
- lerror("aname()");
-
- sym = getblk(sizeof (sym_t));
-
- sym->s_name = unnamed;
- sym->s_def = DEF;
- sym->s_scl = ABSTRACT;
- sym->s_blklev = -1;
-
- if (dcs->d_ctx == PARG)
- sym->s_arg = 1;
-
- sym->s_type = dcs->d_type;
- dcs->d_rdcsym = NULL;
- dcs->d_vararg = 0;
-
- return (sym);
-}
-
-/*
- * Removes anything which has nothing to do on global level.
- */
-void
-globclup(void)
-{
- while (dcs->d_nxt != NULL)
- popdecl();
-
- cleanup();
- blklev = 0;
- mblklev = 0;
-
- /*
- * remove all information about pending lint directives without
- * warnings.
- */
- glclup(1);
-}
-
-/*
- * Process an abstract type declaration
- */
-sym_t *
-decl1abs(sym_t *sym)
-{
- chkfdef(sym, 1);
- chktyp(sym);
- return (sym);
-}
-
-/*
- * Checks size after declarations of variables and their initialisation.
- */
-void
-chksz(sym_t *dsym)
-{
- /*
- * check size only for symbols which are defined and no function and
- * not typedef name
- */
- if (dsym->s_def != DEF)
- return;
- if (dsym->s_scl == TYPEDEF)
- return;
- if (dsym->s_type->t_tspec == FUNC)
- return;
-
- if (length(dsym->s_type, dsym->s_name) == 0 &&
- dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
- /* empty array declaration: %s */
- error(190, dsym->s_name);
- }
-}
-
-/*
- * Mark an object as set if it is not already
- */
-void
-setsflg(sym_t *sym)
-{
- if (!sym->s_set) {
- sym->s_set = 1;
- STRUCT_ASSIGN(sym->s_spos, curr_pos);
- }
-}
-
-/*
- * Mark an object as used if it is not already
- */
-void
-setuflg(sym_t *sym, int fcall, int szof)
-{
- if (!sym->s_used) {
- sym->s_used = 1;
- STRUCT_ASSIGN(sym->s_upos, curr_pos);
- }
- /*
- * for function calls another record is written
- *
- * XXX Should symbols used in sizeof() treated as used or not?
- * Probably not, because there is no sense to declare an
- * external variable only to get their size.
- */
- if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
- outusg(sym);
-}
-
-/*
- * Prints warnings for a list of variables and labels (concatenated
- * with s_dlnxt) if these are not used or only set.
- */
-void
-chkusage(dinfo_t *di)
-{
- sym_t *sym;
- int mknowarn;
-
- /* for this warnings LINTED has no effect */
- mknowarn = nowarn;
- nowarn = 0;
-
- for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt)
- chkusg1(di->d_asm, sym);
-
- nowarn = mknowarn;
-}
-
-/*
- * Prints a warning for a single variable or label if it is not used or
- * only set.
- */
-void
-chkusg1(int novar, sym_t *sym)
-{
- pos_t cpos;
-
- if (sym->s_blklev == -1)
- return;
-
- STRUCT_ASSIGN(cpos, curr_pos);
-
- if (sym->s_kind == FVFT) {
- if (sym->s_arg) {
- chkausg(novar, sym);
- } else {
- chkvusg(novar, sym);
- }
- } else if (sym->s_kind == FLAB) {
- chklusg(sym);
- } else if (sym->s_kind == FTAG) {
- chktusg(sym);
- }
-
- STRUCT_ASSIGN(curr_pos, cpos);
-}
-
-static void
-chkausg(int novar, sym_t *arg)
-{
- if (!arg->s_set)
- lerror("chkausg() 1");
-
- if (novar)
- return;
-
- if (!arg->s_used && vflag) {
- STRUCT_ASSIGN(curr_pos, arg->s_dpos);
- /* argument %s unused in function %s */
- warning(231, arg->s_name, funcsym->s_name);
- }
-}
-
-static void
-chkvusg(int novar, sym_t *sym)
-{
- scl_t sc;
- sym_t *xsym;
-
- if (blklev == 0 || sym->s_blklev == 0)
- lerror("chkvusg() 1");
-
- /* errors in expressions easily cause lots of these warnings */
- if (nerr != 0)
- return;
-
- /*
- * XXX Only variables are checkd, although types should
- * probably also be checked
- */
- if ((sc = sym->s_scl) != EXTERN && sc != STATIC &&
- sc != AUTO && sc != REG) {
- return;
- }
-
- if (novar)
- return;
-
- if (sc == EXTERN) {
- if (!sym->s_used && !sym->s_set) {
- STRUCT_ASSIGN(curr_pos, sym->s_dpos);
- /* %s unused in function %s */
- warning(192, sym->s_name, funcsym->s_name);
- }
- } else {
- if (sym->s_set && !sym->s_used) {
- STRUCT_ASSIGN(curr_pos, sym->s_spos);
- /* %s set but not used in function %s */
- warning(191, sym->s_name, funcsym->s_name);
- } else if (!sym->s_used) {
- STRUCT_ASSIGN(curr_pos, sym->s_dpos);
- /* %s unused in function %s */
- warning(192, sym->s_name, funcsym->s_name);
- }
- }
-
- if (sc == EXTERN) {
- /*
- * information about usage is taken over into the symbol
- * tabel entry at level 0 if the symbol was locally declared
- * as an external symbol.
- *
- * XXX This is wrong for symbols declared static at level 0
- * if the usage information stems from sizeof(). This is
- * because symbols at level 0 only used in sizeof() are
- * considered to not be used.
- */
- if ((xsym = sym->s_xsym) != NULL) {
- if (sym->s_used && !xsym->s_used) {
- xsym->s_used = 1;
- STRUCT_ASSIGN(xsym->s_upos, sym->s_upos);
- }
- if (sym->s_set && !xsym->s_set) {
- xsym->s_set = 1;
- STRUCT_ASSIGN(xsym->s_spos, sym->s_spos);
- }
- }
- }
-}
-
-static void
-chklusg(sym_t *lab)
-{
- if (blklev != 1 || lab->s_blklev != 1)
- lerror("chklusg() 1");
-
- if (lab->s_set && !lab->s_used) {
- STRUCT_ASSIGN(curr_pos, lab->s_spos);
- /* label %s unused in function %s */
- warning(192, lab->s_name, funcsym->s_name);
- } else if (!lab->s_set) {
- STRUCT_ASSIGN(curr_pos, lab->s_upos);
- /* undefined label %s */
- warning(23, lab->s_name);
- }
-}
-
-static void
-chktusg(sym_t *sym)
-{
- if (!incompl(sym->s_type))
- return;
-
- /* complain always about incomplete tags declared inside blocks */
- if (!zflag || dcs->d_ctx != EXTERN)
- return;
-
- STRUCT_ASSIGN(curr_pos, sym->s_dpos);
- switch (sym->s_type->t_tspec) {
- case STRUCT:
- /* struct %s never defined */
- warning(233, sym->s_name);
- break;
- case UNION:
- /* union %s never defined */
- warning(234, sym->s_name);
- break;
- case ENUM:
- /* enum %s never defined */
- warning(235, sym->s_name);
- break;
- default:
- lerror("chktusg() 1");
- }
-}
-
-/*
- * Called after the entire translation unit has been parsed.
- * Changes tentative definitions in definitions.
- * Performs some tests on global Symbols. Detected Problems are:
- * - defined variables of incomplete type
- * - constant variables which are not initialized
- * - static symbols which are never used
- */
-void
-chkglsyms(void)
-{
- sym_t *sym;
- pos_t cpos;
-
- if (blklev != 0 || dcs->d_nxt != NULL)
- norecover();
-
- STRUCT_ASSIGN(cpos, curr_pos);
-
- for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
- if (sym->s_blklev == -1)
- continue;
- if (sym->s_kind == FVFT) {
- chkglvar(sym);
- } else if (sym->s_kind == FTAG) {
- chktusg(sym);
- } else {
- if (sym->s_kind != FMOS)
- lerror("chkglsyms() 1");
- }
- }
-
- STRUCT_ASSIGN(curr_pos, cpos);
-}
-
-static void
-chkglvar(sym_t *sym)
-{
- if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON)
- return;
-
- if (sym->s_scl != EXTERN && sym->s_scl != STATIC)
- lerror("chkglvar() 1");
-
- glchksz(sym);
-
- if (sym->s_scl == STATIC) {
- if (sym->s_type->t_tspec == FUNC) {
- if (sym->s_used && sym->s_def != DEF) {
- STRUCT_ASSIGN(curr_pos, sym->s_upos);
- /* static func. called but not def.. */
- error(225, sym->s_name);
- }
- }
- if (!sym->s_used) {
- STRUCT_ASSIGN(curr_pos, sym->s_dpos);
- if (sym->s_type->t_tspec == FUNC) {
- if (sym->s_def == DEF) {
- if (!sym->s_inline)
- /* static function %s unused */
- warning(236, sym->s_name);
- } else {
- /* static function %s decl. but ... */
- warning(290, sym->s_name);
- }
- } else if (!sym->s_set) {
- /* static variable %s unused */
- warning(226, sym->s_name);
- } else {
- /* static variable %s set but not used */
- warning(307, sym->s_name);
- }
- }
- if (sym->s_def == TDEF && sym->s_type->t_const) {
- STRUCT_ASSIGN(curr_pos, sym->s_dpos);
- /* const object %s should have initializer */
- warning(227, sym->s_name);
- }
- }
-}
-
-static void
-glchksz(sym_t *sym)
-{
- if (sym->s_def == TDEF) {
- if (sym->s_type->t_tspec == FUNC)
- /*
- * this can happen if a syntax error occurred
- * after a function declaration
- */
- return;
- STRUCT_ASSIGN(curr_pos, sym->s_dpos);
- if (length(sym->s_type, sym->s_name) == 0 &&
- sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
- /* empty array declaration: %s */
- if (sym->s_scl == EXTERN && !sflag) {
- warning(190, sym->s_name);
- } else {
- error(190, sym->s_name);
- }
- }
- }
-}
-
-/*
- * Prints information about location of previous definition/declaration.
- */
-void
-prevdecl(int msg, sym_t *psym)
-{
- pos_t cpos;
-
- if (!rflag)
- return;
-
- STRUCT_ASSIGN(cpos, curr_pos);
- STRUCT_ASSIGN(curr_pos, psym->s_dpos);
- if (msg != -1) {
- message(msg, psym->s_name);
- } else if (psym->s_def == DEF || psym->s_def == TDEF) {
- /* previous definition of %s */
- message(261, psym->s_name);
- } else {
- /* previous declaration of %s */
- message(260, psym->s_name);
- }
- STRUCT_ASSIGN(curr_pos, cpos);
-}
diff --git a/usr.bin/xlint/lint1/emit.c b/usr.bin/xlint/lint1/emit.c
deleted file mode 100644
index 379d344e826..00000000000
--- a/usr.bin/xlint/lint1/emit.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/* $OpenBSD: emit.c,v 1.10 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <err.h>
-
-#include "lint.h"
-
-/* name and handle of output file */
-static const char *loname;
-static FILE *lout;
-
-/* output buffer data */
-ob_t ob;
-
-static void outxbuf(void);
-
-
-/*
- * initialize output
- */
-void
-outopen(const char *name)
-{
- loname = name;
-
- /* open output file */
- if ((lout = fopen(name, "w")) == NULL)
- err(1, "cannot open '%s'", name);
-
- /* generate output buffer */
- ob.o_len = 1024;
- ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len;
-}
-
-/*
- * flush output buffer and close file
- */
-void
-outclose(void)
-{
- outclr();
- if (fclose(lout) == EOF)
- err(1, "cannot close '%s'", loname);
-}
-
-/*
- * resize output buffer
- */
-static void
-outxbuf(void)
-{
- ptrdiff_t coffs;
-
- coffs = ob.o_nxt - ob.o_buf;
- ob.o_len *= 2;
- ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len;
- ob.o_nxt = ob.o_buf + coffs;
-}
-
-/*
- * reset output buffer
- * if it is not empty, it is flushed
- */
-void
-outclr(void)
-{
- size_t sz;
-
- if (ob.o_buf != ob.o_nxt) {
- outchar('\n');
- sz = ob.o_nxt - ob.o_buf;
- if (sz > ob.o_len)
- errx(1, "internal error: outclr() 1");
- if (fwrite(ob.o_buf, sz, 1, lout) != 1)
- err(1, "cannot write to %s", loname);
- ob.o_nxt = ob.o_buf;
- }
-}
-
-/*
- * write a character to the output buffer
- */
-void
-outchar(int c)
-{
- if (ob.o_nxt == ob.o_end)
- outxbuf();
- *ob.o_nxt++ = (char)c;
-}
-
-/*
- * write a character to the output buffer, qouted if necessary
- */
-void
-outqchar(int c)
-{
- if (isprint(c) && c != '\\' && c != '"' && c != '\'') {
- outchar(c);
- } else {
- outchar('\\');
- switch (c) {
- case '\\':
- outchar('\\');
- break;
- case '"':
- outchar('"');
- break;
- case '\'':
- outchar('\'');
- break;
- case '\b':
- outchar('b');
- break;
- case '\t':
- outchar('t');
- break;
- case '\n':
- outchar('n');
- break;
- case '\f':
- outchar('f');
- break;
- case '\r':
- outchar('r');
- break;
- case '\v':
- outchar('v');
- break;
- case '\a':
- outchar('a');
- break;
- default:
- outchar((((u_int)c >> 6) & 07) + '0');
- outchar((((u_int)c >> 3) & 07) + '0');
- outchar((c & 07) + '0');
- break;
- }
- }
-}
-
-/*
- * write a strint to the output buffer
- * the string must not contain any characters which
- * should be quoted
- */
-void
-outstrg(const char *s)
-{
- while (*s != '\0') {
- if (ob.o_nxt == ob.o_end)
- outxbuf();
- *ob.o_nxt++ = *s++;
- }
-}
-
-/*
- * write an integer value to toe output buffer
- */
-void
-outint(int i)
-{
- if ((ob.o_end - ob.o_nxt) < 12)
- outxbuf();
- snprintf(ob.o_nxt, ob.o_end - ob.o_nxt, "%d", i);
- ob.o_nxt += strlen(ob.o_nxt);
-}
-
-/*
- * write the name of a symbol to the output buffer
- * the name is preceded by its length
- */
-void
-outname(const char *name)
-{
- if (name == NULL)
- errx(1, "internal error: outname() 1");
- outint((int)strlen(name));
- outstrg(name);
-}
-
-/*
- * write the name of the .c source
- */
-void
-outsrc(const char *name)
-{
- outclr();
- outchar('S');
- outstrg(name);
-}
diff --git a/usr.bin/xlint/lint1/emit1.c b/usr.bin/xlint/lint1/emit1.c
deleted file mode 100644
index 28f962cd549..00000000000
--- a/usr.bin/xlint/lint1/emit1.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/* $OpenBSD: emit1.c,v 1.9 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-
-#include "lint1.h"
-
-static void outtt(sym_t *, sym_t *);
-static void outfstrg(strg_t *);
-
-/*
- * Write type into the output buffer.
- * The type is written as a sequence of substrings, each of which describes a
- * node of type type_t
- * a node is coded as follows:
- * _Bool B
- * char C
- * signed char s C
- * unsigned char u C
- * short S
- * unsigned short u S
- * int I
- * unsigned int u I
- * long L
- * unsigned long u L
- * long long Q
- * unsigned long long u Q
- * float s D
- * double D
- * long double l D
- * float _Complex s X
- * double _Complex X
- * long double _Complex l X
- * float _Imaginary s J
- * double _Imaginary J
- * long double _Imaginary l J
- * void V
- * * P
- * [n] A n
- * () F
- * (void) F 0
- * (n arguments) F n arg1 arg2 ... argn
- * (n arguments, ...) F n arg1 arg2 ... argn-1 E
- * (a, b, c, ...) f n arg1 arg2 ...
- * enum tag e T tag_or_typename
- * struct tag s T tag_or_typename
- * union tag u T tag_or_typename
- *
- * tag_or_typename 0 no tag or type name
- * 1 n tag Tag
- * 2 n typename only type name
- *
- * spaces are only for better readability
- * additionaly it is possible to prepend the characters 'c' (for const)
- * and 'v' (for volatile)
- */
-void
-outtype(type_t *tp)
-{
- int t, s, na;
- sym_t *arg;
- tspec_t ts;
-
- while (tp != NULL) {
- if ((ts = tp->t_tspec) == INT && tp->t_isenum)
- ts = ENUM;
- switch (ts) {
- case BOOL: t = 'B'; s = '\0'; break;
- case CHAR: t = 'C'; s = '\0'; break;
- case SCHAR: t = 'C'; s = 's'; break;
- case UCHAR: t = 'C'; s = 'u'; break;
- case SHORT: t = 'S'; s = '\0'; break;
- case USHORT: t = 'S'; s = 'u'; break;
- case INT: t = 'I'; s = '\0'; break;
- case UINT: t = 'I'; s = 'u'; break;
- case LONG: t = 'L'; s = '\0'; break;
- case ULONG: t = 'L'; s = 'u'; break;
- case QUAD: t = 'Q'; s = '\0'; break;
- case UQUAD: t = 'Q'; s = 'u'; break;
- case FLOAT: t = 'D'; s = 's'; break;
- case DOUBLE: t = 'D'; s = '\0'; break;
- case LDOUBLE: t = 'D'; s = 'l'; break;
- case COMPLEX: t = 'X'; s = 's'; break;
- case DCOMPLEX: t = 'X'; s = '\0'; break;
- case LDCOMPLEX: t = 'X'; s = 'l'; break;
- case IMAGINARY: t = 'J'; s = 's'; break;
- case DIMAGINARY: t = 'J'; s = '\0'; break;
- case LDIMAGINARY:t = 'J'; s = 'l'; break;
- case VOID: t = 'V'; s = '\0'; break;
- case PTR: t = 'P'; s = '\0'; break;
- case ARRAY: t = 'A'; s = '\0'; break;
- case FUNC: t = 'F'; s = '\0'; break;
- case ENUM: t = 'T'; s = 'e'; break;
- case STRUCT: t = 'T'; s = 's'; break;
- case UNION: t = 'T'; s = 'u'; break;
- default:
- lerror("outtyp() 1");
- }
- if (tp->t_const)
- outchar('c');
- if (tp->t_volatile)
- outchar('v');
- if (s != '\0')
- outchar(s);
- outchar(t);
- if (ts == ARRAY) {
- outint(tp->t_dim);
- } else if (ts == ENUM) {
- outtt(tp->t_enum->etag, tp->t_enum->etdef);
- } else if (ts == STRUCT || ts == UNION) {
- outtt(tp->t_str->stag, tp->t_str->stdef);
- } else if (ts == FUNC && tp->t_proto) {
- na = 0;
- for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt)
- na++;
- if (tp->t_vararg)
- na++;
- outint(na);
- for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt)
- outtype(arg->s_type);
- if (tp->t_vararg)
- outchar('E');
- }
- tp = tp->t_subt;
- }
-}
-
-/*
- * type to string
- * used for debugging output
- *
- * it uses its own output buffer for conversion
- */
-const char *
-ttos(type_t *tp)
-{
- static ob_t tob;
- ob_t tmp;
-
- if (tob.o_buf == NULL) {
- tob.o_len = 64;
- tob.o_buf = tob.o_nxt = xmalloc(tob.o_len);
- tob.o_end = tob.o_buf + tob.o_len;
- }
-
- tmp = ob;
- ob = tob;
- ob.o_nxt = ob.o_buf;
- outtype(tp);
- outchar('\0');
- tob = ob;
- ob = tmp;
-
- return (tob.o_buf);
-}
-
-/*
- * write the name of a tag or typename
- *
- * if the tag is named, the name of the
- * tag is written, otherwise, if a typename exists which
- * refers to this tag, this typename is written
- */
-static void
-outtt(sym_t *tag, sym_t *tdef)
-{
- if (tag->s_name != unnamed) {
- outint(1);
- outname(tag->s_name);
- } else if (tdef != NULL) {
- outint(2);
- outname(tdef->s_name);
- } else {
- outint(0);
- }
-}
-
-/*
- * write information about an global declared/defined symbol
- * with storage class extern
- *
- * informations about function definitions are written in outfdef(),
- * not here
- */
-void
-outsym(sym_t *sym, scl_t sc, def_t def)
-{
- /*
- * Static function declarations must also be written to the output
- * file. Compatibility of function declarations (for both static
- * and extern functions) must be checked in lint2. Lint1 can't do
- * this, especially not, if functions are declared at block level
- * before their first declaration at level 0.
- */
- if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC))
- return;
-
- /* reset buffer */
- outclr();
-
- /*
- * line number of .c source, 'd' for declaration, Id of current
- * source (.c or .h), and line in current source.
- */
- outint(csrc_pos.p_line);
- outchar('d');
- outint(getfnid(sym->s_dpos.p_file));
- outchar('.');
- outint(sym->s_dpos.p_line);
-
- /* flags */
-
- switch (def) {
- case DEF:
- /* defined */
- outchar('d');
- break;
- case TDEF:
- /* tentative defined */
- outchar('t');
- break;
- case DECL:
- /* declared */
- outchar('e');
- break;
- default:
- lerror("outsym() 2");
- }
- if (llibflg && def != DECL) {
- /*
- * mark it as used so we get no warnings from lint2 about
- * unused symbols in libraries.
- */
- outchar('u');
- }
-
- if (sc == STATIC)
- outchar('s');
-
- /* name of the symbol */
- outname(sym->s_name);
-
- /* type of the symbol */
- outtype(sym->s_type);
-}
-
-/*
- * write information about function definition
- *
- * this is also done for static functions so we are able to check if
- * they are called with proper argument types
- */
-void
-outfdef(sym_t *fsym, pos_t *posp, int rval, int osdef, sym_t *args)
-{
- int narg;
- sym_t *arg;
-
- /* reset the buffer */
- outclr();
-
- /*
- * line number of .c source, 'd' for declaration, Id of current
- * source (.c or .h), and line in current source
- *
- * we are already at the end of the function. If we are in the
- * .c source, posp->p_line is correct, otherwise csrc_pos.p_line
- * (for functions defined in header files).
- */
- if (posp->p_file == csrc_pos.p_file) {
- outint(posp->p_line);
- } else {
- outint(csrc_pos.p_line);
- }
- outchar('d');
- outint(getfnid(posp->p_file));
- outchar('.');
- outint(posp->p_line);
-
- /* flags */
-
- /* both SCANFLIKE and PRINTFLIKE imply VARARGS */
- if (prflstrg != -1) {
- nvararg = prflstrg;
- } else if (scflstrg != -1) {
- nvararg = scflstrg;
- }
-
- if (nvararg != -1) {
- outchar('v');
- outint(nvararg);
- }
- if (scflstrg != -1) {
- outchar('S');
- outint(scflstrg);
- }
- if (prflstrg != -1) {
- outchar('P');
- outint(prflstrg);
- }
- nvararg = prflstrg = scflstrg = -1;
-
- outchar('d');
-
- if (rval)
- /* has return value */
- outchar('r');
-
- if (llibflg)
- /*
- * mark it as used so lint2 does not complain about
- * unused symbols in libraries
- */
- outchar('u');
-
- if (osdef)
- /* old style function definition */
- outchar('o');
-
- if (fsym->s_scl == STATIC)
- outchar('s');
-
- /* name of function */
- outname(fsym->s_name);
-
- /* argument types and return value */
- if (osdef) {
- narg = 0;
- for (arg = args; arg != NULL; arg = arg->s_nxt)
- narg++;
- outchar('f');
- outint(narg);
- for (arg = args; arg != NULL; arg = arg->s_nxt)
- outtype(arg->s_type);
- outtype(fsym->s_type->t_subt);
- } else {
- outtype(fsym->s_type);
- }
-}
-
-/*
- * write out all information necessary for lint2 to check function
- * calls
- *
- * rvused is set if the return value is used (asigned to a variable)
- * rvdisc is set if the return value is not used and not ignored
- * (casted to void)
- */
-void
-outcall(tnode_t *tn, int rvused, int rvdisc)
-{
- tnode_t *args, *arg;
- int narg, n, i;
- quad_t q;
- tspec_t t;
-
- /* reset buffer */
- outclr();
-
- /*
- * line number of .c source, 'c' for function call, Id of current
- * source (.c or .h), and line in current source
- */
- outint(csrc_pos.p_line);
- outchar('c');
- outint(getfnid(curr_pos.p_file));
- outchar('.');
- outint(curr_pos.p_line);
-
- /*
- * flags; 'u' and 'i' must be last to make sure a letter
- * is between the numeric argument of a flag and the name of
- * the function
- */
- narg = 0;
- args = tn->tn_right;
- for (arg = args; arg != NULL; arg = arg->tn_right)
- narg++;
- /* informations about arguments */
- for (n = 1; n <= narg; n++) {
- /* the last argument is the top one in the tree */
- for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
- arg = arg->tn_left;
- if (arg->tn_op == CON) {
- if (isityp(t = arg->tn_type->t_tspec)) {
- /*
- * XXX it would probably be better to
- * explicitly test the sign
- */
- if ((q = arg->tn_val->v_quad) == 0) {
- /* zero constant */
- outchar('z');
- } else if (msb(q, t, 0) == 0) {
- /* positive if casted to signed */
- outchar('p');
- } else {
- /* negative if casted to signed */
- outchar('n');
- }
- outint(n);
- }
- } else {
- if (arg->tn_op == CVT && !arg->tn_cast)
- arg = arg->tn_left;
- if (arg->tn_op == AMPER &&
- arg->tn_left->tn_op == STRING &&
- arg->tn_left->tn_strg->st_tspec == CHAR) {
- /* constant string, write format specifiers */
- outchar('s');
- outint(n);
- outfstrg(arg->tn_left->tn_strg);
- }
- }
-
- }
- /* return value discarded/used/ignored */
- outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i'));
-
- /* name of the called function */
- outname(tn->tn_left->tn_left->tn_sym->s_name);
-
- /* types of arguments */
- outchar('f');
- outint(narg);
- for (n = 1; n <= narg; n++) {
- /* the last argument is the top one in the tree */
- for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
- outtype(arg->tn_left->tn_type);
- }
- /* expected type of return value */
- outtype(tn->tn_type);
-}
-
-/*
- * extracts potential format specifiers for printf() and scanf() and
- * writes them, enclosed in "" and quoted if necessary, to the output buffer
- */
-static void
-outfstrg(strg_t *strg)
-{
- int c, oc, first;
- u_char *cp;
-
- if (strg->st_tspec != CHAR)
- lerror("outfstrg() 1");
-
- cp = strg->st_cp;
-
- outchar('"');
-
- c = *cp++;
-
- while (c != '\0') {
-
- if (c != '%') {
- c = *cp++;
- continue;
- }
-
- outqchar('%');
- c = *cp++;
-
- /* flags for printf and scanf and *-fieldwidth for printf */
- while (c != '\0' && (c == '-' || c == '+' || c == ' ' ||
- c == '#' || c == '0' || c == '*')) {
- outqchar(c);
- c = *cp++;
- }
-
- /* numeric field width */
- while (isdigit(c)) {
- outqchar(c);
- c = *cp++;
- }
-
- /* precision for printf */
- if (c == '.') {
- outqchar(c);
- if ((c = *cp++) == '*') {
- outqchar(c);
- c = *cp++;
- } else {
- while (isdigit(c)) {
- outqchar(c);
- c = *cp++;
- }
- }
- }
-
- /* h, l, L and q flags fpr printf and scanf */
- if (c == 'h' || c == 'l' || c == 'L' || c == 'q') {
- outqchar(c);
- c = *cp++;
- }
-
- /*
- * The last character. It is always written so we can detect
- * invalid format specifiers.
- */
- if (c != '\0') {
- outqchar(c);
- oc = c;
- c = *cp++;
- /*
- * handle [ for scanf. [-] means that a minus sign
- * was found at an undefined position.
- */
- if (oc == '[') {
- if (c == '^')
- c = *cp++;
- if (c == ']')
- c = *cp++;
- first = 1;
- while (c != '\0' && c != ']') {
- if (c == '-') {
- if (!first && *cp != ']')
- outqchar(c);
- }
- first = 0;
- c = *cp++;
- }
- if (c == ']') {
- outqchar(c);
- c = *cp++;
- }
- }
- }
-
- }
-
- outchar('"');
-}
-
-/*
- * writes a record if sym was used
- */
-void
-outusg(sym_t *sym)
-{
- /* reset buffer */
- outclr();
-
- /*
- * line number of .c source, 'u' for used, Id of current
- * source (.c or .h), and line in current source
- */
- outint(csrc_pos.p_line);
- outchar('u');
- outint(getfnid(curr_pos.p_file));
- outchar('.');
- outint(curr_pos.p_line);
-
- /* necessary to delimit both numbers */
- outchar('x');
-
- /* Den Namen des Symbols ausgeben */
- outname(sym->s_name);
-}
diff --git a/usr.bin/xlint/lint1/err.c b/usr.bin/xlint/lint1/err.c
deleted file mode 100644
index 98c6b59d204..00000000000
--- a/usr.bin/xlint/lint1/err.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/* $OpenBSD: err.c,v 1.28 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: err.c,v 1.8 1995/10/02 17:37:00 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* number of errors found */
-int nerr;
-
-/* number of syntax errors */
-int sytxerr;
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <err.h>
-
-#include "lint1.h"
-
-static const char *lbasename(const char *);
-static void verror(int, va_list);
-static void vwarning(int, va_list);
-static void excerpt(pos_t *);
-
-const char *msgs[] = {
- "syntax error: empty declaration", /* 0 */
- "old style declaration; add int", /* 1 */
- "empty declaration", /* 2 */
- "%s declared in argument declaration list", /* 3 */
- "illegal type combination", /* 4 */
- "modifying typedef with '%s'; only qualifiers allowed", /* 5 */
- "use 'double' instead of 'long float'", /* 6 */
- "only one storage class allowed", /* 7 */
- "illegal storage class", /* 8 */
- "only register valid as formal parameter storage class", /* 9 */
- "duplicate '%s'", /* 10 */
- "bit-field initializer out of range", /* 11 */
- "compiler takes size of function", /* 12 */
- "incomplete enum type: %s", /* 13 */
- "compiler takes alignment of function", /* 14 */
- "function returns illegal type", /* 15 */
- "array of function is illegal", /* 16 */
- "null dimension", /* 17 */
- "illegal use of 'void'", /* 18 */
- "void type for %s", /* 19 */
- "zero or negative array dimension", /* 20 */
- "redeclaration of formal parameter %s", /* 21 */
- "incomplete or misplaced function definition", /* 22 */
- "undefined label %s", /* 23 */
- "cannot initialize function: %s", /* 24 */
- "cannot initialize typedef: %s", /* 25 */
- "cannot initialize extern declaration: %s", /* 26 */
- "redeclaration of %s", /* 27 */
- "redefinition of %s", /* 28 */
- "previously declared extern, becomes static: %s", /* 29 */
- "redeclaration of %s; ANSI C requires static", /* 30 */
- "incomplete structure or union %s: %s", /* 31 */
- "argument type defaults to 'int': %s", /* 32 */
- "duplicate member name: %s", /* 33 */
- "nonportable bit-field type", /* 34 */
- "illegal bit-field type", /* 35 */
- "illegal bit-field size", /* 36 */
- "zero size bit-field", /* 37 */
- "function illegal in structure or union", /* 38 */
- "illegal zero sized structure member: %s", /* 39 */
- "unknown size: %s", /* 40 */
- "illegal use of bit-field", /* 41 */
- "forward reference to enum type", /* 42 */
- "redefinition hides earlier one: %s", /* 43 */
- "declaration introduces new type in ANSI C: %s %s", /* 44 */
- "base type is really '%s %s'", /* 45 */
- "(%s) tag redeclared", /* 46 */
- "zero sized %s", /* 47 */
- "overflow in enumeration values: %s", /* 48 */
- "struct or union member must be named", /* 49 */
- "a function is declared as an argument: %s", /* 50 */
- "parameter mismatch: %d declared, %d defined", /* 51 */
- "cannot initialize parameter: %s", /* 52 */
- "declared argument %s is missing", /* 53 */
- "trailing ',' prohibited in enum declaration", /* 54 */
- "integral constant expression expected", /* 55 */
- "integral constant too large", /* 56 */
- "enumeration constant hides parameter: %s", /* 57 */
- "type does not match prototype: %s", /* 58 */
- "formal parameter lacks name: param #%d", /* 59 */
- "void must be sole parameter", /* 60 */
- "void parameter cannot have name: %s", /* 61 */
- "function prototype parameters must have types", /* 62 */
- "prototype does not match old-style definition", /* 63 */
- "()-less function definition", /* 64 */
- "%s has no named members", /* 65 */
- "syntax requires ';' after last struct/union member", /* 66 */
- "cannot return incomplete type", /* 67 */
- "typedef already qualified with '%s'", /* 68 */
- "inappropriate qualifiers with 'void'", /* 69 */
- "%soperand of '%s' is unsigned in ANSI C", /* 70 */
- "too many characters in character constant", /* 71 */
- "typedef declares no type name", /* 72 */
- "empty character constant", /* 73 */
- "no hex digits follow \\x", /* 74 */
- "overflow in hex escape", /* 75 */
- "character escape does not fit in character", /* 76 */
- "bad octal digit %c", /* 77 */
- "nonportable character escape", /* 78 */
- "dubious escape \\%c", /* 79 */
- "dubious escape \\%o", /* 80 */
- "\\a undefined in traditional C", /* 81 */
- "\\x undefined in traditional C", /* 82 */
- "storage class after type is obsolescent", /* 83 */
- "ANSI C requires formal parameter before '...'", /* 84 */
- "dubious tag declaration: %s %s", /* 85 */
- "automatic hides external declaration: %s", /* 86 */
- "static hides external declaration: %s", /* 87 */
- "typedef hides external declaration: %s", /* 88 */
- "typedef redeclared: %s", /* 89 */
- "inconsistent redeclaration of extern: %s", /* 90 */
- "declaration hides parameter: %s", /* 91 */
- "inconsistent redeclaration of static: %s", /* 92 */
- "dubious static function at block level: %s", /* 93 */
- "function has illegal storage class: %s", /* 94 */
- "declaration hides earlier one: %s", /* 95 */
- "cannot dereference non-pointer type", /* 96 */
- "suffix U is illegal in traditional C", /* 97 */
- "suffixes F and L are illegal in traditional C", /* 98 */
- "%s undefined", /* 99 */
- "unary + is illegal in traditional C", /* 100 */
- "undefined struct/union member: %s", /* 101 */
- "illegal member use: %s", /* 102 */
- "left operand of '.' must be struct/union object", /* 103 */
- "left operand of '->' must be pointer to struct/union", /* 104 */
- "non-unique member requires struct/union %s", /* 105 */
- "left operand of '->' must be pointer", /* 106 */
- "operands of '%s' have incompatible types", /* 107 */
- "operand of '%s' has incompatible type", /* 108 */
- "void type illegal in expression", /* 109 */
- "pointer to function is not allowed here", /* 110 */
- "unacceptable operand of '%s'", /* 111 */
- "cannot take address of bit-field", /* 112 */
- "cannot take address of register %s", /* 113 */
- "%soperand of '%s' must be lvalue", /* 114 */
- "%soperand of '%s' must be modifiable lvalue", /* 115 */
- "illegal pointer subtraction", /* 116 */
- "bitwise operation on signed value possibly nonportable", /* 117 */
- "semantics of '%s' change in ANSI C; use explicit cast", /* 118 */
- "conversion of '%s' to '%s' is out of range", /* 119 */
- "bitwise operation on signed value nonportable", /* 120 */
- "negative shift", /* 121 */
- "shift greater than size of object", /* 122 */
- "illegal combination of pointer and integer, op %s", /* 123 */
- "illegal pointer combination, op %s", /* 124 */
- "ANSI C forbids ordered comparisons of pointers to functions",/* 125 */
- "incompatible types in conditional", /* 126 */
- "'&' before array or function: ignored", /* 127 */
- "operands have incompatible pointer types, op %s", /* 128 */
- "expression has null effect", /* 129 */
- "enum type mismatch, op %s", /* 130 */
- "conversion from '%s' to '%s' may sign-extend incorrectly", /* 131 */
- "converted from '%s' to '%s'", /* 132 */
- "conversion of pointer to '%s' loses bits", /* 133 */
- "conversion of pointer to '%s' may lose bits", /* 134 */
- "possible pointer alignment problem", /* 135 */
- "cannot do pointer arithmetic on operand of unknown size", /* 136 */
- "use of incomplete enum type, op %s", /* 137 */
- "unknown operand size, op %s", /* 138 */
- "division by 0", /* 139 */
- "modulus by 0", /* 140 */
- "integer overflow detected, op %s", /* 141 */
- "floating point overflow detected, op %s", /* 142 */
- "cannot take size of incomplete type", /* 143 */
- "cannot take size of function", /* 144 */
- "cannot take size of bit-field", /* 145 */
- "cannot take size of void", /* 146 */
- "invalid cast expression", /* 147 */
- "improper cast of void expression", /* 148 */
- "illegal function", /* 149 */
- "argument mismatch: %d arg%s passed, %d expected", /* 150 */
- "void expressions may not be arguments, arg #%d", /* 151 */
- "argument cannot have unknown size, arg #%d", /* 152 */
- "%s() arg #%d: incompatible pointer type", /* 153 */
- "%s() arg #%d: illegal combination of pointer and integer", /* 154 */
- "%s() arg #%d: argument is incompatible with prototype", /* 155 */
- "%s() arg #%d: enum type mismatch", /* 156 */
- "ANSI C treats constant as unsigned", /* 157 */
- "%s may be used before set", /* 158 */
- "assignment in conditional context", /* 159 */
- "operator '==' found where '=' was expected", /* 160 */
- "constant in conditional context", /* 161 */
- "comparison of %s with %s, op %s", /* 162 */
- "a cast does not yield an lvalue", /* 163 */
- "assignment of negative constant to unsigned type", /* 164 */
- "constant truncated by assignment", /* 165 */
- "precision lost in bit-field assignment", /* 166 */
- "array subscript cannot be negative: %ld", /* 167 */
- "array subscript cannot be > %d: %ld", /* 168 */
- "precedence confusion possible: parenthesize!", /* 169 */
- "first operand must have scalar type, op ? :", /* 170 */
- "assignment type mismatch", /* 171 */
- "too many struct/union initializers", /* 172 */
- "too many array initializers", /* 173 */
- "too many initializers", /* 174 */
- "initialisation of an incomplete type", /* 175 */
- "invalid initializer", /* 176 */
- "non-constant initializer", /* 177 */
- "initializer does not fit", /* 178 */
- "cannot initialize struct/union with no named member", /* 179 */
- "bit-field initializer does not fit", /* 180 */
- "{}-enclosed initializer required", /* 181 */
- "incompatible pointer types", /* 182 */
- "illegal combination of pointer and integer", /* 183 */
- "illegal pointer combination", /* 184 */
- "initialisation type mismatch", /* 185 */
- "bit-field initialisation is illegal in traditional C", /* 186 */
- "non-null byte ignored in string initializer", /* 187 */
- "no automatic aggregate initialization in traditional C", /* 188 */
- "assignment of struct/union illegal in traditional C", /* 189 */
- "empty array declaration: %s", /* 190 */
- "%s set but not used in function %s", /* 191 */
- "%s unused in function %s", /* 192 */
- "statement not reached", /* 193 */
- "label %s redefined", /* 194 */
- "case not in switch", /* 195 */
- "case label affected by conversion", /* 196 */
- "non-constant case expression", /* 197 */
- "non-integral case expression", /* 198 */
- "duplicate case in switch: %ld", /* 199 */
- "duplicate case in switch: %lu", /* 200 */
- "default outside switch", /* 201 */
- "duplicate default in switch", /* 202 */
- "case label must be of type `int' in traditional C", /* 203 */
- "controlling expressions must have scalar type", /* 204 */
- "switch expression must have integral type", /* 205 */
- "enumeration value(s) not handled in switch", /* 206 */
- "loop not entered at top", /* 207 */
- "break outside loop or switch", /* 208 */
- "continue outside loop", /* 209 */
- "enum type mismatch in initialisation", /* 210 */
- "return value type mismatch", /* 211 */
- "cannot return incomplete type", /* 212 */
- "void function %s cannot return value", /* 213 */
- "function %s expects to return value", /* 214 */
- "function implicitly declared to return int", /* 215 */
- "function %s has return (e); and return;", /* 216 */
- "function %s falls off bottom without returning value", /* 217 */
- "ANSI C treats constant as unsigned, op %s", /* 218 */
- "concatenated strings are illegal in traditional C", /* 219 */
- "fallthrough on case statement", /* 220 */
- "initialisation of unsigned with negative constant", /* 221 */
- "conversion of negative constant to unsigned type", /* 222 */
- "end-of-loop code not reached", /* 223 */
- "cannot recover from previous errors", /* 224 */
- "static function called but not defined: %s()", /* 225 */
- "static variable %s unused", /* 226 */
- "const object %s should have initializer", /* 227 */
- "function cannot return const or volatile object", /* 228 */
- "questionable conversion of function pointer", /* 229 */
- "nonportable character comparison, op %s", /* 230 */
- "argument %s unused in function %s()", /* 231 */
- "label %s unused in function %s()", /* 232 */
- "struct %s never defined", /* 233 */
- "union %s never defined", /* 234 */
- "enum %s never defined", /* 235 */
- "static function %s unused", /* 236 */
- "redeclaration of formal parameter %s", /* 237 */
- "initialisation of union is illegal in traditional C", /* 238 */
- "constant argument to NOT", /* 239 */
- "assignment of different structures", /* 240 */
- "dubious operation on enum, op %s", /* 241 */
- "combination of '%s' and '%s', op %s", /* 242 */
- "dubious comparison of enums, op %s", /* 243 */
- "illegal structure pointer combination", /* 244 */
- "illegal structure pointer combination, op %s", /* 245 */
- "dubious conversion of enum to '%s'", /* 246 */
- "pointer casts may be troublesome", /* 247 */
- "floating-point constant out of range", /* 248 */
- "syntax error", /* 249 */
- "unknown character \\%o", /* 250 */
- "malformed integer constant", /* 251 */
- "integer constant out of range", /* 252 */
- "unterminated character constant", /* 253 */
- "newline in string or char constant", /* 254 */
- "undefined or invalid # directive", /* 255 */
- "unterminated comment", /* 256 */
- "extra characters in lint comment", /* 257 */
- "unterminated string constant", /* 258 */
- "%s() arg #%d: converted from '%s' to '%s'", /* 259 */
- "previous declaration of %s", /* 260 */
- "previous definition of %s", /* 261 */
- "\\\" inside character constants undefined in traditional C", /* 262 */
- "\\? undefined in traditional C", /* 263 */
- "\\v undefined in traditional C", /* 264 */
- "%s C does not support 'long long'", /* 265 */
- "'long double' is illegal in traditional C", /* 266 */
- "shift equal to size of object", /* 267 */
- "variable declared inline: %s", /* 268 */
- "argument declared inline: %s", /* 269 */
- "function prototypes are illegal in traditional C", /* 270 */
- "switch expression must be of type `int' in traditional C", /* 271 */
- "empty translation unit", /* 272 */
- "bit-field type '%s' invalid in ANSI C", /* 273 */
- "ANSI C forbids comparison of %s with %s", /* 274 */
- "cast discards 'const' from pointer target type", /* 275 */
- "", /* 276 */
- "initialisation of '%s' with '%s'", /* 277 */
- "%s() arg #%d: combination of '%s' and '%s'", /* 278 */
- "combination of '%s' and '%s' in return", /* 279 */
- "must be outside function: /* %s */", /* 280 */
- "duplicate use of /* %s */", /* 281 */
- "must precede function definition: /* %s */", /* 282 */
- "argument number mismatch with directive: /* %s */", /* 283 */
- "fallthrough on default statement", /* 284 */
- "prototype declaration", /* 285 */
- "function definition is not a prototype", /* 286 */
- "function declaration is not a prototype", /* 287 */
- "dubious use of /* VARARGS */ with /* %s */", /* 288 */
- "can't be used together: /* PRINTFLIKE */ /* SCANFLIKE */", /* 289 */
- "static function %s declared but not defined", /* 290 */
- "invalid multibyte character", /* 291 */
- "cannot concatenate wide and regular string literals", /* 292 */
- "argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE", /* 293 */
- "multi-character character constant", /* 294 */
- "%s() arg #%d: conversion of '%s' to '%s' is out of range", /* 295 */
- "%s() arg #%d: conversion of negative constant to unsigned type", /* 296 */
- "%s() arg #%d: conversion from '%s' to '%s' may sign-extend incorrectly", /* 297 */
- "%s() arg #%d: converted from '%s' to '%s'", /* 298 */
- "prototype does not match old style definition, arg #%d", /* 299 */
- "old style definition", /* 300 */
- "array of incomplete type", /* 301 */
- "%s returns pointer to automatic object", /* 302 */
- "ANSI C forbids conversion of %s to %s", /* 303 */
- "ANSI C forbids conversion of %s to %s, arg #%d", /* 304 */
- "ANSI C forbids conversion of %s to %s, op %s", /* 305 */
- "constant truncated by conversion, op %s", /* 306 */
- "static variable %s set but not used", /* 307 */
- "", /* 308 */
- "extra bits set to 0 in conversion of '%s' to '%s', op %s", /* 309 */
- "right shift of %d-bit quantity by %lld bits", /* 310 */
- "case ranges are illegal in ANSI C", /* 311 */
- "suspicious operator for sizeof: %s", /* 312 */
- "conversion of %s() return value from '%s' to '%s'", /* 313 */
- "hexadecimal float constants are illegal in traditional C", /* 314 */
- "empty body of the if statement", /* 315 */
- "empty body of the else statement", /* 316 */
-};
-
-/*
- * If Fflag is not set lbasename() returns a pointer to the last
- * component of the path, otherwise it returns the argument.
- */
-static const char *
-lbasename(const char *path)
-{
- const char *cp, *cp1, *cp2;
-
- if (Fflag)
- return (path);
-
- cp = cp1 = cp2 = path;
- while (*cp != '\0') {
- if (*cp++ == '/') {
- cp2 = cp1;
- cp1 = cp;
- }
- }
- return (*cp1 == '\0' ? cp2 : cp1);
-}
-
-static void
-verror(int n, va_list ap)
-{
- const char *fn;
-
- fn = lbasename(curr_pos.p_file);
- (void)printf("%s:%d: ", fn, curr_pos.p_line);
- (void)vprintf(msgs[n], ap);
- (void)printf("\n");
- nerr++;
-
- if (fflag)
- excerpt(&curr_pos);
-
-}
-
-static void
-vwarning(int n, va_list ap)
-{
- const char *fn;
-
- if (nowarn)
- /* this warning is suppressed by a LINTED comment */
- return;
-
- fn = lbasename(curr_pos.p_file);
- (void)printf("%s:%d: warning: ", fn, curr_pos.p_line);
- (void)vprintf(msgs[n], ap);
- (void)printf("\n");
-
- if (fflag)
- excerpt(&curr_pos);
-}
-
-void
-error(int n, ...)
-{
- va_list ap;
-
- va_start(ap, n);
- verror(n, ap);
- va_end(ap);
-}
-
-void
-lerror(const char *msg, ...)
-{
- va_list ap;
- const char *fn;
-
- va_start(ap, msg);
- fn = lbasename(curr_pos.p_file);
- (void)fprintf(stderr, "%s:%d: lint error: ", fn, curr_pos.p_line);
- (void)vfprintf(stderr, msg, ap);
- (void)fprintf(stderr, "\n");
- va_end(ap);
- exit(1);
-}
-
-void
-warning(int n, ...)
-{
- va_list ap;
-
- va_start(ap, n);
- vwarning(n, ap);
- va_end(ap);
-}
-
-void
-message(int n, ...)
-{
- va_list ap;
- const char *fn;
-
- va_start(ap, n);
- fn = lbasename(curr_pos.p_file);
- (void)printf("%s:%d: ", fn, curr_pos.p_line);
- (void)vprintf(msgs[n], ap);
- (void)printf("\n");
- va_end(ap);
-
- if (fflag)
- excerpt(&curr_pos);
-}
-
-int
-gnuism(int n, ...)
-{
- va_list ap;
- int msg;
-
- va_start(ap, n);
- if (sflag && !gflag) {
- verror(n, ap);
- msg = 1;
- } else if (!sflag && gflag) {
- msg = 0;
- } else {
- vwarning(n, ap);
- msg = 1;
- }
- va_end(ap);
-
- return (msg);
-}
-
-static void
-excerpt(pos_t *pos)
-{
- static FILE *fp = NULL;
- static const char *file = NULL;
- static int lineno = 0;
- char *buf, *lbuf;
- size_t len;
-
- if (!pos || !pos->p_file)
- return;
-
- /* don't print the same line twice */
- if (pos->p_line == lineno)
- return;
-
- if (fp == NULL || file != pos->p_file || pos->p_line < lineno) {
- if (fp)
- fclose(fp);
-
- if (!(fp = fopen(pos->p_file, "r")))
- return;
-
- file = pos->p_file;
- lineno = 0;
- }
-
- lbuf = NULL;
- while (lineno < pos->p_line && (buf = fgetln(fp, &len))) {
- if (buf[len - 1] == '\n')
- buf[len - 1] = '\0';
- else {
- /* EOF without EOL, copy and add the NUL */
- if (!(lbuf = malloc(len + 1)))
- err(1, NULL);
-
- lbuf[len] = '\0';
- buf = lbuf;
- }
- lineno++;
- }
-
- if (buf)
- printf("%s:%d: %s\n", pos->p_file, lineno, buf);
-
- free(lbuf);
-}
diff --git a/usr.bin/xlint/lint1/externs.h b/usr.bin/xlint/lint1/externs.h
deleted file mode 100644
index a8834ab559f..00000000000
--- a/usr.bin/xlint/lint1/externs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $OpenBSD: externs.h,v 1.4 2006/03/08 07:18:51 moritz Exp $ */
-/* $NetBSD: externs.h,v 1.2 1995/07/03 21:24:06 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * mem.c
- */
-extern void *xmalloc(size_t);
-extern void *xcalloc(size_t, size_t);
-extern void *xrealloc(void *, size_t);
-extern char *xstrdup(const char *);
-
-/*
- * emit.c
- */
-extern ob_t ob;
-
-extern void outopen(const char *);
-extern void outclose(void);
-extern void outclr(void);
-extern void outchar(int);
-extern void outqchar(int);
-extern void outstrg(const char *);
-extern void outint(int);
-extern void outname(const char *);
-extern void outsrc(const char *);
diff --git a/usr.bin/xlint/lint1/externs1.h b/usr.bin/xlint/lint1/externs1.h
deleted file mode 100644
index d9d19299b16..00000000000
--- a/usr.bin/xlint/lint1/externs1.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/* $OpenBSD: externs1.h,v 1.16 2010/07/24 22:17:03 guenther Exp $ */
-/* $NetBSD: externs1.h,v 1.7 1995/10/02 17:31:39 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * main.c
- */
-extern int cflag;
-extern int dflag;
-extern int eflag;
-extern int fflag;
-extern int Fflag;
-extern int gflag;
-extern int hflag;
-extern int pflag;
-extern int rflag;
-extern int sflag;
-extern int uflag;
-extern int vflag;
-extern int yflag;
-extern int zflag;
-
-extern void norecover(void);
-
-/*
- * cgram.y
- */
-extern int blklev;
-extern int mblklev;
-extern int yydebug;
-
-extern int yyerror(char *);
-extern int yyparse(void);
-
-/*
- * scan.l
- */
-extern pos_t curr_pos;
-extern pos_t csrc_pos;
-extern symt_t symtyp;
-extern FILE *yyin;
-extern u_quad_t qbmasks[], qlmasks[], qumasks[];
-
-extern void initscan(void);
-extern int sign(quad_t, tspec_t, int);
-extern int msb(quad_t, tspec_t, int);
-extern quad_t xsign(quad_t, tspec_t, int);
-extern void clrwflgs(void);
-extern sym_t *getsym(sbuf_t *);
-extern void cleanup(void);
-extern sym_t *pushdown(sym_t *);
-extern void rmsym(sym_t *);
-extern void rmsyms(sym_t *);
-extern void inssym(int, sym_t *);
-extern void freeyyv(void *, int);
-extern int yylex(void);
-
-/*
- * mem1.c
- */
-extern const char *fnalloc(const char *);
-extern const char *fnnalloc(const char *, size_t);
-extern int getfnid(const char *);
-
-extern void initmem(void);
-
-extern void *getblk(size_t);
-extern void *getlblk(int, size_t);
-extern void freeblk(void);
-extern void freelblk(int);
-
-extern void *tgetblk(size_t);
-extern tnode_t *getnode(void);
-extern void tfreeblk(void);
-extern struct mbl *tsave(void);
-extern void trestor(struct mbl *);
-
-/*
- * err.c
- */
-extern int nerr;
-extern int sytxerr;
-extern const char *msgs[];
-
-extern void error(int, ...);
-extern void warning(int, ...);
-extern void message(int, ...);
-extern int gnuism(int, ...);
-extern void lerror(const char *, ...);
-
-/*
- * decl.c
- */
-extern dinfo_t *dcs;
-extern const char *unnamed;
-extern int enumval;
-
-extern void initdecl(void);
-extern type_t *gettyp(tspec_t);
-extern type_t *duptyp(const type_t *);
-extern type_t *tduptyp(const type_t *);
-extern int incompl(type_t *);
-extern void setcompl(type_t *, int);
-extern void addscl(scl_t);
-extern void addtype(type_t *);
-extern void addqual(tqual_t);
-extern void pushdecl(scl_t);
-extern void popdecl(void);
-extern void setasm(void);
-extern void clrtyp(void);
-extern int mergedomain(tspec_t *, tspec_t);
-extern void deftyp(void);
-extern int length(type_t *, const char *);
-extern int getbound(type_t *);
-extern sym_t *lnklst(sym_t *, sym_t *);
-extern void chktyp(sym_t *);
-extern sym_t *decl1str(sym_t *);
-extern sym_t *bitfield(sym_t *, int);
-extern pqinf_t *mergepq(pqinf_t *, pqinf_t *);
-extern sym_t *addptr(sym_t *, pqinf_t *);
-extern sym_t *addarray(sym_t *, int, int);
-extern sym_t *addfunc(sym_t *, sym_t *);
-extern void chkfdef(sym_t *, int);
-extern sym_t *dname(sym_t *);
-extern sym_t *iname(sym_t *);
-extern type_t *mktag(sym_t *, tspec_t, int, int);
-extern const char *scltoa(scl_t);
-extern type_t *compltag(type_t *, sym_t *);
-extern sym_t *ename(sym_t *, int, int);
-extern void decl1ext(sym_t *, int);
-extern void cpuinfo(sym_t *, sym_t *);
-extern int isredec(sym_t *, int *);
-extern int eqtype(type_t *, type_t *, int, int, int *);
-extern void compltyp(sym_t *, sym_t *);
-extern sym_t *decl1arg(sym_t *, int);
-extern void cluparg(void);
-extern void decl1loc(sym_t *, int);
-extern sym_t *aname(void);
-extern void globclup(void);
-extern sym_t *decl1abs(sym_t *);
-extern void chksz(sym_t *);
-extern void setsflg(sym_t *);
-extern void setuflg(sym_t *, int, int);
-extern void chkusage(dinfo_t *);
-extern void chkusg1(int, sym_t *);
-extern void chkglsyms(void);
-extern void prevdecl(int, sym_t *);
-
-/*
- * tree.c
- */
-extern void initmtab(void);
-extern type_t *incref(type_t *, tspec_t);
-extern type_t *tincref(type_t *, tspec_t);
-extern tnode_t *getcnode(type_t *, val_t *);
-extern tnode_t *getnnode(sym_t *, int);
-extern tnode_t *getsnode(strg_t *);
-extern sym_t *strmemb(tnode_t *, op_t, sym_t *);
-extern tnode_t *build(op_t, tnode_t *, tnode_t *);
-extern tnode_t *cconv(tnode_t *);
-extern int typeok(op_t, farg_t *, tnode_t *, tnode_t *);
-extern tnode_t *promote(op_t, int, tnode_t *);
-extern tnode_t *convert(op_t, farg_t *, type_t *, tnode_t *);
-extern void cvtcon(op_t, farg_t *, type_t *, val_t *, val_t *);
-extern const char *tyname(type_t *);
-extern tnode_t *bldszof(type_t *);
-extern tnode_t *bldszoftrm(tnode_t *);
-extern tnode_t *cast(tnode_t *, type_t *);
-extern tnode_t *funcarg(tnode_t *, tnode_t *);
-extern tnode_t *funccall(tnode_t *, tnode_t *);
-extern val_t *constant(tnode_t *);
-extern void expr(tnode_t *, int, int);
-extern void chkmisc(tnode_t *, int, int, int, int, int, int);
-extern int conaddr(tnode_t *, sym_t **, ptrdiff_t *);
-extern strg_t *catstrg(strg_t *, strg_t *);
-extern void displexpr(tnode_t *, int);
-
-/*
- * func.c
- */
-extern sym_t *funcsym;
-extern int reached;
-extern int rchflg;
-extern int ftflg;
-extern int nargusg;
-extern pos_t aupos;
-extern int nvararg;
-extern pos_t vapos;
-extern int prflstrg;
-extern pos_t prflpos;
-extern int scflstrg;
-extern pos_t scflpos;
-extern int ccflg;
-extern int llibflg;
-extern int nowarn;
-extern int noretflg;
-extern int usedflg;
-extern int plibflg;
-extern int quadflg;
-
-extern void pushctrl(int);
-extern void popctrl(int);
-extern void chkreach(void);
-extern void funcdef(sym_t *);
-extern void funcend(void);
-extern void label(int, sym_t *, tnode_t *);
-extern void if1(tnode_t *);
-extern void if2(void);
-extern void if3(int);
-extern void switch1(tnode_t *);
-extern void switch2(void);
-extern void while1(tnode_t *);
-extern void while2(void);
-extern void do1(void);
-extern void do2(tnode_t *);
-extern void for1(tnode_t *, tnode_t *, tnode_t *);
-extern void for2(void);
-extern void dogoto(sym_t *);
-extern void docont(void);
-extern void dobreak(void);
-extern void doreturn(tnode_t *);
-extern void glclup(int);
-extern void argsused(int);
-extern void noreturn(int);
-extern void lintused(int);
-extern void constcond(int);
-extern void fallthru(int);
-extern void notreach(int);
-extern void lintlib(int);
-extern void linted(int);
-extern void varargs(int);
-extern void printflike(int);
-extern void scanflike(int);
-extern void protolib(int);
-extern void longlong(int);
-
-/*
- * init.c
- */
-extern int initerr;
-extern sym_t *initsym;
-extern int startinit;
-
-extern void prepinit(void);
-extern void initrbr(void);
-extern void initlbr(void);
-extern void mkinit(tnode_t *);
-
-/*
- * emit.c
- */
-extern void outtype(type_t *);
-extern const char *ttos(type_t *);
-extern void outsym(sym_t *, scl_t, def_t);
-extern void outfdef(sym_t *, pos_t *, int, int, sym_t *);
-extern void outcall(tnode_t *, int, int);
-extern void outusg(sym_t *);
diff --git a/usr.bin/xlint/lint1/func.c b/usr.bin/xlint/lint1/func.c
deleted file mode 100644
index a81c6948998..00000000000
--- a/usr.bin/xlint/lint1/func.c
+++ /dev/null
@@ -1,1287 +0,0 @@
-/* $OpenBSD: func.c,v 1.22 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: func.c,v 1.7 1995/10/02 17:31:40 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "lint1.h"
-#include "y.tab.h"
-
-/*
- * Contains a pointer to the symbol table entry of the current function
- * definition.
- */
-sym_t *funcsym;
-
-/* Is set as long as a statement can be reached. Must be set at level 0. */
-int reached = 1;
-
-/*
- * Is set as long as NOTREACHED is in effect.
- * Is reset everywhere where reached can become 0.
- */
-int rchflg;
-
-/*
- * In conjunction with reached controls printing of "fallthrough on ..."
- * warnings.
- * Reset by each statement and set by FALLTHROUGH, switch (switch1())
- * and case (label()).
- *
- * Control statements if, for, while and switch do not reset ftflg because
- * this must be done by the controled statement. At least for if this is
- * important because ** FALLTHROUGH ** after "if (expr) stmnt" is evaluated
- * befor the following token, wich causes reduction of above, is read.
- * This means that ** FALLTHROUGH ** after "if ..." would always be ignored.
- */
-int ftflg;
-
-/* Top element of stack for control statements */
-cstk_t *cstk;
-
-/*
- * Number of arguments which will be checked for usage in following
- * function definition. -1 stands for all arguments.
- *
- * The position of the last ARGSUSED comment is stored in aupos.
- */
-int nargusg = -1;
-pos_t aupos;
-
-/*
- * If the following function has been declared NORETURN, noretflg is set
- * to 1. Otherwise it is set to 0.
- */
-int noretflg = 0;
-
-/*
- * If the following symbol should be marked as having been used, even if
- * lint thinks otherwise, usedflg is set to 1. Otherwise it is set to 0.
- */
-int usedflg = 0;
-
-/*
- * Number of arguments of the following function definition whose types
- * shall be checked by lint2. -1 stands for all arguments.
- *
- * The position of the last VARARGS comment is stored in vapos.
- */
-int nvararg = -1;
-pos_t vapos;
-
-/*
- * Both prflstr and scflstrg contain the number of the argument which
- * shall be used to check the types of remaining arguments (for PRINTFLIKE
- * and SCANFLIKE).
- *
- * prflpos and scflpos are the positions of the last PRINTFLIKE or
- * SCANFLIKE comment.
- */
-int prflstrg = -1;
-int scflstrg = -1;
-pos_t prflpos;
-pos_t scflpos;
-
-/*
- * Are both plibflg and llibflg set, prototypes are written as function
- * definitions to the output file.
- */
-int plibflg;
-
-/*
- * Nonzero means that no warnings about constants in conditional
- * context are printed.
- */
-int ccflg;
-
-/*
- * llibflg is set if a lint library shall be created. The effect of
- * llibflg is that all defined symbols are treated as used.
- * (The LINTLIBRARY comment also resets vflag.)
- */
-int llibflg;
-
-/*
- * Nonzero if warnings are suppressed by a LINTED directive
- */
-int nowarn;
-
-/*
- * Nonzero if complaints about use of "long long" are suppressed in
- * the next statement or declaration.
- */
-int quadflg = 1;
-
-/*
- * Puts a new element at the top of the stack used for control statements.
- */
-void
-pushctrl(int env)
-{
- cstk_t *ci;
-
- ci = xcalloc(1, sizeof (cstk_t));
- ci->c_env = env;
- ci->c_nxt = cstk;
- cstk = ci;
-}
-
-/*
- * Removes the top element of the stack used for control statements.
- */
-void
-popctrl(int env)
-{
- cstk_t *ci;
- clst_t *cl;
-
- if (cstk == NULL || cstk->c_env != env)
- lerror("popctrl() 1");
-
- cstk = (ci = cstk)->c_nxt;
-
- while ((cl = ci->c_clst) != NULL) {
- ci->c_clst = cl->cl_nxt;
- free(cl);
- }
-
- if (ci->c_swtype != NULL)
- free(ci->c_swtype);
-
- free(ci);
-}
-
-/*
- * Prints a warning if a statement cannot be reached.
- */
-void
-chkreach(void)
-{
- if (!reached && !rchflg) {
- /* statement not reached */
- warning(193);
- reached = 1;
- }
-}
-
-/*
- * Called after a function declaration which introduces a function definition
- * and before an (optional) old style argument declaration list.
- *
- * Puts all symbols declared in the prototype or in an old style argument
- * list back to the symbol table.
- *
- * Does the usual checking of storage class, type (return value),
- * redeclaration etc..
- */
-void
-funcdef(sym_t *fsym)
-{
- int n, warn;
- sym_t *arg, *sym, *rdsym;
-
- funcsym = fsym;
-
- /*
- * Put all symbols declared in the argument list back to the
- * symbol table.
- */
- for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) {
- if (sym->s_blklev != -1) {
- if (sym->s_blklev != 1)
- lerror("funcdef() 1");
- inssym(1, sym);
- }
- }
-
- /*
- * __func__ is a "predefined identifier" in c99, which means it is a
- * block-scope variable supplying the name of the enclosing function.
- * It is defined as:
- *
- * static const char __func__[] = "function-name";
- *
- */
- sym = getblk(sizeof (sym_t));
- sym->s_name = "__func__";
- sym->s_kind = FVFT;
- sym->s_scl = STATIC;
- sym->s_type = incref(gettyp(CHAR), ARRAY);
- sym->s_blklev = 1;
- sym->s_def = DEF;
- sym->s_type->t_dim = strlen(fsym->s_name) + 1;
- sym->s_type->t_subt = duptyp(gettyp(CHAR));
- sym->s_type->t_subt->t_const = 1;
- inssym(1, sym);
-
- /*
- * In osfunc() we did not know whether it is an old style function
- * definition or only an old style declaration, if there are no
- * arguments inside the argument list ("f()").
- */
- if (!fsym->s_type->t_proto && fsym->s_args == NULL)
- fsym->s_osdef = 1;
-
- chktyp(fsym);
-
- /*
- * chktyp() checks for almost all possible errors, but not for
- * incomplete return values (these are allowed in declarations)
- */
- if (fsym->s_type->t_subt->t_tspec != VOID &&
- incompl(fsym->s_type->t_subt)) {
- /* cannot return incomplete type */
- error(67);
- }
-
- fsym->s_def = DEF;
-
- if (fsym->s_scl == TYPEDEF) {
- fsym->s_scl = EXTERN;
- /* illegal storage class */
- error(8);
- }
-
- if (dcs->d_inline)
- fsym->s_inline = 1;
-
- /*
- * Arguments in new style function declarations need a name.
- * (void is already removed from the list of arguments)
- */
- n = 1;
- for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) {
- if (arg->s_scl == ABSTRACT) {
- if (arg->s_name != unnamed)
- lerror("funcdef() 2");
- /* formal parameter lacks name: param #%d */
- error(59, n);
- } else {
- if (arg->s_name == unnamed)
- lerror("funcdef() 3");
- }
- n++;
- }
-
- /*
- * We must also remember the position. s_dpos is overwritten
- * if this is an old style definition and we had already a
- * prototype.
- */
- STRUCT_ASSIGN(dcs->d_fdpos, fsym->s_dpos);
-
- if ((rdsym = dcs->d_rdcsym) != NULL) {
-
- if (!isredec(fsym, (warn = 0, &warn))) {
-
- /*
- * Print nothing if the newly defined function
- * is defined in old style. A better warning will
- * be printed in cluparg().
- */
- if (warn && !fsym->s_osdef) {
- /* redeclaration of %s */
- (*(sflag ? error : warning))(27, fsym->s_name);
- prevdecl(-1, rdsym);
- }
-
- /* copy usage information */
- cpuinfo(fsym, rdsym);
-
- /*
- * If the old symbol was a prototype and the new
- * one is none, overtake the position of the
- * declaration of the prototype.
- */
- if (fsym->s_osdef && rdsym->s_type->t_proto)
- STRUCT_ASSIGN(fsym->s_dpos, rdsym->s_dpos);
-
- /* complete the type */
- compltyp(fsym, rdsym);
-
- /* once a function is inline it remains inline */
- if (rdsym->s_inline)
- fsym->s_inline = 1;
-
- }
-
- /* remove the old symbol from the symbol table */
- rmsym(rdsym);
-
- }
-
- if (fsym->s_osdef && !fsym->s_type->t_proto) {
- if (sflag && hflag && strcmp(fsym->s_name, "main") != 0)
- /* function definition is not a prototype */
- warning(286);
- }
-
- if (dcs->d_notyp)
- /* return value is implicitly declared to be int */
- fsym->s_rimpl = 1;
-
- reached = 1;
-}
-
-/*
- * Called at the end of a function definition.
- */
-void
-funcend(void)
-{
- sym_t *arg;
- int n;
-
- if (reached) {
- cstk->c_noretval = 1;
- if (funcsym->s_type->t_subt->t_tspec != VOID &&
- !funcsym->s_rimpl) {
- /* func. %s falls off bottom without returning value */
- warning(217, funcsym->s_name);
- }
- }
-
- /*
- * This warning is printed only if the return value was implicitly
- * declared to be int. Otherwise the wrong return statement
- * has already printed a warning.
- */
- if (cstk->c_noretval && cstk->c_retval && funcsym->s_rimpl)
- /* function %s has return (e); and return; */
- warning(216, funcsym->s_name);
-
- /* Print warnings for unused arguments */
- arg = dcs->d_fargs;
- n = 0;
- while (arg != NULL && (nargusg == -1 || n < nargusg)) {
- chkusg1(dcs->d_asm, arg);
- arg = arg->s_nxt;
- n++;
- }
- nargusg = -1;
-
- if (noretflg)
- funcsym->s_noreturn = 1;
- noretflg = 0;
-
- /*
- * write the information about the function definition to the
- * output file
- * inline functions explicitly declared extern are written as
- * declarations only.
- */
- if (dcs->d_scl == EXTERN && funcsym->s_inline) {
- outsym(funcsym, funcsym->s_scl, DECL);
- } else {
- outfdef(funcsym, &dcs->d_fdpos, cstk->c_retval,
- funcsym->s_osdef, dcs->d_fargs);
- }
-
- /*
- * remove all symbols declared during argument declaration from
- * the symbol table
- */
- if (dcs->d_nxt != NULL || dcs->d_ctx != EXTERN)
- lerror("funcend() 1");
- rmsyms(dcs->d_fpsyms);
-
- /* must be set on level 0 */
- reached = 1;
-}
-
-/*
- * Process a label.
- *
- * typ type of the label (T_NAME, T_DEFAULT or T_CASE).
- * sym symbol table entry of label if typ == T_NAME
- * tn expression if typ == T_CASE
- */
-void
-label(int typ, sym_t *sym, tnode_t *tn)
-{
- cstk_t *ci;
- clst_t *cl;
- val_t *v, *nv;
- tspec_t t;
-
- switch (typ) {
-
- case T_NAME:
- if (sym->s_set) {
- /* label %s redefined */
- error(194, sym->s_name);
- } else {
- setsflg(sym);
- }
- break;
-
- case T_CASE:
-
- /* find the stack entry for the innermost switch statement */
- for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) ;
-
- if (ci == NULL) {
- /* case not in switch */
- error(195);
- tn = NULL;
- } else if (tn != NULL && tn->tn_op != CON) {
- /* non-constant case expression */
- error(197);
- tn = NULL;
- } else if (tn != NULL && !isityp(tn->tn_type->t_tspec)) {
- /* non-integral case expression */
- error(198);
- tn = NULL;
- }
-
- if (tn != NULL) {
-
- if (ci->c_swtype == NULL)
- lerror("label() 1");
-
- if (reached && !ftflg) {
- if (hflag)
- /* fallthrough on case statement */
- warning(220);
- }
-
- t = tn->tn_type->t_tspec;
-
- /*
- * get the value of the expression and convert it
- * to the type of the switch expression
- */
- v = constant(tn);
- nv = xcalloc(1, sizeof (val_t));
- cvtcon(CASE, NULL, ci->c_swtype, nv, v);
- free(v);
-
- /* look if we had this value already */
- for (cl = ci->c_clst; cl != NULL; cl = cl->cl_nxt) {
- if (cl->cl_val.v_quad == nv->v_quad)
- break;
- }
- if (cl != NULL && isutyp(nv->v_tspec)) {
- /* duplicate case in switch, %lu */
- error(200, (u_long)nv->v_quad);
- } else if (cl != NULL) {
- /* duplicate case in switch, %ld */
- error(199, (long)nv->v_quad);
- } else {
- /*
- * append the value to the list of
- * case values
- */
- cl = xcalloc(1, sizeof (clst_t));
- STRUCT_ASSIGN(cl->cl_val, *nv);
- cl->cl_nxt = ci->c_clst;
- ci->c_clst = cl;
- }
- }
- tfreeblk();
- break;
-
- case T_DEFAULT:
-
- /* find the stack entry for the innermost switch statement */
- for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) ;
-
- if (ci == NULL) {
- /* default outside switch */
- error(201);
- } else if (ci->c_default) {
- /* duplicate default in switch */
- error(202);
- } else {
- if (reached && !ftflg) {
- if (hflag)
- /* fallthrough on default statement */
- warning(284);
- }
- ci->c_default = 1;
- }
- break;
- };
- reached = 1;
-}
-
-/*
- * T_IF T_LPARN expr T_RPARN
- */
-void
-if1(tnode_t *tn)
-{
- if (tn != NULL)
- tn = cconv(tn);
- if (tn != NULL)
- tn = promote(NOOP, 0, tn);
- expr(tn, 0, 1);
- pushctrl(T_IF);
-}
-
-/*
- * if_without_else
- * if_without_else T_ELSE
- */
-void
-if2(void)
-{
- cstk->c_rchif = reached ? 1 : 0;
- reached = 1;
-}
-
-/*
- * if_without_else
- * if_without_else T_ELSE stmnt
- */
-void
-if3(int els)
-{
- if (els) {
- reached |= cstk->c_rchif;
- } else {
- reached = 1;
- }
- popctrl(T_IF);
-}
-
-/*
- * T_SWITCH T_LPARN expr T_RPARN
- */
-void
-switch1(tnode_t *tn)
-{
- type_t *tp;
-
- if (tn != NULL)
- tn = cconv(tn);
- if (tn != NULL)
- tn = promote(NOOP, 0, tn);
- if (tn != NULL && !isityp(tn->tn_type->t_tspec)) {
- /* switch expression must have integral type */
- error(205);
- tn = NULL;
- }
-
- /*
- * Remember the type of the expression. Because its possible
- * that (*tp) is allocated on tree memory the type must be
- * duplicated. This is not too complicated because it is
- * only an integer type.
- */
- tp = xcalloc(1, sizeof (type_t));
- if (tn != NULL) {
- tp->t_tspec = tn->tn_type->t_tspec;
- if ((tp->t_isenum = tn->tn_type->t_isenum) != 0)
- tp->t_enum = tn->tn_type->t_enum;
- } else {
- tp->t_tspec = INT;
- }
-
- expr(tn, 1, 0);
-
- pushctrl(T_SWITCH);
- cstk->c_switch = 1;
- cstk->c_swtype = tp;
-
- reached = rchflg = 0;
- ftflg = 1;
-}
-
-/*
- * switch_expr stmnt
- */
-void
-switch2(void)
-{
- int nenum, nclab;
- sym_t *esym;
- clst_t *cl;
-
- if (cstk->c_swtype == NULL)
- lerror("switch2() 1");
-
- /*
- * If the switch expression was of type enumeration, count the case
- * labels and the number of enumerators. If both counts are not
- * equal print a warning.
- */
- if (cstk->c_swtype->t_isenum) {
- nenum = nclab = 0;
- if (cstk->c_swtype->t_enum == NULL)
- lerror("switch2() 2");
- for (esym = cstk->c_swtype->t_enum->elem;
- esym != NULL; esym = esym->s_nxt) {
- nenum++;
- }
- for (cl = cstk->c_clst; cl != NULL; cl = cl->cl_nxt)
- nclab++;
- if (hflag && eflag && nenum != nclab && !cstk->c_default) {
- /* enumeration value(s) not handled in switch */
- warning(206);
- }
- }
-
- if (cstk->c_break) {
- /*
- * end of switch always reached (c_break is only set if the
- * break statement can be reached).
- */
- reached = 1;
- } else if (!cstk->c_default &&
- (!hflag || !cstk->c_swtype->t_isenum || nenum != nclab)) {
- /*
- * there are possible values which are not handled in
- * switch
- */
- reached = 1;
- } /*
- * otherwise the end of the switch expression is reached
- * if the end of the last statement inside it is reached.
- */
-
- popctrl(T_SWITCH);
-}
-
-/*
- * T_WHILE T_LPARN expr T_RPARN
- */
-void
-while1(tnode_t *tn)
-{
- if (!reached) {
- /* loop not entered at top */
- warning(207);
- reached = 1;
- }
-
- if (tn != NULL)
- tn = cconv(tn);
- if (tn != NULL)
- tn = promote(NOOP, 0, tn);
- if (tn != NULL && !issclt(tn->tn_type->t_tspec)) {
- /* controlling expressions must have scalar type */
- error(204);
- tn = NULL;
- }
-
- pushctrl(T_WHILE);
- cstk->c_loop = 1;
- if (tn != NULL && tn->tn_op == CON) {
- if (isityp(tn->tn_type->t_tspec)) {
- cstk->c_infinite = tn->tn_val->v_quad != 0;
- } else {
- cstk->c_infinite = tn->tn_val->v_ldbl != 0.0;
- }
- }
-
- expr(tn, 0, 1);
-}
-
-/*
- * while_expr stmnt
- * while_expr error
- */
-void
-while2(void)
-{
- /*
- * The end of the loop can be reached if it is no endless loop
- * or there was a break statement which was reached.
- */
- reached = !cstk->c_infinite || cstk->c_break;
- rchflg = 0;
-
- popctrl(T_WHILE);
-}
-
-/*
- * T_DO
- */
-void
-do1(void)
-{
- if (!reached) {
- /* loop not entered at top */
- warning(207);
- reached = 1;
- }
-
- pushctrl(T_DO);
- cstk->c_loop = 1;
-}
-
-/*
- * do stmnt do_while_expr
- * do error
- */
-void
-do2(tnode_t *tn)
-{
- /*
- * If there was a continue statement the expression controlling the
- * loop is reached.
- */
- if (cstk->c_cont)
- reached = 1;
-
- if (tn != NULL)
- tn = cconv(tn);
- if (tn != NULL)
- tn = promote(NOOP, 0, tn);
- if (tn != NULL && !issclt(tn->tn_type->t_tspec)) {
- /* controlling expressions must have scalar type */
- error(204);
- tn = NULL;
- }
-
- if (tn != NULL && tn->tn_op == CON) {
- if (isityp(tn->tn_type->t_tspec)) {
- cstk->c_infinite = tn->tn_val->v_quad != 0;
- } else {
- cstk->c_infinite = tn->tn_val->v_ldbl != 0.0;
- }
- }
-
- expr(tn, 0, 1);
-
- /*
- * The end of the loop is only reached if it is no endless loop
- * or there was a break statement which could be reached.
- */
- reached = !cstk->c_infinite || cstk->c_break;
- rchflg = 0;
-
- popctrl(T_DO);
-}
-
-/*
- * T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN
- */
-void
-for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3)
-{
- /*
- * If there is no initialisation expression it is possible that
- * it is intended not to enter the loop at top.
- */
- if (tn1 != NULL && !reached) {
- /* loop not entered at top */
- warning(207);
- reached = 1;
- }
-
- pushctrl(T_FOR);
- cstk->c_loop = 1;
-
- /*
- * Store the tree memory for the reinitialisation expression.
- * Also remember this expression itself. We must check it at
- * the end of the loop to get "used but not set" warnings correct.
- */
- cstk->c_fexprm = tsave();
- cstk->c_f3expr = tn3;
- STRUCT_ASSIGN(cstk->c_fpos, curr_pos);
- STRUCT_ASSIGN(cstk->c_cfpos, csrc_pos);
-
- if (tn1 != NULL)
- expr(tn1, 0, 0);
-
- if (tn2 != NULL)
- tn2 = cconv(tn2);
- if (tn2 != NULL)
- tn2 = promote(NOOP, 0, tn2);
- if (tn2 != NULL && !issclt(tn2->tn_type->t_tspec)) {
- /* controlling expressions must have scalar type */
- error(204);
- tn2 = NULL;
- }
- if (tn2 != NULL)
- expr(tn2, 0, 1);
-
- if (tn2 == NULL) {
- cstk->c_infinite = 1;
- } else if (tn2->tn_op == CON) {
- if (isityp(tn2->tn_type->t_tspec)) {
- cstk->c_infinite = tn2->tn_val->v_quad != 0;
- } else {
- cstk->c_infinite = tn2->tn_val->v_ldbl != 0.0;
- }
- }
-
- /* Checking the reinitialisation expression is done in for2() */
-
- reached = 1;
-}
-
-/*
- * for_exprs stmnt
- * for_exprs error
- */
-void
-for2(void)
-{
- pos_t cpos, cspos;
- tnode_t *tn3;
-
- if (cstk->c_cont)
- reached = 1;
-
- STRUCT_ASSIGN(cpos, curr_pos);
- STRUCT_ASSIGN(cspos, csrc_pos);
-
- /* Restore the tree memory for the reinitialisation expression */
- trestor(cstk->c_fexprm);
- tn3 = cstk->c_f3expr;
- STRUCT_ASSIGN(curr_pos, cstk->c_fpos);
- STRUCT_ASSIGN(csrc_pos, cstk->c_cfpos);
-
- /* simply "statement not reached" would be confusing */
- if (!reached && !rchflg) {
- /* end-of-loop code not reached */
- warning(223);
- reached = 1;
- }
-
- if (tn3 != NULL) {
- expr(tn3, 0, 0);
- } else {
- tfreeblk();
- }
-
- STRUCT_ASSIGN(curr_pos, cpos);
- STRUCT_ASSIGN(csrc_pos, cspos);
-
- /* An endless loop without break will never terminate */
- reached = cstk->c_break || !cstk->c_infinite;
- rchflg = 0;
-
- popctrl(T_FOR);
-}
-
-/*
- * T_GOTO identifier T_SEMI
- * T_GOTO error T_SEMI
- */
-void
-dogoto(sym_t *lab)
-{
- setuflg(lab, 0, 0);
-
- chkreach();
-
- reached = rchflg = 0;
-}
-
-/*
- * T_BREAK T_SEMI
- */
-void
-dobreak(void)
-{
- cstk_t *ci;
-
- ci = cstk;
- while (ci != NULL && !ci->c_loop && !ci->c_switch)
- ci = ci->c_nxt;
-
- if (ci == NULL) {
- /* break outside loop or switch */
- error(208);
- } else {
- if (reached)
- ci->c_break = 1;
- }
-
- /* Don't warn about unreachable breaks in a switch, e.g.:
- *
- * switch (foo) {
- * case 1:
- * return 1;
- * break;
- * case 2:
- * // etc...
- * }
- */
- if (ci == NULL || !ci->c_switch)
- chkreach();
-
- reached = rchflg = 0;
-}
-
-/*
- * T_CONTINUE T_SEMI
- */
-void
-docont(void)
-{
- cstk_t *ci;
-
- for (ci = cstk; ci != NULL && !ci->c_loop; ci = ci->c_nxt) ;
-
- if (ci == NULL) {
- /* continue outside loop */
- error(209);
- } else {
- ci->c_cont = 1;
- }
-
- chkreach();
-
- reached = rchflg = 0;
-}
-
-/*
- * T_RETURN T_SEMI
- * T_RETURN expr T_SEMI
- */
-void
-doreturn(tnode_t *tn)
-{
- tnode_t *ln, *rn;
- cstk_t *ci;
- op_t op;
-
- for (ci = cstk; ci->c_nxt != NULL; ci = ci->c_nxt) ;
-
- if (tn != NULL) {
- ci->c_retval = 1;
- } else {
- ci->c_noretval = 1;
- }
-
- if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) {
- /* void function %s cannot return value */
- error(213, funcsym->s_name);
- tfreeblk();
- tn = NULL;
- } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) {
- /*
- * Assume that the function has a return value only if it
- * is explicitly declared.
- */
- if (!funcsym->s_rimpl)
- /* function %s expects to return value */
- warning(214, funcsym->s_name);
- }
-
- if (tn != NULL) {
-
- /* Create a temporary node for the left side */
- ln = tgetblk(sizeof (tnode_t));
- ln->tn_op = NAME;
- ln->tn_type = tduptyp(funcsym->s_type->t_subt);
- ln->tn_type->t_const = 0;
- ln->tn_lvalue = 1;
- ln->tn_sym = funcsym; /* better than nothing */
-
- tn = build(RETURN, ln, tn);
-
- if (tn != NULL) {
- rn = tn->tn_right;
- while ((op = rn->tn_op) == CVT || op == PLUS)
- rn = rn->tn_left;
- if (rn->tn_op == AMPER && rn->tn_left->tn_op == NAME &&
- rn->tn_left->tn_sym->s_scl == AUTO) {
- /* %s returns pointer to automatic object */
- warning(302, funcsym->s_name);
- }
- }
-
- expr(tn, 1, 0);
-
- } else {
-
- chkreach();
-
- }
-
- reached = rchflg = 0;
-}
-
-/*
- * Do some cleanup after a global declaration or definition.
- * Especially remove informations about unused lint comments.
- */
-void
-glclup(int silent)
-{
- pos_t cpos;
-
- STRUCT_ASSIGN(cpos, curr_pos);
-
- if (nargusg != -1) {
- if (!silent) {
- STRUCT_ASSIGN(curr_pos, aupos);
- /* must precede function definition: %s */
- warning(282, "ARGSUSED");
- }
- nargusg = -1;
- }
- if (nvararg != -1) {
- if (!silent) {
- STRUCT_ASSIGN(curr_pos, vapos);
- /* must precede function definition: %s */
- warning(282, "VARARGS");
- }
- nvararg = -1;
- }
- if (prflstrg != -1) {
- if (!silent) {
- STRUCT_ASSIGN(curr_pos, prflpos);
- /* must precede function definition: %s */
- warning(282, "PRINTFLIKE");
- }
- prflstrg = -1;
- }
- if (scflstrg != -1) {
- if (!silent) {
- STRUCT_ASSIGN(curr_pos, scflpos);
- /* must precede function definition: %s */
- warning(282, "SCANFLIKE");
- }
- scflstrg = -1;
- }
-
- STRUCT_ASSIGN(curr_pos, cpos);
-
- dcs->d_asm = 0;
-}
-
-/*
- * ARGSUSED comment
- *
- * Only the first n arguments of the following function are checked
- * for usage. A missing argument is taken to be 0.
- */
-void
-argsused(int n)
-{
- if (n == -1)
- n = 0;
-
- if (dcs->d_ctx != EXTERN) {
- /* must be outside function: ** %s ** */
- warning(280, "ARGSUSED");
- return;
- }
- if (nargusg != -1) {
- /* duplicate use of ** %s ** */
- warning(281, "ARGSUSED");
- }
- nargusg = n;
- STRUCT_ASSIGN(aupos, curr_pos);
-}
-
-/*
- * NORETURN comment
- *
- * The following function will never return, which means any code
- * following a call to this function is unreachable.
- */
-void
-noreturn(int n)
-{
- noretflg = 1;
-}
-
-/*
- * LINTUSED comment
- *
- * Mark a symbol as used, so lint2 does not complain.
- */
-void
-lintused(int n)
-{
- usedflg = 1;
-}
-
-/*
- * VARARGS comment
- *
- * Makes that lint2 checks only the first n arguments for compatibility
- * to the function definition. A missing argument is taken to be 0.
- */
-void
-varargs(int n)
-{
- if (n == -1)
- n = 0;
-
- if (dcs->d_ctx != EXTERN) {
- /* must be outside function: ** %s ** */
- warning(280, "VARARGS");
- return;
- }
- if (nvararg != -1) {
- /* duplicate use of ** %s ** */
- warning(281, "VARARGS");
- }
- nvararg = n;
- STRUCT_ASSIGN(vapos, curr_pos);
-}
-
-/*
- * PRINTFLIKE comment
- *
- * Check all arguments until the (n-1)-th as usual. The n-th argument is
- * used the check the types of remaining arguments.
- */
-void
-printflike(int n)
-{
- if (n == -1)
- n = 0;
-
- if (dcs->d_ctx != EXTERN) {
- /* must be outside function: ** %s ** */
- warning(280, "PRINTFLIKE");
- return;
- }
- if (prflstrg != -1) {
- /* duplicate use of ** %s ** */
- warning(281, "PRINTFLIKE");
- }
- prflstrg = n;
- STRUCT_ASSIGN(prflpos, curr_pos);
-}
-
-/*
- * SCANFLIKE comment
- *
- * Check all arguments until the (n-1)-th as usual. The n-th argument is
- * used the check the types of remaining arguments.
- */
-void
-scanflike(int n)
-{
- if (n == -1)
- n = 0;
-
- if (dcs->d_ctx != EXTERN) {
- /* must be outside function: ** %s ** */
- warning(280, "SCANFLIKE");
- return;
- }
- if (scflstrg != -1) {
- /* duplicate use of ** %s ** */
- warning(281, "SCANFLIKE");
- }
- scflstrg = n;
- STRUCT_ASSIGN(scflpos, curr_pos);
-}
-
-/*
- * Set the linenumber for a CONSTCOND comment. At this and the following
- * line no warnings about constants in conditional contexts are printed.
- */
-/* ARGSUSED */
-void
-constcond(int n)
-{
- ccflg = 1;
-}
-
-/*
- * Suppress printing of "fallthrough on ..." warnings until next
- * statement.
- */
-/* ARGSUSED */
-void
-fallthru(int n)
-{
- ftflg = 1;
-}
-
-/*
- * Stop warnings about statements which cannot be reached. Also tells lint
- * that the following statements cannot be reached (e.g. after exit()).
- */
-/* ARGSUSED */
-void
-notreach(int n)
-{
- reached = 0;
- rchflg = 1;
-}
-
-/* ARGSUSED */
-void
-lintlib(int n)
-{
- if (dcs->d_ctx != EXTERN) {
- /* must be outside function: ** %s ** */
- warning(280, "LINTLIBRARY");
- return;
- }
- llibflg = 1;
- vflag = 0;
-}
-
-/*
- * Suppress most warnings at the current and the following line.
- */
-/* ARGSUSED */
-void
-linted(int n)
-{
- nowarn = 1;
-}
-
-/*
- * PROTOTLIB in conjunction with LINTLIBRARY can be used to handle
- * prototypes like function definitions. This is done if the argument
- * to PROTOLIB is nonzero. Otherwise prototypes are handled normaly.
- */
-void
-protolib(int n)
-{
- if (dcs->d_ctx != EXTERN) {
- /* must be outside function: ** %s ** */
- warning(280, "PROTOLIB");
- return;
- }
- plibflg = n == 0 ? 0 : 1;
-}
-
-/*
- * Set quadflg to nonzero which means that the next statement/declaration
- * may use "long long" without an error or warning.
- */
-/* ARGSUSED */
-void
-longlong(int n)
-{
- quadflg = 1;
-}
diff --git a/usr.bin/xlint/lint1/init.c b/usr.bin/xlint/lint1/init.c
deleted file mode 100644
index 6fbec3194ed..00000000000
--- a/usr.bin/xlint/lint1/init.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/* $OpenBSD: init.c,v 1.13 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-
-#include "lint1.h"
-
-/*
- * initerr is set as soon as a fatal error occurred in an initialisation.
- * The effect is that the rest of the initialisation is ignored (parsed
- * by yacc, expression trees built, but no initialisation takes place).
- */
-int initerr;
-
-/* Pointer to the symbol which is to be initialized. */
-sym_t *initsym;
-
-/* Points to the top element of the initialisation stack. */
-istk_t *initstk;
-
-
-static void popi2(void);
-static void popinit(int);
-static void pushinit(void);
-static void testinit(void);
-static void nextinit(int);
-static int strginit(tnode_t *);
-
-
-/*
- * Initialize the initialisation stack by putting an entry for the variable
- * which is to be initialized on it.
- */
-void
-prepinit(void)
-{
- istk_t *istk;
-
- if (initerr)
- return;
-
- /* free memory used in last initialisation */
- while ((istk = initstk) != NULL) {
- initstk = istk->i_nxt;
- free(istk);
- }
-
- /*
- * If the type which is to be initialized is an incomplete type,
- * it must be duplicated.
- */
- if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
- initsym->s_type = duptyp(initsym->s_type);
-
- istk = initstk = xcalloc(1, sizeof (istk_t));
- istk->i_subt = initsym->s_type;
- istk->i_cnt = 1;
-
-}
-
-static void
-popi2(void)
-{
- istk_t *istk;
- sym_t *m;
-
- initstk = (istk = initstk)->i_nxt;
- if (initstk == NULL)
- lerror("popi2() 1");
- free(istk);
-
- istk = initstk;
-
- istk->i_cnt--;
- if (istk->i_cnt < 0)
- lerror("popi2() 3");
-
- /*
- * If the removed element was a structure member, we must go
- * to the next structure member.
- */
- if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
- do {
- m = istk->i_mem = istk->i_mem->s_nxt;
- if (m == NULL)
- lerror("popi2() 2");
- } while (m->s_field && m->s_name == unnamed);
- istk->i_subt = m->s_type;
- }
-}
-
-static void
-popinit(int brace)
-{
- if (brace) {
- /*
- * Take all entries, including the first which requires
- * a closing brace, from the stack.
- */
- do {
- brace = initstk->i_brace;
- popi2();
- } while (!brace);
- } else {
- /*
- * Take all entries which cannot be used for further
- * initializers from the stack, but do this only if
- * they do not require a closing brace.
- */
- while (!initstk->i_brace &&
- initstk->i_cnt == 0 && !initstk->i_nolimit) {
- popi2();
- }
- }
-}
-
-static void
-pushinit(void)
-{
- istk_t *istk;
- int cnt;
- sym_t *m;
-
- istk = initstk;
-
- /* Extend an incomplete array type by one element */
- if (istk->i_cnt == 0) {
- /*
- * Inside of other aggregate types must not be an incomplete
- * type.
- */
- if (istk->i_nxt->i_nxt != NULL)
- lerror("pushinit() 1");
- istk->i_cnt = 1;
- if (istk->i_type->t_tspec != ARRAY)
- lerror("pushinit() 2");
- istk->i_type->t_dim++;
- /* from now its an complete type */
- setcompl(istk->i_type, 0);
- }
-
- if (istk->i_cnt <= 0)
- lerror("pushinit() 3");
- if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
- lerror("pushinit() 4");
-
- initstk = xcalloc(1, sizeof (istk_t));
- initstk->i_nxt = istk;
- initstk->i_type = istk->i_subt;
- if (initstk->i_type->t_tspec == FUNC)
- lerror("pushinit() 5");
-
- istk = initstk;
-
- switch (istk->i_type->t_tspec) {
- case ARRAY:
- if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
- /* initialisation of an incomplete type */
- error(175);
- initerr = 1;
- return;
- }
- istk->i_subt = istk->i_type->t_subt;
- istk->i_nolimit = incompl(istk->i_type);
- istk->i_cnt = istk->i_type->t_dim;
- break;
- case UNION:
- /* FALLTHROUGH */
- case STRUCT:
- if (incompl(istk->i_type)) {
- /* initialisation of an incomplete type */
- error(175);
- initerr = 1;
- return;
- }
- cnt = 0;
- for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
- if (m->s_field && m->s_name == unnamed)
- continue;
- if (++cnt == 1) {
- istk->i_mem = m;
- istk->i_subt = m->s_type;
- }
- }
- if (cnt == 0) {
- /* cannot init. struct/union with no named member */
- error(179);
- initerr = 1;
- return;
- }
- istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
- break;
- default:
- istk->i_cnt = 1;
- break;
- }
-}
-
-static void
-testinit(void)
-{
- istk_t *istk;
-
- istk = initstk;
-
- /*
- * If a closing brace is expected we have at least one initializer
- * too much.
- */
- if (istk->i_cnt == 0 && !istk->i_nolimit) {
- switch (istk->i_type->t_tspec) {
- case ARRAY:
- /* too many array initializers */
- error(173);
- break;
- case STRUCT:
- case UNION:
- /* too many struct/union initializers */
- error(172);
- break;
- default:
- /* too many initializers */
- error(174);
- break;
- }
- initerr = 1;
- }
-}
-
-static void
-nextinit(int brace)
-{
- if (!brace) {
- if (initstk->i_type == NULL &&
- !issclt(initstk->i_subt->t_tspec)) {
- /* {}-enclosed initializer required */
- error(181);
- }
- /*
- * Make sure an entry with a scalar type is at the top
- * of the stack.
- */
- if (!initerr)
- testinit();
- while (!initerr && (initstk->i_type == NULL ||
- !issclt(initstk->i_type->t_tspec))) {
- if (!initerr)
- pushinit();
- }
- } else {
- if (initstk->i_type != NULL &&
- issclt(initstk->i_type->t_tspec)) {
- /* invalid initializer */
- error(176);
- initerr = 1;
- }
- if (!initerr)
- testinit();
- if (!initerr)
- pushinit();
- if (!initerr)
- initstk->i_brace = 1;
- }
-}
-
-void
-initlbr(void)
-{
- if (initerr)
- return;
-
- /*
- * Remove all entries which cannot be used for further initializers
- * and do not expect a closing brace.
- */
- popinit(0);
-
- nextinit(1);
-}
-
-void
-initrbr(void)
-{
- if (initerr)
- return;
-
- popinit(1);
-}
-
-void
-mkinit(tnode_t *tn)
-{
- ptrdiff_t offs;
- sym_t *sym;
- tspec_t lt, rt;
- tnode_t *ln;
- struct mbl *tmem;
- scl_t sc;
-
- if (initerr || tn == NULL)
- goto end;
-
- sc = initsym->s_scl;
-
- /*
- * Do not test for automatic aggregate initialisation. If the
- * initializer starts with a brace we have the warning already.
- * If not, an error will be printed that the initializer must
- * be enclosed by braces.
- */
-
- /*
- * Local initialisation of non-array-types with only one expression
- * without braces is done by ASSIGN
- */
- if ((sc == AUTO || sc == REG) &&
- initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
- ln = getnnode(initsym, 0);
- ln->tn_type = tduptyp(ln->tn_type);
- ln->tn_type->t_const = 0;
- tn = build(ASSIGN, ln, tn);
- expr(tn, 0, 0);
- goto end;
- }
-
- /*
- * Remove all entries which cannot be used for further initializers
- * and do not require a closing brace.
- */
- popinit(0);
-
- /* Initialisations by strings are done in strginit(). */
- if (strginit(tn))
- goto end;
-
- nextinit(0);
- if (initerr || tn == NULL)
- goto end;
-
- initstk->i_cnt--;
-
- /* Create a temporary node for the left side. */
- ln = tgetblk(sizeof (tnode_t));
- ln->tn_op = NAME;
- ln->tn_type = tduptyp(initstk->i_type);
- ln->tn_type->t_const = 0;
- ln->tn_lvalue = 1;
- ln->tn_sym = initsym; /* better than nothing */
-
- tn = cconv(tn);
-
- lt = ln->tn_type->t_tspec;
- rt = tn->tn_type->t_tspec;
-
- if (!issclt(lt))
- lerror("mkinit() 1");
-
- if (!typeok(INIT, NULL, ln, tn))
- goto end;
-
- /*
- * Store the tree memory. This is necessary because otherwise
- * expr() would free it.
- */
- tmem = tsave();
- expr(tn, 1, 0);
- trestor(tmem);
-
- if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
- tn = convert(INIT, NULL, initstk->i_type, tn);
-
- if (tn != NULL && tn->tn_op != CON) {
- sym = NULL;
- offs = 0;
- if (conaddr(tn, &sym, &offs) == -1) {
- if (sc == AUTO || sc == REG) {
- /* non-constant initializer */
- (void)gnuism(177);
- } else {
- /* non-constant initializer */
- error(177);
- }
- }
- }
-
- end:
- tfreeblk();
-}
-
-
-static int
-strginit(tnode_t *tn)
-{
- tspec_t t;
- istk_t *istk;
- int len;
- strg_t *strg;
-
- if (tn->tn_op != STRING)
- return (0);
-
- istk = initstk;
- strg = tn->tn_strg;
-
- /*
- * Check if we have an array type which can be initialized by
- * the string.
- */
- if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
- t = istk->i_subt->t_subt->t_tspec;
- if (!((strg->st_tspec == CHAR &&
- (t == CHAR || t == UCHAR || t == SCHAR)) ||
- (strg->st_tspec == WCHAR && t == WCHAR))) {
- return (0);
- }
- /* Put the array at top of stack */
- pushinit();
- istk = initstk;
- } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
- t = istk->i_type->t_subt->t_tspec;
- if (!((strg->st_tspec == CHAR &&
- (t == CHAR || t == UCHAR || t == SCHAR)) ||
- (strg->st_tspec == WCHAR && t == WCHAR))) {
- return (0);
- }
- /*
- * If the array is already partly initialized, we are
- * wrong here.
- */
- if (istk->i_cnt != istk->i_type->t_dim)
- return (0);
- } else {
- return (0);
- }
-
- /* Get length without trailing NUL character. */
- len = strg->st_len;
-
- if (istk->i_nolimit) {
- istk->i_nolimit = 0;
- istk->i_type->t_dim = len + 1;
- /* from now complete type */
- setcompl(istk->i_type, 0);
- } else {
- if (istk->i_type->t_dim < len) {
- /* non-null byte ignored in string initializer */
- warning(187);
- }
- }
-
- /* In every case the array is initialized completely. */
- istk->i_cnt = 0;
-
- return (1);
-}
diff --git a/usr.bin/xlint/lint1/lint.h b/usr.bin/xlint/lint1/lint.h
deleted file mode 100644
index 570832e04e5..00000000000
--- a/usr.bin/xlint/lint1/lint.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* $OpenBSD: lint.h,v 1.7 2010/07/24 22:17:03 guenther Exp $ */
-/* $NetBSD: lint.h,v 1.2 1995/07/03 21:24:18 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stddef.h>
-
-#include "param.h"
-
-/*
- * Type specifiers, used in type structures (type_t) and elsewhere.
- */
-typedef enum {
- NOTSPEC,
- SIGNED, /* keyword "signed", only used in the parser */
- UNSIGN, /* keyword "unsigned", only used in the parser */
- BOOL, /* _Bool */
- CHAR, /* char */
- SCHAR, /* signed char */
- UCHAR, /* unsigned char */
- SHORT, /* (signed) short */
- USHORT, /* unsigned short */
- INT, /* (signed) int */
- UINT, /* unsigned int */
- LONG, /* (signed) long */
- ULONG, /* unsigned long */
- QUAD, /* (signed) long long */
- UQUAD, /* unsigned long long */
- FLOAT, /* float */
- DOUBLE, /* double */
- LDOUBLE, /* long double */
- COMPLEX, /* float _Complex */
- DCOMPLEX, /* double _Complex */
- LDCOMPLEX, /* long double _Complex */
- IMAGINARY, /* float _Imaginary */
- DIMAGINARY, /* double _Imaginary */
- LDIMAGINARY, /* long double _Imaginary */
- VOID, /* void */
- STRUCT, /* structure tag */
- UNION, /* union tag */
- ENUM, /* enum tag */
- PTR, /* pointer */
- ARRAY, /* array */
- FUNC /* function */
-#define NTSPEC ((int)FUNC + 1)
-} tspec_t;
-
-/*
- * size of types, name and classification
- */
-typedef struct {
- int tt_sz; /* size in bits */
- int tt_psz; /* size, different from tt_sz
- if pflag is set */
- int tt_rank; /* rank (C99), similar to tt_psz */
- tspec_t tt_styp; /* signed counterpart */
- tspec_t tt_utyp; /* unsigned counterpart */
- u_int tt_isityp : 1; /* 1 if integer type */
- u_int tt_isutyp : 1; /* 1 if unsigned integer type */
- u_int tt_isftyp : 1; /* 1 if floating point type */
- u_int tt_isatyp : 1; /* 1 if arithmetic type */
- u_int tt_domain : 2; /* 0 if non-scalar, 1 if real,
- 2 if imaginary, 3 if complex */
- char *tt_name; /* type name */
-} ttab_t;
-
-#define size(t) (ttab[t].tt_sz)
-#define psize(t) (ttab[t].tt_psz)
-#define rank(t) (ttab[t].tt_rank)
-#define styp(t) (ttab[t].tt_styp)
-#define utyp(t) (ttab[t].tt_utyp)
-#define isityp(t) (ttab[t].tt_isityp)
-#define isutyp(t) (ttab[t].tt_isutyp)
-#define isftyp(t) (ttab[t].tt_isftyp)
-#define isatyp(t) (ttab[t].tt_isatyp)
-#define issclt(t) (ttab[t].tt_domain != 0)
-#define iscomplex(t) (ttab[t].tt_domain == 3)
-#define isimag(t) (ttab[t].tt_domain == 2)
-
-extern ttab_t ttab[];
-
-
-typedef enum {
- NODECL, /* until now not declared */
- DECL, /* declared */
- TDEF, /* tentative defined */
- DEF /* defined */
-} def_t;
-
-/*
- * Following structure contains some data used for the output buffer.
- */
-typedef struct ob {
- char *o_buf; /* buffer */
- char *o_end; /* first byte after buffer */
- size_t o_len; /* length of buffer */
- char *o_nxt; /* next free byte in buffer */
-} ob_t;
-
-#include "externs.h"
diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h
deleted file mode 100644
index 780b0913412..00000000000
--- a/usr.bin/xlint/lint1/lint1.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/* $OpenBSD: lint1.h,v 1.15 2011/05/30 15:15:58 martynas Exp $ */
-/* $NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "lint.h"
-#include "op.h"
-
-/*
- * Describes the position of a declaration or anything else.
- */
-typedef struct {
- int p_line;
- const char *p_file;
-} pos_t;
-
-/*
- * Strings cannot be referenced to simply by a pointer to its first
- * char. This is because strings can contain NUL characters other than the
- * trailing NUL.
- *
- * Strings are stored with a trailing NUL.
- */
-typedef struct strg {
- tspec_t st_tspec; /* CHAR or WCHAR */
- size_t st_len; /* length without trailing NUL */
- union {
- u_char *_st_cp;
- wchar_t *_st_wcp;
- } st_u;
-} strg_t;
-
-#define st_cp st_u._st_cp
-#define st_wcp st_u._st_wcp
-
-/*
- * qualifiers (only for lex/yacc interface)
- */
-typedef enum {
- CONST, VOLATILE, RESTRICT
-} tqual_t;
-
-/*
- * Integer and floating point values are stored in this structure
- */
-typedef struct {
- tspec_t v_tspec;
- int v_ansiu; /* set if an integer constant is
- unsigned in ANSI C */
- tspec_t v_lspec; /* the underlying type of a literal */
- union {
- quad_t _v_quad; /* integers */
- ldbl_t _v_ldbl; /* floats */
- } v_u;
-} val_t;
-
-#define v_quad v_u._v_quad
-#define v_ldbl v_u._v_ldbl
-
-/*
- * Structures of type str_t uniqely identify structures. This can't
- * be done in structures of type type_t, because these are copied
- * if they must be modified. So it would not be possible to check
- * if two structures are identical by comparing the pointers to
- * the type structures.
- *
- * The typename is used if the structure is unnamed to identify
- * the structure type in pass 2.
- */
-typedef struct {
- u_int size; /* size in bit */
- u_int align : 15; /* alignment in bit */
- u_int sincompl : 1; /* set if incomplete type */
- struct sym *memb; /* list of members */
- struct sym *stag; /* symbol table entry of tag */
- struct sym *stdef; /* symbol table entry of first typename */
-} str_t;
-
-/*
- * same as above for enums
- */
-typedef struct {
- u_int eincompl : 1; /* incomplete enum type */
- struct sym *elem; /* list of enumerators */
- struct sym *etag; /* symbol table entry of tag */
- struct sym *etdef; /* symbol table entry of first typename */
-} enum_t;
-
-/*
- * Types are represented by concatenation of structures of type type_t
- * via t_subt.
- */
-typedef struct type {
- tspec_t t_tspec; /* type specifier */
- u_int t_aincompl : 1; /* incomplete array type */
- u_int t_const : 1; /* const modifier */
- u_int t_volatile : 1; /* volatile modifier */
- u_int t_restrict : 1; /* restrict modifier */
- u_int t_proto : 1; /* function prototype (t_args valid) */
- u_int t_vararg : 1; /* protoype with ... */
- u_int t_typedef : 1; /* type defined with typedef */
- u_int t_isfield : 1; /* type is bitfield */
- u_int t_isenum : 1; /* type is (or was) enum (t_enum valid) */
- union {
- int _t_dim; /* dimension */
- str_t *_t_str; /* struct/union tag */
- enum_t *_t_enum; /* enum tag */
- struct sym *_t_args; /* arguments (if t_proto) */
- struct {
- u_int _t_flen : 8; /* length of bit-field */
- u_int _t_foffs : 24; /* offset of bit-field */
- } _t_u;
- } t_u;
- struct type *t_subt; /* element type (arrays), return value
- (functions), or type pointer points to */
-} type_t;
-
-#define t_dim t_u._t_dim
-#define t_str t_u._t_str
-#define t_field t_u._t_field
-#define t_enum t_u._t_enum
-#define t_args t_u._t_args
-#define t_flen t_u._t_u._t_flen
-#define t_foffs t_u._t_u._t_foffs
-
-/*
- * types of symbols
- */
-typedef enum {
- FVFT, /* variables, functions, type names, enums */
- FMOS, /* members of structs or unions */
- FTAG, /* tags */
- FLAB /* labels */
-} symt_t;
-
-/*
- * storage classes
- */
-typedef enum {
- NOSCL,
- EXTERN, /* external symbols (indep. of decl_t) */
- STATIC, /* static symbols (local and global) */
- AUTO, /* automatic symbols (except register) */
- REG, /* register */
- TYPEDEF, /* typedef */
- STRTAG,
- UNIONTAG,
- ENUMTAG,
- MOS, /* member of struct */
- MOU, /* member of union */
- ENUMCON, /* enumerator */
- ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */
- ARG, /* argument */
- PARG, /* used in declaration stack during prototype
- declaration */
- INLINE /* only used by the parser */
-} scl_t;
-
-/*
- * symbol table entry
- */
-typedef struct sym {
- const char *s_name; /* name */
- pos_t s_dpos; /* position of last (prototype)definition,
- prototypedeclaration, no-prototype-def.,
- tentative definition or declaration,
- in this order */
- pos_t s_spos; /* position of first initialisation */
- pos_t s_upos; /* position of first use */
- symt_t s_kind; /* type of symbol */
- u_int s_keyw : 1; /* keyword */
- u_int s_field : 1; /* bit-field */
- u_int s_set : 1; /* variable set, label defined */
- u_int s_used : 1; /* variable/label used */
- u_int s_arg : 1; /* symbol is function argument */
- u_int s_reg : 1; /* symbol is register variable */
- u_int s_defarg : 1; /* undefined symbol in old style function
- definition */
- u_int s_rimpl : 1; /* return value of function implicit decl. */
- u_int s_osdef : 1; /* symbol stems from old style function def. */
- u_int s_inline : 1; /* true if this is a inline function */
- u_int s_noreturn : 1; /* true if this is a NORETURN function */
- struct sym *s_xsym; /* for local declared external symbols pointer
- to external symbol with same name */
- def_t s_def; /* declared, tentative defined, defined */
- scl_t s_scl; /* storage class */
- int s_blklev; /* level of declaration, -1 if not in symbol
- table */
- type_t *s_type; /* type */
- val_t s_value; /* value (if enumcon) */
- union {
- str_t *_s_st; /* tag, if it is a struct/union member */
- enum_t *_s_et; /* tag, if it is a enumerator */
- tspec_t _s_tsp; /* type (only for keywords) */
- tqual_t _s_tqu; /* qualifier (only for keywords) */
- struct sym *_s_args; /* arguments in old style function
- definitions */
- op_t _s_op; /* op type (only for operators) */
- } u;
- struct sym *s_link; /* next symbol with same hash value */
- struct sym **s_rlink; /* pointer to s_link of prev. symbol */
- struct sym *s_nxt; /* next struct/union member, enumerator,
- argument */
- struct sym *s_dlnxt; /* next symbol declared on same level */
-} sym_t;
-
-#define s_styp u._s_st
-#define s_etyp u._s_et
-#define s_tspec u._s_tsp
-#define s_tqual u._s_tqu
-#define s_op u._s_op
-#define s_args u._s_args
-
-/*
- * Used to keep some informations about symbols before they are entered
- * into the symbol table.
- */
-typedef struct sbuf {
- const char *sb_name; /* name of symbol */
- size_t sb_len; /* length (without '\0') */
- int sb_hash; /* hash value */
- sym_t *sb_sym; /* symbol table entry */
- struct sbuf *sb_nxt; /* for freelist */
-} sbuf_t;
-
-
-/*
- * tree node
- */
-typedef struct tnode {
- op_t tn_op; /* operator */
- type_t *tn_type; /* type */
- u_int tn_lvalue : 1; /* node is lvalue */
- u_int tn_cast : 1; /* if tn_op == CVT its an explicit cast */
- u_int tn_parn : 1; /* node parenthesized */
- union {
- struct {
- struct tnode *_tn_left; /* (left) operand */
- struct tnode *_tn_right; /* right operand */
- } tn_s;
- sym_t *_tn_sym; /* symbol if op == NAME */
- val_t *_tn_val; /* value if op == CON */
- strg_t *_tn_strg; /* string if op == STRING */
- } tn_u;
-} tnode_t;
-
-#define tn_left tn_u.tn_s._tn_left
-#define tn_right tn_u.tn_s._tn_right
-#define tn_sym tn_u._tn_sym
-#define tn_val tn_u._tn_val
-#define tn_strg tn_u._tn_strg
-
-/*
- * For nested declarations a stack exists, which holds all information
- * needed for the current level. dcs points to the top element of this
- * stack.
- *
- * ctx describes the context of the current declaration. Its value is
- * one of
- * EXTERN global declarations
- * MOS oder MOU declarations of struct or union members
- * ENUMCON declarations of enums
- * ARG declaration of arguments in old style function definitions
- * PARG declaration of arguments in function prototypes
- * AUTO declaration of local symbols
- * ABSTRACT abstract declarations (sizeof, casts)
- *
- */
-typedef struct dinfo {
- tspec_t d_atyp; /* NOTSPEC, VOID, CHAR, INT, FLOAT or DOUBLE */
- tspec_t d_smod; /* sign: NOTSPEC, SIGNED or UNSIGN */
- tspec_t d_lmod; /* length: NOTSPEC, SHORT, LONG or QUAD */
- tspec_t d_dmod; /* domain: NOTSPEC, COMPLEX or IMAGINARY */
- scl_t d_scl; /* storage class */
- type_t *d_type; /* after deftyp() pointer to the type used
- for all declarators */
- sym_t *d_rdcsym; /* redeclared symbol */
- int d_offset; /* offset of next structure member */
- int d_stralign; /* alignment required for current structure */
- scl_t d_ctx; /* context of declaration */
- u_int d_const : 1; /* const in declaration specifiers */
- u_int d_volatile : 1; /* volatile in declaration specifiers */
- u_int d_restrict : 1; /* restrict in declaration specifiers */
- u_int d_inline : 1; /* inline in declaration specifiers */
- u_int d_mscl : 1; /* multiple storage classes */
- u_int d_terr : 1; /* invalid type combination */
- u_int d_nedecl : 1; /* 1 if at least a tag is declared */
- u_int d_vararg : 1; /* ... in current function decl. */
- u_int d_proto : 1; /* current funct. decl. is prototype */
- u_int d_notyp : 1; /* set if no type specifier was present */
- u_int d_asm : 1; /* set if d_ctx == AUTO and asm() present */
- type_t *d_tagtyp; /* tag during member declaration */
- sym_t *d_fargs; /* list of arguments during function def. */
- pos_t d_fdpos; /* position of function definition */
- sym_t *d_dlsyms; /* first symbol declared at this level */
- sym_t **d_ldlsym; /* points to s_dlnxt in last symbol decl.
- at this level */
- sym_t *d_fpsyms; /* symbols defined in prototype */
- struct dinfo *d_nxt; /* next level */
-} dinfo_t;
-
-/*
- * Type of stack which is used for initialisation of aggregate types.
- */
-typedef struct istk {
- type_t *i_type; /* type of initialisation */
- type_t *i_subt; /* type of next level */
- u_int i_brace : 1; /* need } for pop */
- u_int i_nolimit : 1; /* incomplete array type */
- sym_t *i_mem; /* next structure member */
- int i_cnt; /* # of remaining elements */
- struct istk *i_nxt; /* previous level */
-} istk_t;
-
-/*
- * Used to collect information about pointers and qualifiers in
- * declarators.
- */
-typedef struct pqinf {
- int p_pcnt; /* number of asterisks */
- u_int p_const : 1;
- u_int p_volatile : 1;
- u_int p_restrict : 1;
- struct pqinf *p_nxt;
-} pqinf_t;
-
-/*
- * Case values are stored in a list of type clst_t.
- */
-typedef struct clst {
- val_t cl_val;
- struct clst *cl_nxt;
-} clst_t;
-
-/*
- * Used to keep informations about nested control statements.
- */
-typedef struct cstk {
- int c_env; /* type of statement (T_IF, ...) */
- u_int c_loop : 1; /* continue && break are valid */
- u_int c_switch : 1; /* case && break are valid */
- u_int c_break : 1; /* loop/switch has break */
- u_int c_cont : 1; /* loop has continue */
- u_int c_default : 1; /* switch has default */
- u_int c_infinite : 1; /* break condition always false
- (for (;;), while (1)) */
- u_int c_rchif : 1; /* end of if-branch reached */
- u_int c_noretval : 1; /* had "return;" */
- u_int c_retval : 1; /* had "return (e);" */
- type_t *c_swtype; /* type of switch expression */
- clst_t *c_clst; /* list of case values */
- struct mbl *c_fexprm; /* saved memory for end of loop
- expression in for() */
- tnode_t *c_f3expr; /* end of loop expr in for() */
- pos_t c_fpos; /* position of end of loop expr */
- pos_t c_cfpos; /* same for csrc_pos */
- struct cstk *c_nxt; /* outer control statement */
-} cstk_t;
-
-/*
- * Used to keep information about arguments passed to functions with
- * prototypes.
- */
-typedef struct farg {
- int fa_num; /* argument number (1-basde) */
- sym_t *fa_sym; /* argument symbol */
- tnode_t *fa_func; /* function name */
-} farg_t;
-
-#include "externs1.h"
diff --git a/usr.bin/xlint/lint1/main1.c b/usr.bin/xlint/lint1/main1.c
deleted file mode 100644
index 99916e5f47b..00000000000
--- a/usr.bin/xlint/lint1/main1.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* $OpenBSD: main1.c,v 1.12 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: main1.c,v 1.3 1995/10/02 17:29:56 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <err.h>
-
-#include "lint1.h"
-
-/* set yydebug to 1*/
-int yflag;
-
-/* Print warnings for pointer casts. */
-int cflag;
-
-/* Print various debug information. */
-int dflag;
-
-/* Perform stricter checking of enum types and operations on enum types. */
-int eflag;
-
-/* Print complete pathnames, not only the basename. */
-int Fflag = 1;
-
-/* After an error or warning, print the actual text of the program source code */
-int fflag = 0;
-
-/* Enable some extensions of gcc */
-int gflag;
-
-/*
- * Apply a number of heuristic tests to attempt to intuit bugs, improve
- * style, and reduce waste.
- */
-int hflag;
-
-/* Attempt to check portability to other dialects of C. */
-int pflag;
-
-/*
- * In case of redeclarations/redefinitions print the location of the
- * previous declaration/definition.
- */
-int rflag;
-
-/* Strict ANSI C mode. */
-int sflag;
-
-/*
- * Complain about functions and external variables used and not defined,
- * or defined and not used.
- */
-int uflag = 1;
-
-/* Complain about unused function arguments. */
-int vflag = 1;
-
-/* Complain about structures which are never defined. */
-int zflag = 0;
-
-static void usage(void);
-
-int
-main(int argc, char *argv[])
-{
- int c;
-
- while ((c = getopt(argc, argv, "abcdefghprstuvyzF")) != -1) {
- switch (c) {
- case 'a': /* obsolete */ break;
- case 'b': /* obsolete */ break;
- case 'c': cflag = 1; break;
- case 'd': dflag = 1; break;
- case 'e': eflag = 1; break;
- case 'F': Fflag = 1; break;
- case 'g': gflag = 1; break;
- case 'h': hflag = 1; break;
- case 'f': fflag = 1; break;
- case 'p': pflag = 1; break;
- case 'r': rflag = 1; break;
- case 's': sflag = 1; break;
- case 't': /* obsolete */ break;
- case 'u': uflag = 0; break;
- case 'v': vflag = 0; break;
- case 'y': yflag = 1; break;
- case 'z': zflag = 0; break;
- case '?': usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 2)
- usage();
-
- /* open the input file */
- if ((yyin = fopen(argv[0], "r")) == NULL)
- err(1, "cannot open '%s'", argv[0]);
-
- /* initialize output */
- outopen(argv[1]);
-
-#if YYDEBUG
- if (yflag)
- yydebug = 1;
-#endif
-
- initmem();
- initdecl();
- initscan();
- initmtab();
-
- yyparse();
-
- /* Following warnings cannot be suppressed by LINTED */
- nowarn = 0;
-
- chkglsyms();
-
- outclose();
-
- return (nerr != 0);
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr, "usage: lint1 [-abcdeghprstuvyzF] src dest\n");
- exit(1);
-}
-
-void
-norecover(void)
-{
- /* cannot recover from previous errors */
- error(224);
- exit(1);
-}
diff --git a/usr.bin/xlint/lint1/mem.c b/usr.bin/xlint/lint1/mem.c
deleted file mode 100644
index e2f605188cb..00000000000
--- a/usr.bin/xlint/lint1/mem.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $OpenBSD: mem.c,v 1.5 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: mem.c,v 1.2 1995/07/03 21:24:24 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <err.h>
-
-#include "lint.h"
-
-void *
-xmalloc(size_t s)
-{
- void *p;
-
- if ((p = malloc(s)) == NULL)
- err(1, NULL);
- return (p);
-}
-
-void *
-xcalloc(size_t n, size_t s)
-{
- void *p;
-
- if ((p = calloc(n, s)) == NULL)
- err(1, NULL);
- return (p);
-}
-
-void *
-xrealloc(void *p, size_t s)
-{
- if ((p = realloc(p, s)) == NULL)
- err(1, NULL);
- return (p);
-}
-
-char *
-xstrdup(const char *s)
-{
- char *s2;
-
- if ((s2 = strdup(s)) == NULL)
- err(1, NULL);
- return (s2);
-}
diff --git a/usr.bin/xlint/lint1/mem1.c b/usr.bin/xlint/lint1/mem1.c
deleted file mode 100644
index 19976272f62..00000000000
--- a/usr.bin/xlint/lint1/mem1.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* $OpenBSD: mem1.c,v 1.12 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: mem1.c,v 1.2 1995/07/03 21:24:25 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-
-#include "lint1.h"
-
-/*
- * Filenames allocated by fnalloc() and fnnalloc() are shared.
- */
-typedef struct fn {
- char *fn_name;
- size_t fn_len;
- int fn_id;
- struct fn *fn_nxt;
-} fn_t;
-
-static fn_t *fnames;
-
-static fn_t *srchfn(const char *, size_t);
-
-/*
- * Look for a Filename of length l.
- */
-static fn_t *
-srchfn(const char *s, size_t len)
-{
- fn_t *fn;
-
- for (fn = fnames; fn != NULL; fn = fn->fn_nxt) {
- if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0)
- break;
- }
- return (fn);
-}
-
-/*
- * Return a shared string for filename s.
- */
-const char *
-fnalloc(const char *s)
-{
- return (s != NULL ? fnnalloc(s, strlen(s)) : NULL);
-}
-
-const char *
-fnnalloc(const char *s, size_t len)
-{
- fn_t *fn;
-
- static int nxt_id = 0;
-
- if (s == NULL)
- return (NULL);
-
- if ((fn = srchfn(s, len)) == NULL) {
- fn = xmalloc(sizeof (fn_t));
- /* Do not used strdup() because string is not NUL-terminated.*/
- fn->fn_name = xmalloc(len + 1);
- (void)memcpy(fn->fn_name, s, len);
- fn->fn_name[len] = '\0';
- fn->fn_len = len;
- fn->fn_id = nxt_id++;
- fn->fn_nxt = fnames;
- fnames = fn;
- /* Write id of this filename to the output file. */
- outclr();
- outint(fn->fn_id);
- outchar('s');
- outstrg(fn->fn_name);
- }
- return (fn->fn_name);
-}
-
-/*
- * Get id of a filename.
- */
-int
-getfnid(const char *s)
-{
- fn_t *fn;
-
- if (s == NULL || (fn = srchfn(s, strlen(s))) == NULL)
- return (-1);
- return (fn->fn_id);
-}
-
-/*
- * Memory for declarations and other things which must be available
- * until the end of a block (or the end of the translation unit)
- * are associated with the level (mblklev) of the block (or with 0).
- * Because this memory is allocated in large blocks associated with
- * a given level it can be freed easily at the end of a block.
- */
-#define ML_INC ((size_t)32) /* Increment for length of *mblks */
-
-typedef struct mbl {
- void *blk; /* beginning of memory block */
- void *ffree; /* first free byte */
- size_t nfree; /* # of free bytes */
- size_t size; /* total size of memory block */
- struct mbl *nxt; /* next block */
-} mbl_t;
-
-/*
- * Array of pointers to lists of memory blocks. mblklev is used as
- * index into this array.
- */
-static mbl_t **mblks;
-
-/* number of elements in *mblks */
-static size_t nmblks;
-
-/* free list for memory blocks */
-static mbl_t *frmblks;
-
-/* length of new allocated memory blocks */
-static size_t mblklen;
-
-static void *xgetblk(mbl_t **, size_t);
-static void xfreeblk(mbl_t **);
-static mbl_t *xnewblk(void);
-
-static mbl_t *
-xnewblk(void)
-{
- mbl_t *mb;
-
- mb = xmalloc(sizeof (mbl_t));
- mb->blk = xmalloc(mblklen);
- mb->size = mblklen;
- return (mb);
-}
-
-/*
- * Allocate new memory. If the first block of the list has not enough
- * free space, or there is no first block, get a new block. The new
- * block is taken from the free list or, if there is no block on the
- * free list, is allocated using xnewblk(). If a new block is allocated
- * it is initialized with zero. Blocks taken from the free list are
- * zero'd in xfreeblk().
- */
-static void *
-xgetblk(mbl_t **mbp, size_t s)
-{
- mbl_t *mb;
- void *p;
-
- s = ALIGN(s);
- if ((mb = *mbp) == NULL || mb->nfree < s) {
- if ((mb = frmblks) == NULL) {
- mb = xnewblk();
- (void)memset(mb->blk, 0, mb->size);
- } else {
- frmblks = mb->nxt;
- }
- mb->ffree = mb->blk;
- mb->nfree = mb->size;
- mb->nxt = *mbp;
- *mbp = mb;
- }
- p = mb->ffree;
- mb->ffree = (char *)mb->ffree + s;
- mb->nfree -= s;
- return (p);
-}
-
-/*
- * Move all blocks from list *fmbp to free list. For each block, set all
- * used memory to zero.
- */
-static void
-xfreeblk(mbl_t **fmbp)
-{
- mbl_t *mb;
-
- while ((mb = *fmbp) != NULL) {
- *fmbp = mb->nxt;
- mb->nxt = frmblks;
- frmblks = mb;
- (void)memset(mb->blk, 0, mb->size - mb->nfree);
- }
-}
-
-void
-initmem(void)
-{
- int pgsz;
-
- pgsz = getpagesize();
- mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz;
-
- mblks = xcalloc(nmblks = ML_INC, sizeof (mbl_t *));
-}
-
-
-/*
- * Allocate memory associated with level l.
- */
-void *
-getlblk(int l, size_t s)
-{
- while (l >= nmblks) {
- mblks = xrealloc(mblks, (nmblks + ML_INC) * sizeof (mbl_t *));
- (void)memset(&mblks[nmblks], 0, ML_INC * sizeof (mbl_t *));
- nmblks += ML_INC;
- }
- return (xgetblk(&mblks[l], s));
-}
-
-void *
-getblk(size_t s)
-{
- return (getlblk(mblklev, s));
-}
-
-/*
- * Free all memory associated with level l.
- */
-void
-freelblk(int l)
-{
- xfreeblk(&mblks[l]);
-}
-
-void
-freeblk(void)
-{
- freelblk(mblklev);
-}
-
-/*
- * tgetblk() returns memory which is associated with the current
- * expression.
- */
-static mbl_t *tmblk;
-
-void *
-tgetblk(size_t s)
-{
- return (xgetblk(&tmblk, s));
-}
-
-/*
- * Get memory for a new tree node.
- */
-tnode_t *
-getnode(void)
-{
- return (tgetblk(sizeof (tnode_t)));
-}
-
-/*
- * Free all memory which is allocated by the current expression.
- */
-void
-tfreeblk(void)
-{
- xfreeblk(&tmblk);
-}
-
-/*
- * Save the memory which is used by the current expression. This memory
- * is not freed by the next tfreeblk() call. The pointer returned can be
- * used to restore the memory.
- */
-mbl_t *
-tsave(void)
-{
- mbl_t *tmem;
-
- tmem = tmblk;
- tmblk = NULL;
- return (tmem);
-}
-
-/*
- * Free all memory used for the current expression and the memory used
- * be a previous expression and saved by tsave(). The next call to
- * tfreeblk() frees the restored memory.
- */
-void
-trestor(mbl_t *tmem)
-{
- tfreeblk();
- if (tmblk != NULL) {
- free(tmblk->blk);
- free(tmblk);
- }
- tmblk = tmem;
-}
diff --git a/usr.bin/xlint/lint1/op.h b/usr.bin/xlint/lint1/op.h
deleted file mode 100644
index 2198822f8aa..00000000000
--- a/usr.bin/xlint/lint1/op.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $OpenBSD: op.h,v 1.4 2010/07/24 22:17:03 guenther Exp $ */
-/* $NetBSD: op.h,v 1.2 1995/07/03 21:24:27 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Various information about operators
- */
-typedef struct {
- u_int m_binary : 1; /* binary op. */
- u_int m_logop : 1; /* logical op., result is int */
- u_int m_rqint : 1; /* operands must have integer type */
- u_int m_rqsclt : 1; /* operands must have scalar type */
- u_int m_rqatyp : 1; /* operands must have arithmetic type */
- u_int m_fold : 1; /* operands should be folded */
- u_int m_vctx : 1; /* value context for left operand */
- u_int m_tctx : 1; /* test context for left operand */
- u_int m_balance : 1; /* op. requires balancing */
- u_int m_sideeff : 1; /* op. has side effect */
- u_int m_tlansiu : 1; /* warning if left op. is unsign. in ANSI C */
- u_int m_transiu : 1; /* warning if right op. is unsign. in ANSI C */
- u_int m_tpconf : 1; /* test possible precedence confusion */
- u_int m_comp : 1; /* op. performs comparison */
- u_int m_enumop : 1; /* valid operation on enums */
- u_int m_badeop : 1; /* dubious operation on enums */
- u_int m_eqwarn : 1; /* warning if on operand stems from == */
- const char *m_name; /* name of op. */
-} mod_t;
-
-typedef enum {
- NOOP = 0,
- ARROW,
- POINT,
- NOT,
- COMPL,
- INC,
- DEC,
- INCBEF,
- DECBEF,
- INCAFT,
- DECAFT,
- UPLUS,
- UMINUS,
- STAR,
- AMPER,
- MULT,
- DIV,
- MOD,
- PLUS,
- MINUS,
- SHL,
- SHR,
- LT,
- LE,
- GT,
- GE,
- EQ,
- NE,
- AND,
- XOR,
- OR,
- LOGAND,
- LOGOR,
- QUEST,
- COLON,
- ASSIGN,
- MULASS,
- DIVASS,
- MODASS,
- ADDASS,
- SUBASS,
- SHLASS,
- SHRASS,
- ANDASS,
- XORASS,
- ORASS,
- NAME,
- CON,
- STRING,
- FSEL,
- CALL,
- COMMA,
- CVT,
- ICALL,
- LOAD,
- PUSH,
- RETURN,
- REAL, /* gcc extension: __real__ */
- IMAG, /* gcc extension: __imag__ */
- INIT, /* pseudo op, not used in trees */
- CASE, /* pseudo op, not used in trees */
- FARG /* pseudo op, not used in trees */
-#define NOPS ((int)FARG + 1)
-} op_t;
diff --git a/usr.bin/xlint/lint1/param.h b/usr.bin/xlint/lint1/param.h
deleted file mode 100644
index f8f86fc132a..00000000000
--- a/usr.bin/xlint/lint1/param.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* $OpenBSD: param.h,v 1.15 2007/10/11 07:30:07 otto Exp $ */
-/* $NetBSD: param.h,v 1.6 1996/04/01 21:47:57 mark Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Minimun size of string buffer. If this is not enough, the buffer
- * is enlarged in steps of STRBLEN bytes.
- */
-#define STRBLEN 256
-
-/*
- * This defines the size of memory blocks which are used to allocate
- * memory in larger chunks.
- */
-#define MBLKSIZ ((size_t)0x4000)
-
-/*
- * Sizes of hash tables
- * Should be a prime. Possible primes are
- * 307, 401, 503, 601, 701, 809, 907, 1009, 1103, 1201, 1301, 1409, 1511.
- *
- * HSHSIZ1 symbol table 1st pass
- * HSHSIZ2 symbol table 2nd pass
- * THSHSIZ2 type table 2nd pass
- */
-#define HSHSIZ1 503
-#define HSHSIZ2 1009
-#define THSHSIZ2 1009
-
-/*
- * Should be set to 1 if the difference of two pointers is of type long
- * or the value of sizeof is of type unsigned long.
- */
-#define PTRDIFF_IS_LONG 1
-#define SIZEOF_IS_ULONG 1
-
-/*
- * Make sure this matches wchar_t.
- */
-#define WCHAR INT
-
-#if !defined(__GNUC__) && !defined(__PCC__)
-#ifndef lint
-#ifndef QUAD_MAX /* necessary for mkdep */
-#define QUAD_MAX LONG_MAX
-#define QUAD_MIN LONG_MIN
-#define UQUAD_MAX ULONG_MAX
-#endif
-typedef long quad_t;
-typedef u_long u_quad_t;
-#endif
-#endif
-typedef long double ldbl_t;
-
-/*
- * Modern compilers are able to assign structures.
- */
-#define STRUCT_ASSIGN(dest, src) (dest) = (src)
diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l
deleted file mode 100644
index 7f9464ffd00..00000000000
--- a/usr.bin/xlint/lint1/scan.l
+++ /dev/null
@@ -1,1484 +0,0 @@
-%{
-/* $OpenBSD: scan.l,v 1.33 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: scan.l,v 1.8 1995/10/23 13:38:51 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <float.h>
-#include <ctype.h>
-#include <errno.h>
-#include <math.h>
-#include <err.h>
-
-#include "lint1.h"
-#include "y.tab.h"
-
-#define CHAR_MASK (~(~0 << CHAR_BIT))
-
-/* Current position (its also updated when an included file is parsed) */
-pos_t curr_pos = { 1, "" };
-
-/*
- * Current position in C source (not updated when an included file is
- * parsed).
- */
-pos_t csrc_pos = { 1, "" };
-
-static void incline(void);
-static void badchar(int);
-static sbuf_t *allocsb(void);
-static void freesb(sbuf_t *);
-static int inpc(void);
-static int hash(const char *);
-static sym_t *search(sbuf_t *);
-static int name(void);
-static int keyw(sym_t *);
-static int icon(int);
-static int fcon(void);
-static int fhexcon(void);
-static int operator(int, op_t);
-static int ccon(void);
-static int wccon(void);
-static int getescc(int);
-static void directive(void);
-static void comment(void);
-static void slashslashcomment(void);
-static int string(void);
-static int wcstrg(void);
-
-%}
-
-L [_A-Za-z]
-D [0-9]
-NZD [1-9]
-OD [0-7]
-HD [0-9A-Fa-f]
-EX ([eE][+-]?[0-9]+)
-HEX ([pP][+-]?[0-9]+)
-FSUFF ([fFlL][iIjJ]?|[iIjJ][fFlL]?)?
-
-%%
-
-{L}({L}|{D})* return (name());
-0{OD}*[lLuU]* return (icon(8));
-{NZD}{D}*[lLuU]* return (icon(10));
-0[xX]{HD}+[lLuU]* return (icon(16));
-{D}+\.{D}*{EX}?{FSUFF} |
-{D}+{EX}{FSUFF} |
-\.{D}+{EX}?{FSUFF} return (fcon());
-0[xX]{HD}+\.{HD}*{HEX}{FSUFF} |
-0[xX]{HD}+{HEX}{FSUFF} |
-0[xX]\.{HD}+{HEX}{FSUFF} return (fhexcon());
-"=" return (operator(T_ASSIGN, ASSIGN));
-"*=" return (operator(T_OPASS, MULASS));
-"/=" return (operator(T_OPASS, DIVASS));
-"%=" return (operator(T_OPASS, MODASS));
-"+=" return (operator(T_OPASS, ADDASS));
-"-=" return (operator(T_OPASS, SUBASS));
-"<<=" return (operator(T_OPASS, SHLASS));
-">>=" return (operator(T_OPASS, SHRASS));
-"&=" return (operator(T_OPASS, ANDASS));
-"^=" return (operator(T_OPASS, XORASS));
-"|=" return (operator(T_OPASS, ORASS));
-"||" return (operator(T_LOGOR, LOGOR));
-"&&" return (operator(T_LOGAND, LOGAND));
-"|" return (operator(T_OR, OR));
-"&" return (operator(T_AND, AND));
-"^" return (operator(T_XOR, XOR));
-"==" return (operator(T_EQOP, EQ));
-"!=" return (operator(T_EQOP, NE));
-"<" return (operator(T_RELOP, LT));
-">" return (operator(T_RELOP, GT));
-"<=" return (operator(T_RELOP, LE));
-">=" return (operator(T_RELOP, GE));
-"<<" return (operator(T_SHFTOP, SHL));
-">>" return (operator(T_SHFTOP, SHR));
-"++" return (operator(T_INCDEC, INC));
-"--" return (operator(T_INCDEC, DEC));
-"->" return (operator(T_STROP, ARROW));
-"." return (operator(T_STROP, POINT));
-"+" return (operator(T_ADDOP, PLUS));
-"-" return (operator(T_ADDOP, MINUS));
-"*" return (operator(T_MULT, MULT));
-"/" return (operator(T_DIVOP, DIV));
-"%" return (operator(T_DIVOP, MOD));
-"!" return (operator(T_UNOP, NOT));
-"~" return (operator(T_UNOP, COMPL));
-"\"" return (string());
-"L\"" return (wcstrg());
-";" return (T_SEMI);
-"{" return (T_LBRACE);
-"}" return (T_RBRACE);
-"," return (T_COMMA);
-":" return (T_COLON);
-"?" return (T_QUEST);
-"[" return (T_LBRACK);
-"]" return (T_RBRACK);
-"(" return (T_LPARN);
-")" return (T_RPARN);
-"..." return (T_ELLIPSE);
-"'" return (ccon());
-"L'" return (wccon());
-^#.*$ directive();
-\n incline();
-\t|" "|\f|\v ;
-"/*" comment();
-"//" slashslashcomment();
-. badchar(yytext[0]);
-
-%%
-
-static void
-incline(void)
-{
- curr_pos.p_line++;
- if (curr_pos.p_file == csrc_pos.p_file)
- csrc_pos.p_line++;
-}
-
-static void
-badchar(int c)
-{
- /* unknown character \%o */
- error(250, c);
-}
-
-/*
- * Keywords.
- * During initialisation they are written to the symbol table.
- */
-static struct kwtab {
- const char *kw_name; /* keyword */
- int kw_token; /* token returned by yylex() */
- union {
- scl_t kw_scl; /* storage class if kw_token T_SCLASS */
- tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */
- tqual_t kw_tqual; /* type qual. if kw_token T_QUAL */
- op_t kw_op; /* operator if kw_token T_UNOP */
- } kw_u;
- u_int kw_stdc : 1; /* STDC keyword */
- u_int kw_gcc : 1; /* GCC keyword */
-} kwtab[] = {
- { "asm", T_ASM, { 0 }, 0, 1 },
- { "__asm", T_ASM, { 0 }, 0, 0 },
- { "__asm__", T_ASM, { 0 }, 0, 0 },
- { "__attribute__", T_ATTRIBUTE, { 0 }, 0, 0 },
- { "auto", T_SCLASS, { AUTO }, 0, 0 },
- { "_Bool", T_TYPE, { BOOL }, 1, 0 },
- { "break", T_BREAK, { 0 }, 0, 0 },
- { "case", T_CASE, { 0 }, 0, 0 },
- { "char", T_TYPE, { CHAR }, 0, 0 },
- { "_Complex", T_TYPE, { COMPLEX }, 1, 0 },
- { "__complex__", T_TYPE, { COMPLEX }, 0, 1 },
- { "const", T_QUAL, { CONST }, 1, 0 },
- { "__const__", T_QUAL, { CONST }, 0, 0 },
- { "__const", T_QUAL, { CONST }, 0, 0 },
- { "continue", T_CONTINUE, { 0 }, 0, 0 },
- { "default", T_DEFAULT, { 0 }, 0, 0 },
- { "do", T_DO, { 0 }, 0, 0 },
- { "double", T_TYPE, { DOUBLE }, 0, 0 },
- { "else", T_ELSE, { 0 }, 0, 0 },
- { "enum", T_ENUM, { 0 }, 0, 0 },
- { "extern", T_SCLASS, { EXTERN }, 0, 0 },
- { "float", T_TYPE, { FLOAT }, 0, 0 },
- { "for", T_FOR, { 0 }, 0, 0 },
- { "goto", T_GOTO, { 0 }, 0, 0 },
- { "if", T_IF, { 0 }, 0, 0 },
- { "__imag__", T_UNOP, { IMAG }, 0, 0 /*1*/ },
-/* { "_Imaginary", T_TYPE, { IMAGINARY }, 1, 0 }, */
- { "inline", T_SCLASS, { INLINE }, 1, 0 },
- { "__inline__", T_SCLASS, { INLINE }, 0, 0 },
- { "__inline", T_SCLASS, { INLINE }, 0, 0 },
- { "int", T_TYPE, { INT }, 0, 0 },
- { "__lint_equal__", T_LEQUAL, { 0 }, 0, 0 },
- { "long", T_TYPE, { LONG }, 0, 0 },
- { "__real__", T_UNOP, { REAL }, 0, 0 /*1*/ },
- { "register", T_SCLASS, { REG }, 0, 0 },
- { "__restrict", T_QUAL, { RESTRICT }, 0, 0 },
- { "__restrict__", T_QUAL, { RESTRICT }, 0, 0 },
- { "return", T_RETURN, { 0 }, 0, 0 },
- { "short", T_TYPE, { SHORT }, 0, 0 },
- { "signed", T_TYPE, { SIGNED }, 1, 0 },
- { "__signed__", T_TYPE, { SIGNED }, 0, 0 },
- { "__signed", T_TYPE, { SIGNED }, 0, 0 },
- { "sizeof", T_SIZEOF, { 0 }, 0, 0 },
- { "static", T_SCLASS, { STATIC }, 0, 0 },
- { "struct", T_SOU, { STRUCT }, 0, 0 },
- { "switch", T_SWITCH, { 0 }, 0, 0 },
- { "typedef", T_SCLASS, { TYPEDEF }, 0, 0 },
- { "union", T_SOU, { UNION }, 0, 0 },
- { "unsigned", T_TYPE, { UNSIGN }, 0, 0 },
- { "void", T_TYPE, { VOID }, 0, 0 },
- { "volatile", T_QUAL, { VOLATILE }, 1, 0 },
- { "__volatile__", T_QUAL, { VOLATILE }, 0, 0 },
- { "__volatile", T_QUAL, { VOLATILE }, 0, 0 },
- { "while", T_WHILE, { 0 }, 0, 0 },
- { NULL, 0, { 0 }, 0, 0 }
-};
-
-#define kw_scl kw_u.kw_scl
-#define kw_tspec kw_u.kw_tspec
-#define kw_tqual kw_u.kw_tqual
-#define kw_op kw_u.kw_op
-
-/* Symbol table */
-static sym_t *symtab[HSHSIZ1];
-
-/* bit i of the entry with index i is set */
-u_quad_t qbmasks[sizeof(u_quad_t) * CHAR_BIT];
-
-/* least significant i bits are set in the entry with index i */
-u_quad_t qlmasks[sizeof(u_quad_t) * CHAR_BIT + 1];
-
-/* least significant i bits are not set in the entry with index i */
-u_quad_t qumasks[sizeof(u_quad_t) * CHAR_BIT + 1];
-
-/* free list for sbuf structures */
-static sbuf_t *sbfrlst;
-
-/* type of next expected symbol */
-symt_t symtyp;
-
-
-/*
- * All keywords are written to the symbol table. This saves us looking
- * in a extra table for each name we found.
- */
-void
-initscan(void)
-{
- struct kwtab *kw;
- sym_t *sym;
- int h, i;
- u_quad_t uq;
-
- for (kw = kwtab; kw->kw_name != NULL; kw++) {
- if (kw->kw_gcc && !gflag)
- continue;
- sym = getblk(sizeof (sym_t));
- sym->s_name = kw->kw_name;
- sym->s_keyw = 1;
- sym->s_value.v_quad = kw->kw_token;
- if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) {
- sym->s_tspec = kw->kw_tspec;
- } else if (kw->kw_token == T_SCLASS) {
- sym->s_scl = kw->kw_scl;
- } else if (kw->kw_token == T_QUAL) {
- sym->s_tqual = kw->kw_tqual;
- } else if (kw->kw_token == T_UNOP) {
- sym->s_op = kw->kw_op;
- }
- h = hash(sym->s_name);
- if ((sym->s_link = symtab[h]) != NULL)
- symtab[h]->s_rlink = &sym->s_link;
- (symtab[h] = sym)->s_rlink = &symtab[h];
- }
-
- /* initialize bit-masks for quads */
- for (i = 0; i < sizeof (u_quad_t) * CHAR_BIT; i++) {
- qbmasks[i] = (u_quad_t)1 << i;
- uq = ~(u_quad_t)0 << i;
- qumasks[i] = uq;
- qlmasks[i] = ~uq;
- }
- qumasks[i] = 0;
- qlmasks[i] = ~(u_quad_t)0;
-}
-
-/*
- * Get a free sbuf structure, if possible from the free list
- */
-static sbuf_t *
-allocsb(void)
-{
- sbuf_t *sb;
-
- if ((sb = sbfrlst) != NULL) {
- sbfrlst = sb->sb_nxt;
- } else {
- sb = xmalloc(sizeof (sbuf_t));
- }
- (void)memset(sb, 0, sizeof (sbuf_t));
- return (sb);
-}
-
-/*
- * Put a sbuf structure to the free list
- */
-static void
-freesb(sbuf_t *sb)
-{
- sb->sb_nxt = sbfrlst;
- sbfrlst = sb;
-}
-
-/*
- * Read a character and ensure that it is positive (except EOF).
- * Increment line count(s) if necessary.
- */
-static int
-inpc(void)
-{
- int c;
-
- if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n')
- incline();
- return (c);
-}
-
-static int
-hash(const char *s)
-{
- u_int v;
- const u_char *us;
-
- v = 0;
- for (us = (const u_char *)s; *us != '\0'; us++) {
- v = (v << sizeof (v)) + *us;
- v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
- }
- return (v % HSHSIZ1);
-}
-
-/*
- * Lex has found a letter followed by zero or more letters or digits.
- * It looks for a symbol in the symbol table with the same name. This
- * symbol must either be a keyword or a symbol of the type required by
- * symtyp (label, member, tag, ...).
- *
- * If it is a keyword, the token is returned. In some cases it is described
- * more deeply by data written to yylval.
- *
- * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct
- * is stored in yylval. This struct contains the name of the symbol, it's
- * length and hash value. If there is already a symbol of the same name
- * and type in the symbol table, the sbuf struct also contains a pointer
- * to the symbol table entry.
- */
-static int
-name(void)
-{
- char *s;
- sbuf_t *sb;
- sym_t *sym;
- int tok;
-
- sb = allocsb();
- sb->sb_name = yytext;
- sb->sb_len = yyleng;
- sb->sb_hash = hash(yytext);
-
- if ((sym = search(sb)) != NULL && sym->s_keyw) {
- freesb(sb);
- return (keyw(sym));
- }
-
- sb->sb_sym = sym;
-
- if (sym != NULL) {
- if (blklev < sym->s_blklev)
- lerror("name() 1");
- sb->sb_name = sym->s_name;
- sb->sb_len = strlen(sym->s_name);
- tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
- } else {
- s = getblk(yyleng + 1);
- (void)memcpy(s, yytext, yyleng + 1);
- sb->sb_name = s;
- sb->sb_len = yyleng;
- tok = T_NAME;
- }
-
- yylval.y_sb = sb;
- return (tok);
-}
-
-static sym_t *
-search(sbuf_t *sb)
-{
- sym_t *sym;
-
- for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) {
- if (strcmp(sym->s_name, sb->sb_name) == 0) {
- if (sym->s_keyw || sym->s_kind == symtyp)
- return (sym);
- }
- }
-
- return (NULL);
-}
-
-static int
-keyw(sym_t *sym)
-{
- int t;
-
- if ((t = (int)sym->s_value.v_quad) == T_SCLASS) {
- yylval.y_scl = sym->s_scl;
- } else if (t == T_TYPE || t == T_SOU) {
- yylval.y_tspec = sym->s_tspec;
- } else if (t == T_QUAL) {
- yylval.y_tqual = sym->s_tqual;
- } else if (t == T_UNOP) {
- yylval.y_op = sym->s_op;
- }
- return (t);
-}
-
-/*
- * Convert a string representing an integer into internal representation.
- * The value is returned in yylval. icon() (and yylex()) returns T_CON.
- */
-static int
-icon(int base)
-{
- int l_suffix, u_suffix;
- int len;
- const char *cp;
- char c, *eptr;
- tspec_t typ;
- u_long ul;
- u_quad_t uq;
- int ansiu;
- static tspec_t contypes[2][3] = {
- { INT, LONG, QUAD },
- { UINT, ULONG, UQUAD }
- };
-
- cp = yytext;
- len = yyleng;
-
- /* skip 0x */
- if (base == 16) {
- cp += 2;
- len -= 2;
- }
-
- /* read suffixes */
- l_suffix = u_suffix = 0;
- for ( ; ; ) {
- if ((c = cp[len - 1]) == 'l' || c == 'L') {
- l_suffix++;
- } else if (c == 'u' || c == 'U') {
- u_suffix++;
- } else {
- break;
- }
- len--;
- }
- if (l_suffix > 2 || u_suffix > 1) {
- /* malformed integer constant */
- warning(251);
- if (l_suffix > 2)
- l_suffix = 2;
- if (u_suffix > 1)
- u_suffix = 1;
- }
- typ = contypes[u_suffix][l_suffix];
-
- errno = 0;
- if (l_suffix < 2) {
- ul = strtoul(cp, &eptr, base);
- } else {
- uq = strtouq(cp, &eptr, base);
- }
- if (eptr != cp + len)
- lerror("icon() 1");
- if (errno != 0)
- /* integer constant out of range */
- warning(252);
-
- /*
- * If the value is too big for the current type, we must choose
- * another type.
- */
- ansiu = 0;
- switch (typ) {
- case INT:
- if (ul <= INT_MAX) {
- /* ok */
- } else if (ul <= (unsigned)UINT_MAX && base != 10) {
- typ = UINT;
- } else if (ul <= LONG_MAX) {
- typ = LONG;
- } else {
- typ = ULONG;
- }
- if (typ == UINT || typ == ULONG) {
- if (!sflag) {
- /*
- * Remember that the constant is unsigned
- * only in ANSI C
- */
- ansiu = 1;
- }
- }
- break;
- case UINT:
- if (ul > (u_int)UINT_MAX)
- typ = ULONG;
- break;
- case LONG:
- if (ul > LONG_MAX) {
- typ = ULONG;
- if (!sflag)
- ansiu = 1;
- }
- break;
- case QUAD:
- if (uq > QUAD_MAX) {
- typ = UQUAD;
- if (!sflag)
- ansiu = 1;
- }
- break;
- /* LINTED (enumeration values not handled in switch) */
- }
-
- if (typ != QUAD && typ != UQUAD) {
- if (isutyp(typ)) {
- uq = ul;
- } else {
- uq = (quad_t)(long)ul;
- }
- }
-
- uq = (u_quad_t)xsign((quad_t)uq, typ, -1);
-
- (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
- yylval.y_val->v_ansiu = ansiu;
- yylval.y_val->v_quad = (quad_t)uq;
-
- return (T_CON);
-}
-
-/*
- * Returns 1 if t is a signed type and the value is negative.
- *
- * len is the number of significant bits. If len is -1, len is set
- * to the width of type t.
- */
-int
-sign(quad_t q, tspec_t t, int len)
-{
- if (t == PTR || isutyp(t))
- return (0);
- return (msb(q, t, len));
-}
-
-int
-msb(quad_t q, tspec_t t, int len)
-{
- if (len <= 0)
- len = size(t);
- return ((q & qbmasks[len - 1]) != 0);
-}
-
-/*
- * Extends the sign of q.
- */
-quad_t
-xsign(quad_t q, tspec_t t, int len)
-{
- if (len <= 0)
- len = size(t);
-
- if (t == PTR || isutyp(t) || !sign(q, t, len)) {
- q &= qlmasks[len];
- } else {
- q |= qumasks[len];
- }
- return (q);
-}
-
-/*
- * Convert a string representing a floating point value into its integral
- * representation. Type and value are returned in yylval. fcon()
- * (and yylex()) returns T_CON.
- * XXX Currently it is not possible to convert constants of type
- * long double which are greater then DBL_MAX.
- */
-static int
-fcon(void)
-{
- const char *cp;
- int len;
- tspec_t typ;
- tspec_t domain = NOTSPEC;
- char c, *eptr;
- double d;
- float f;
-
- cp = yytext;
- len = yyleng;
-
- c = cp[len - 1];
- if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
- domain = COMPLEX; /* XXX should be IMAGINARY */
- len--;
- c = cp[len - 1];
- }
- if (c == 'f' || c == 'F') {
- typ = FLOAT;
- len--;
- c = cp[len - 1];
- } else if (c == 'l' || c == 'L') {
- typ = LDOUBLE;
- len--;
- c = cp[len - 1];
- } else {
- typ = DOUBLE;
- }
- if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
- if (domain != NOTSPEC)
- lerror("fcon() 2"); /* can't happen */
- domain = COMPLEX; /* XXX should be IMAGINARY */
- len--;
- }
-
- errno = 0;
- d = strtod(cp, &eptr);
- if (eptr != cp + len)
- lerror("fcon() 1");
- if (errno != 0)
- /* floating-point constant out of range */
- warning(248);
-
- if (typ == FLOAT) {
- f = (float)d;
- if (isinf(f)) {
- /* floating-point constant out of range */
- warning(248);
- f = f > 0 ? FLT_MAX : -FLT_MAX;
- }
- }
-
- yylval.y_val = xcalloc(1, sizeof (val_t));
- if (typ == FLOAT) {
- yylval.y_val->v_ldbl = f;
- } else {
- yylval.y_val->v_ldbl = d;
- }
- if (mergedomain(&typ, domain))
- lerror("fcon() 3");
- yylval.y_val->v_tspec = typ;
-
- return (T_CON);
-}
-
-/*
- * Convert an hexadecimal representation of a floating point value
- * into its integral representation.
- * Type and value are returned in yylval. fhexcon()
- * (and yylex()) returns T_CON.
- * XXX Currently no actual values are parsed.
- */
-static int
-fhexcon(void)
-{
- const char *cp;
- int len;
- tspec_t typ;
- tspec_t domain = NOTSPEC;
- char c;
- double d;
- float f;
-
- cp = yytext;
- len = yyleng;
-
- c = cp[len - 1];
- if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
- domain = COMPLEX; /* XXX should be IMAGINARY */
- len--;
- c = cp[len - 1];
- }
- if (c == 'f' || c == 'F') {
- typ = FLOAT;
- len--;
- c = cp[len - 1];
- } else if (c == 'l' || c == 'L') {
- typ = LDOUBLE;
- len--;
- c = cp[len - 1];
- } else {
- typ = DOUBLE;
- }
- if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
- if (domain != NOTSPEC)
- lerror("fhexcon() 1"); /* can't happen */
- domain = COMPLEX; /* XXX should be IMAGINARY */
- len--;
- }
-
- /* arbitrary value, until strtod can cope */
- d = 1.0;
-
- if (typ == FLOAT) {
- f = (float)d;
- }
-
- yylval.y_val = xcalloc(1, sizeof (val_t));
- if (typ == FLOAT) {
- yylval.y_val->v_ldbl = f;
- } else {
- yylval.y_val->v_ldbl = d;
- }
- if (mergedomain(&typ, domain))
- lerror("fhexcon() 2");
- yylval.y_val->v_tspec = typ;
-
- return (T_CON);
-}
-
-static int
-operator(int t, op_t o)
-{
- yylval.y_op = o;
- return (t);
-}
-
-/*
- * Called if lex found a leading '.
- */
-static int
-ccon(void)
-{
- int n, val, c;
- char cv;
-
- n = 0;
- val = 0;
- while ((c = getescc('\'')) >= 0) {
- val = (val << CHAR_BIT) + c;
- n++;
- }
- if (c == -2) {
- /* unterminated character constant */
- error(253);
- } else {
- if (n > sizeof (int) || (n > 1 && (pflag || hflag))) {
- /* too many characters in character constant */
- error(71);
- } else if (n > 1) {
- /* multi-character character constant */
- warning(294);
- } else if (n == 0) {
- /* empty character constant */
- error(73);
- }
- }
- if (n == 1) {
- cv = (char)val;
- val = cv;
- }
-
- yylval.y_val = xcalloc(1, sizeof (val_t));
- yylval.y_val->v_tspec = INT;
- yylval.y_val->v_lspec = CHAR;
- yylval.y_val->v_quad = val;
-
- return (T_CON);
-}
-
-/*
- * Called if lex found a leading L\'
- */
-static int
-wccon(void)
-{
- static char buf[MB_LEN_MAX + 1];
- int i, c;
- wchar_t wc;
-
- i = 0;
- while ((c = getescc('\'')) >= 0) {
- if (i < MB_CUR_MAX)
- buf[i] = (char)c;
- i++;
- }
-
- wc = 0;
-
- if (c == -2) {
- /* unterminated character constant */
- error(253);
- } else if (c == 0) {
- /* empty character constant */
- error(73);
- } else {
- if (i > MB_CUR_MAX) {
- i = MB_CUR_MAX;
- /* too many characters in character constant */
- error(71);
- } else {
- buf[i] = '\0';
- (void)mbtowc(NULL, NULL, 0);
- if (mbtowc(&wc, buf, MB_CUR_MAX) < 0)
- /* invalid multibyte character */
- error(291);
- }
- }
-
- yylval.y_val = xcalloc(1, sizeof (val_t));
- yylval.y_val->v_tspec = WCHAR;
- yylval.y_val->v_quad = wc;
-
- return (T_CON);
-}
-
-/*
- * Read a character which is part of a character constant or of a string
- * and handle escapes.
- *
- * The Argument is the character which delimits the character constant or
- * string.
- *
- * Returns -1 if the end of the character constant or string is reached,
- * -2 if the EOF is reached, and the charachter otherwise.
- */
-static int
-getescc(int d)
-{
- static int pbc = -1;
- int n, c, v;
-
- if (pbc == -1) {
- c = inpc();
- } else {
- c = pbc;
- pbc = -1;
- }
- if (c == d)
- return (-1);
- switch (c) {
- case '\n':
- /* newline in string or char constant */
- error(254);
- return (-2);
- case EOF:
- return (-2);
- case '\\':
- switch (c = inpc()) {
- case '"':
- return ('"');
- case '\'':
- return ('\'');
- case '?':
- return ('?');
- case '\\':
- return ('\\');
- case 'a':
- return ('\a');
- case 'b':
- return ('\b');
- case 'f':
- return ('\f');
- case 'n':
- return ('\n');
- case 'r':
- return ('\r');
- case 't':
- return ('\t');
- case 'v':
- return ('\v');
- case '8': case '9':
- /* bad octal digit %c */
- warning(77, c);
- /* FALLTHROUGH */
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- n = 3;
- v = 0;
- do {
- v = (v << 3) + (c - '0');
- c = inpc();
- } while (--n && isdigit(c) && (c <= '7'));
- pbc = c;
- if (v > UCHAR_MAX) {
- /* character escape does not fit in char. */
- warning(76);
- v &= CHAR_MASK;
- }
- return (v);
- case 'x':
- v = 0;
- n = 0;
- while ((c = inpc()) >= 0 && isxdigit(c)) {
- c = isdigit(c) ?
- c - '0' : toupper(c) - 'A' + 10;
- v = (v << 4) + c;
- if (n >= 0) {
- if ((v & ~CHAR_MASK) != 0) {
- /* overflow in hex escape */
- warning(75);
- n = -1;
- } else {
- n++;
- }
- }
- }
- pbc = c;
- if (n == 0) {
- /* no hex digits follow \x */
- error(74);
- } if (n == -1) {
- v &= CHAR_MASK;
- }
- return (v);
- case '\n':
- return (getescc(d));
- case EOF:
- return (-2);
- default:
- if (isprint(c)) {
- /* dubious escape \%c */
- warning(79, c);
- } else {
- /* dubious escape \%o */
- warning(80, c);
- }
- }
- }
- return (c);
-}
-
-/*
- * Called for preprocessor directives. Currently implemented are:
- * # lineno
- * # lineno "filename"
- */
-static void
-directive(void)
-{
- const char *cp, *fn;
- char c, *eptr;
- size_t fnl;
- long ln;
- static int first = 1;
-
- /* Go to first non-whitespace after # */
- for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) ;
-
- if (!isdigit(c)) {
- error:
- /* undefined or invalid # directive */
- warning(255);
- return;
- }
- ln = strtol(--cp, &eptr, 10);
- if (cp == eptr)
- goto error;
- if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
- goto error;
- while ((c = *cp++) == ' ' || c == '\t') ;
- if (c != '\0') {
- if (c != '"')
- goto error;
- fn = cp;
- while ((c = *cp) != '"' && c != '\0')
- cp++;
- if (c != '"')
- goto error;
- if ((fnl = cp++ - fn) > PATH_MAX)
- goto error;
- while ((c = *cp++) == ' ' || c == '\t') ;
-#if 0
- if (c != '\0')
- warning("extra character(s) after directive");
-#endif
- curr_pos.p_file = fnnalloc(fn, fnl);
- /*
- * If this is the first directive, the name is the name
- * of the C source file as specified at the command line.
- * It is written to the output file.
- */
- if (first) {
- csrc_pos.p_file = curr_pos.p_file;
- outsrc(curr_pos.p_file);
- first = 0;
- }
- }
- curr_pos.p_line = (int)ln - 1;
- if (curr_pos.p_file == csrc_pos.p_file)
- csrc_pos.p_line = (int)ln - 1;
-}
-
-/*
- * Handle lint comments. Following comments are currently understood:
- * ARGSUSEDn
- * CONSTCOND CONSTANTCOND CONSTANTCONDITION
- * FALLTHRU FALLTHROUGH
- * LINTLIBRARY
- * LINTED NOSTRICT
- * LONGLONG
- * NORETURN
- * NOTREACHED
- * PRINTFLIKEn
- * PROTOLIB
- * SCANFLIKEn
- * VARARGSn
- * If one of this comments is recognized, the arguments, if any, are
- * parsed and a function which handles this comment is called.
- */
-static void
-comment(void)
-{
- int c, lc;
- static struct {
- const char *keywd;
- int arg;
- void (*func)(int);
- } keywtab[] = {
- { "ARGSUSED", 1, argsused },
- { "CONSTCOND", 0, constcond },
- { "CONSTANTCOND", 0, constcond },
- { "CONSTANTCONDITION", 0, constcond },
- { "FALLTHRU", 0, fallthru },
- { "FALLTHROUGH", 0, fallthru },
- { "LINTLIBRARY", 0, lintlib },
- { "LINTED", 0, linted },
- { "LINTUSED", 0, lintused },
- { "LONGLONG", 0, longlong },
- { "NORETURN", 1, noreturn },
- { "NOSTRICT", 0, linted },
- { "NOTREACHED", 0, notreach },
- { "PRINTFLIKE", 1, printflike },
- { "PROTOLIB", 1, protolib },
- { "SCANFLIKE", 1, scanflike },
- { "VARARGS", 1, varargs },
- };
- char keywd[32];
- char arg[32];
- int l, i, a;
- int eoc;
-
- eoc = 0;
-
- /* Skip white spaces after the start of the comment */
- while ((c = inpc()) != EOF && isspace(c)) ;
-
- /* Read the potential keyword to keywd */
- l = 0;
- while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) {
- keywd[l++] = (char)c;
- c = inpc();
- }
- keywd[l] = '\0';
-
- /* look for the keyword */
- for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) {
- if (strcmp(keywtab[i].keywd, keywd) == 0)
- break;
- }
- if (i == sizeof (keywtab) / sizeof (keywtab[0]))
- goto skip_rest;
-
- /* skip white spaces after the keyword */
- while (c != EOF && isspace(c))
- c = inpc();
-
- /* read the argument, if the keyword accepts one and there is one */
- l = 0;
- if (keywtab[i].arg) {
- while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) {
- arg[l++] = (char)c;
- c = inpc();
- }
- }
- arg[l] = '\0';
- a = l != 0 ? atoi(arg) : -1;
-
- /* skip white spaces after the argument */
- while (c != EOF && isspace(c))
- c = inpc();
-
- if (c != '*' || (c = inpc()) != '/') {
- if (keywtab[i].func != linted)
- /* extra characters in lint comment */
- warning(257);
- } else {
- /*
- * remember that we have already found the end of the
- * comment
- */
- eoc = 1;
- }
-
- if (keywtab[i].func != NULL)
- (*keywtab[i].func)(a);
-
- skip_rest:
- while (!eoc) {
- lc = c;
- if ((c = inpc()) == EOF) {
- /* unterminated comment */
- error(256);
- break;
- }
- if (lc == '*' && c == '/')
- eoc = 1;
- }
-}
-
-/*
- * Handle // style comments, which are valid in C99.
- */
-static void
-slashslashcomment(void)
-{
- int c;
-
- while ((c = inpc()) != EOF && c != '\n');
-}
-
-/*
- * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
- * clrwflgs() is called after function definitions and global and
- * local declarations and definitions. It is also called between
- * the controlling expression and the body of control statements
- * (if, switch, for, while).
- */
-void
-clrwflgs(void)
-{
- nowarn = 0;
- quadflg = 1;
- ccflg = 0;
- usedflg = 0;
-}
-
-/*
- * Strings are stored in a dynamically alloceted buffer and passed
- * in yylval.y_xstrg to the parser. The parser or the routines called
- * by the parser are responsible for freeing this buffer.
- */
-static int
-string(void)
-{
- u_char *s;
- int c;
- size_t len, max;
- strg_t *strg;
-
- s = xmalloc(max = 64);
-
- len = 0;
- while ((c = getescc('"')) >= 0) {
- /* +1 to reserve space for a trailing NUL character */
- if (len + 1 == max)
- s = xrealloc(s, max *= 2);
- s[len++] = (char)c;
- }
- s[len] = '\0';
- if (c == -2)
- /* unterminated string constant */
- error(258);
-
- strg = xcalloc(1, sizeof (strg_t));
- strg->st_tspec = CHAR;
- strg->st_len = len;
- strg->st_cp = s;
-
- yylval.y_strg = strg;
- return (T_STRING);
-}
-
-static int
-wcstrg(void)
-{
- char *s;
- int c, i, n, wi;
- size_t len, max, wlen;
- wchar_t *ws;
- strg_t *strg;
-
- s = xmalloc(max = 64);
- len = 0;
- while ((c = getescc('"')) >= 0) {
- /* +1 to save space for a trailing NUL character */
- if (len + 1 >= max)
- s = xrealloc(s, max *= 2);
- s[len++] = (char)c;
- }
- s[len] = '\0';
- if (c == -2)
- /* unterminated string constant */
- error(258);
-
- /* get length of wide character string */
- (void)mblen(NULL, 0);
- for (i = 0, wlen = 0; i < len; i += n, wlen++) {
- if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
- /* invalid multibyte character */
- error(291);
- break;
- }
- if (n == 0)
- n = 1;
- }
-
- ws = xmalloc((wlen + 1) * sizeof (wchar_t));
-
- /* convert from multibyte to wide char */
- (void)mbtowc(NULL, NULL, 0);
- for (i = 0, wi = 0; i < len; i += n, wi++) {
- if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
- break;
- if (n == 0)
- n = 1;
- }
- ws[wi] = 0;
- free(s);
-
- strg = xcalloc(1, sizeof (strg_t));
- strg->st_tspec = WCHAR;
- strg->st_len = wlen;
- strg->st_wcp = ws;
-
- yylval.y_strg = strg;
- return (T_STRING);
-}
-
-/*
- * As noted above the scanner does not create new symbol table entries
- * for symbols it cannot find in the symbol table. This is to avoid
- * putting undeclared symbols into the symbol table if a syntax error
- * occurs.
- *
- * getsym() is called as soon as it is probably ok to put the symbol to
- * the symbol table. This does not mean that it is not possible that
- * symbols are put to the symbol table which are than not completely
- * declared due to syntax errors. To avoid too many problems in this
- * case symbols get type int in getsym().
- *
- * XXX calls to getsym() should be delayed until decl1*() is called
- */
-sym_t *
-getsym(sbuf_t *sb)
-{
- dinfo_t *di;
- char *s;
- sym_t *sym;
-
- sym = sb->sb_sym;
-
- /*
- * During member declaration it is possible that name() looked
- * for symbols of type FVFT, although it should have looked for
- * symbols of type FTAG. Same can happen for labels. Both cases
- * are compensated here.
- */
- if (symtyp == FMOS || symtyp == FLAB) {
- if (sym == NULL || sym->s_kind == FVFT)
- sym = search(sb);
- }
-
- if (sym != NULL) {
- if (sym->s_kind != symtyp)
- lerror("storesym() 1");
- symtyp = FVFT;
- freesb(sb);
- return (sym);
- }
-
- /* create a new symbol table entry */
-
- /* labels must always be allocated at level 1 (outhermost block) */
- if (symtyp == FLAB) {
- sym = getlblk(1, sizeof (sym_t));
- s = getlblk(1, sb->sb_len + 1);
- (void)memcpy(s, sb->sb_name, sb->sb_len + 1);
- sym->s_name = s;
- sym->s_blklev = 1;
- di = dcs;
- while (di->d_nxt != NULL && di->d_nxt->d_nxt != NULL)
- di = di->d_nxt;
- if (di->d_ctx != AUTO)
- lerror("storesym() 2");
- } else {
- sym = getblk(sizeof (sym_t));
- sym->s_name = sb->sb_name;
- sym->s_blklev = blklev;
- di = dcs;
- }
-
- STRUCT_ASSIGN(sym->s_dpos, curr_pos);
- if ((sym->s_kind = symtyp) != FLAB)
- sym->s_type = gettyp(INT);
-
- symtyp = FVFT;
-
- if ((sym->s_link = symtab[sb->sb_hash]) != NULL)
- symtab[sb->sb_hash]->s_rlink = &sym->s_link;
- (symtab[sb->sb_hash] = sym)->s_rlink = &symtab[sb->sb_hash];
-
- *di->d_ldlsym = sym;
- di->d_ldlsym = &sym->s_dlnxt;
-
- freesb(sb);
- return (sym);
-}
-
-/*
- * Remove a symbol forever from the symbol table. s_blklev
- * is set to -1 to avoid that the symbol will later be put
- * back to the symbol table.
- */
-void
-rmsym(sym_t *sym)
-{
- if ((*sym->s_rlink = sym->s_link) != NULL)
- sym->s_link->s_rlink = sym->s_rlink;
- sym->s_blklev = -1;
- sym->s_link = NULL;
-}
-
-/*
- * Remove a list of symbols declared at one level from the symbol
- * table.
- */
-void
-rmsyms(sym_t *syms)
-{
- sym_t *sym;
-
- for (sym = syms; sym != NULL; sym = sym->s_dlnxt) {
- if (sym->s_blklev != -1) {
- if ((*sym->s_rlink = sym->s_link) != NULL)
- sym->s_link->s_rlink = sym->s_rlink;
- sym->s_link = NULL;
- sym->s_rlink = NULL;
- }
- }
-}
-
-/*
- * Put a symbol into the symbol table
- */
-void
-inssym(int bl, sym_t *sym)
-{
- int h;
-
- h = hash(sym->s_name);
- if ((sym->s_link = symtab[h]) != NULL)
- symtab[h]->s_rlink = &sym->s_link;
- (symtab[h] = sym)->s_rlink = &symtab[h];
- sym->s_blklev = bl;
- if (sym->s_link != NULL && sym->s_blklev < sym->s_link->s_blklev)
- lerror("inssym()");
-}
-
-/*
- * Called at level 0 after syntax errors
- * Removes all symbols which are not declared at level 0 from the
- * symbol table. Also frees all memory which is not associated with
- * level 0.
- */
-void
-cleanup(void)
-{
- sym_t *sym, *nsym;
- int i;
-
- for (i = 0; i < HSHSIZ1; i++) {
- for (sym = symtab[i]; sym != NULL; sym = nsym) {
- nsym = sym->s_link;
- if (sym->s_blklev >= 1) {
- if ((*sym->s_rlink = nsym) != NULL)
- nsym->s_rlink = sym->s_rlink;
- }
- }
- }
-
- for (i = mblklev; i > 0; i--)
- freelblk(i);
-}
-
-/*
- * Create a new symbol with the name of an existing symbol.
- */
-sym_t *
-pushdown(sym_t *sym)
-{
- int h;
- sym_t *nsym;
-
- h = hash(sym->s_name);
- nsym = getblk(sizeof (sym_t));
- if (sym->s_blklev > blklev)
- lerror("pushdown()");
- nsym->s_name = sym->s_name;
- STRUCT_ASSIGN(nsym->s_dpos, curr_pos);
- nsym->s_kind = sym->s_kind;
- nsym->s_blklev = blklev;
-
- if ((nsym->s_link = symtab[h]) != NULL)
- symtab[h]->s_rlink = &nsym->s_link;
- (symtab[h] = nsym)->s_rlink = &symtab[h];
-
- *dcs->d_ldlsym = nsym;
- dcs->d_ldlsym = &nsym->s_dlnxt;
-
- return (nsym);
-}
-
-/*
- * Free any dynamically allocated memory referenced by
- * the value stack or yylval.
- * The type of information in yylval is described by tok.
- */
-void
-freeyyv(void *sp, int tok)
-{
- if (tok == T_NAME || tok == T_TYPENAME) {
- sbuf_t *sb = *(sbuf_t **)sp;
- freesb(sb);
- } else if (tok == T_CON) {
- val_t *val = *(val_t **)sp;
- free(val);
- } else if (tok == T_STRING) {
- strg_t *strg = *(strg_t **)sp;
- if (strg->st_tspec == CHAR) {
- free(strg->st_cp);
- } else if (strg->st_tspec == WCHAR) {
- free(strg->st_wcp);
- } else {
- lerror("fryylv() 1");
- }
- free(strg);
- }
-}
diff --git a/usr.bin/xlint/lint1/tree.c b/usr.bin/xlint/lint1/tree.c
deleted file mode 100644
index ce6a1e20941..00000000000
--- a/usr.bin/xlint/lint1/tree.c
+++ /dev/null
@@ -1,3966 +0,0 @@
-/* $OpenBSD: tree.c,v 1.48 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: tree.c,v 1.12 1995/10/02 17:37:57 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <float.h>
-#include <limits.h>
-#include <math.h>
-
-#include "lint1.h"
-#include "y.tab.h"
-
-/* Various flags for each operator. */
-static mod_t modtab[NOPS];
-
-static tnode_t *getinode(tspec_t, quad_t);
-static void ptrcmpok(op_t, tnode_t *, tnode_t *);
-static int asgntypok(op_t, farg_t *, tnode_t *, tnode_t *);
-static void chkbeop(op_t, tnode_t *, tnode_t *);
-static void chkeop2(op_t, farg_t *, tnode_t *, tnode_t *);
-static void chkeop1(op_t, farg_t *, tnode_t *, tnode_t *);
-static tnode_t *mktnode(op_t, type_t *, tnode_t *, tnode_t *);
-static void balance(op_t, tnode_t **, tnode_t **);
-static void incompat(op_t, tspec_t, tspec_t);
-static void illptrc(mod_t *, type_t *, type_t *);
-static void mrgqual(type_t **, type_t *, type_t *);
-static int conmemb(type_t *);
-static tspec_t fcnconv(farg_t *, tspec_t, tspec_t, type_t *, tnode_t *);
-static void iiconv(op_t, farg_t *, tspec_t, tspec_t, type_t *, tnode_t *);
-static void piconv(op_t, tspec_t, type_t *, tnode_t *);
-static void ppconv(op_t, tnode_t *, type_t *);
-static tnode_t *bldstr(op_t, tnode_t *, tnode_t *);
-static tnode_t *bldincdec(op_t, tnode_t *);
-static tnode_t *bldamper(tnode_t *, int);
-static tnode_t *bldplmi(op_t, tnode_t *, tnode_t *);
-static tnode_t *bldshft(op_t, tnode_t *, tnode_t *);
-static tnode_t *bldcol(tnode_t *, tnode_t *);
-static tnode_t *bldasgn(op_t, tnode_t *, tnode_t *);
-static tnode_t *plength(type_t *);
-static tnode_t *fold(tnode_t *);
-static tnode_t *foldtst(tnode_t *);
-static tnode_t *foldflt(tnode_t *);
-static tnode_t *chkfarg(tnode_t *, tnode_t *);
-static tnode_t *parg(farg_t *, tnode_t *);
-static int chkdbz(op_t, tnode_t *);
-static void nulleff(tnode_t *);
-static int nulleffexpr(tnode_t *);
-static void chkaidx(tnode_t *, int);
-static void chkcomp(op_t, tnode_t *, tnode_t *);
-static void precconf(tnode_t *);
-static const char *funcname(tnode_t *);
-
-/*
- * Initialize mods of operators.
- */
-void
-initmtab(void)
-{
- static struct {
- op_t op;
- mod_t m;
- } imods[] = {
- { ARROW, { 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
- "->" } },
- { POINT, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "." } },
- { NOT, { 0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,
- "!" } },
- { COMPL, { 0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,1,1,
- "~" } },
- { INCBEF, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "prefix++" } },
- { DECBEF, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "prefix--" } },
- { INCAFT, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "postfix++" } },
- { DECAFT, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "postfix--" } },
- { UPLUS, { 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,
- "unary +" } },
- { UMINUS, { 0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,1,1,
- "unary -" } },
- { STAR, { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
- "unary *" } },
- { AMPER, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "unary &" } },
- { MULT, { 1,0,0,0,1,1,1,0,1,0,0,1,0,0,0,1,1,
- "*" } },
- { DIV, { 1,0,0,0,1,1,1,0,1,0,1,1,0,0,0,1,1,
- "/" } },
- { MOD, { 1,0,1,0,0,1,1,0,1,0,1,1,0,0,0,1,1,
- "%" } },
- { PLUS, { 1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,
- "+" } },
- { MINUS, { 1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0,
- "-" } },
- { SHL, { 1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,
- "<<" } },
- { SHR, { 1,0,1,0,0,1,1,0,0,0,1,0,1,0,0,1,1,
- ">>" } },
- { LT, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
- "<" } },
- { LE, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
- "<=" } },
- { GT, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
- ">" } },
- { GE, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,
- ">=" } },
- { EQ, { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,0,
- "==" } },
- { NE, { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1,
- "!=" } },
- { AND, { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,
- "&" } },
- { XOR, { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,
- "^" } },
- { OR, { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,
- "|" } },
- { LOGAND, { 1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,
- "&&" } },
- { LOGOR, { 1,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,0,
- "||" } },
- { QUEST, { 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,
- "?" } },
- { COLON, { 1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,
- ":" } },
- { ASSIGN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,
- "=" } },
- { MULASS, { 1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,
- "*=" } },
- { DIVASS, { 1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,
- "/=" } },
- { MODASS, { 1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,
- "%=" } },
- { ADDASS, { 1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "+=" } },
- { SUBASS, { 1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "-=" } },
- { SHLASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "<<=" } },
- { SHRASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
- ">>=" } },
- { ANDASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "&=" } },
- { XORASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "^=" } },
- { ORASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,
- "|=" } },
- { NAME, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "NAME" } },
- { CON, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "CON" } },
- { STRING, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "STRING" } },
- { FSEL, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "FSEL" } },
- { CALL, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
- "CALL" } },
- { COMMA, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
- "," } },
- { CVT, { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
- "CVT" } },
- { ICALL, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
- "ICALL" } },
- { LOAD, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- "LOAD" } },
- { PUSH, { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
- "PUSH" } },
- { RETURN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,
- "RETURN" } },
- { REAL, { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,
- "__real__" } },
- { IMAG, { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,
- "__imag__" } },
- { INIT, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
- "INIT" } },
- { FARG, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
- "FARG" } },
- { NOOP }
- };
- int i;
-
- for (i = 0; imods[i].op != NOOP; i++)
- STRUCT_ASSIGN(modtab[imods[i].op], imods[i].m);
-}
-
-/*
- * Increase degree of reference.
- * This is most often used to change type "T" in type "pointer to T".
- */
-type_t *
-incref(type_t *tp, tspec_t t)
-{
- type_t *tp2;
-
- tp2 = getblk(sizeof (type_t));
- tp2->t_tspec = t;
- tp2->t_subt = tp;
- return (tp2);
-}
-
-/*
- * same for use in expressions
- */
-type_t *
-tincref(type_t *tp, tspec_t t)
-{
- type_t *tp2;
-
- tp2 = tgetblk(sizeof (type_t));
- tp2->t_tspec = t;
- tp2->t_subt = tp;
- return (tp2);
-}
-
-/*
- * Create a node for a constant.
- */
-tnode_t *
-getcnode(type_t *tp, val_t *v)
-{
- tnode_t *n;
-
- n = getnode();
- n->tn_op = CON;
- n->tn_type = tp;
- n->tn_val = tgetblk(sizeof (val_t));
- n->tn_val->v_tspec = tp->t_tspec;
- n->tn_val->v_lspec = v->v_lspec;
- n->tn_val->v_ansiu = v->v_ansiu;
- n->tn_val->v_u = v->v_u;
- free(v);
- return (n);
-}
-
-/*
- * Create a node for a integer constant.
- */
-static tnode_t *
-getinode(tspec_t t, quad_t q)
-{
- tnode_t *n;
-
- n = getnode();
- n->tn_op = CON;
- n->tn_type = gettyp(t);
- n->tn_val = tgetblk(sizeof (val_t));
- n->tn_val->v_tspec = t;
- n->tn_val->v_quad = q;
- return (n);
-}
-
-/*
- * Create a node for a name (symbol table entry).
- * ntok is the token which follows the name.
- */
-tnode_t *
-getnnode(sym_t *sym, int ntok)
-{
- tnode_t *n;
-
- if (sym->s_scl == NOSCL) {
- sym->s_scl = EXTERN;
- sym->s_def = DECL;
- if (ntok == T_LPARN) {
- if (sflag) {
- /* function implicitly declared to ... */
- warning(215);
- }
- sym->s_type = incref(sym->s_type, FUNC);
- } else {
- /* %s undefined */
- error(99, sym->s_name);
- }
- }
-
- if (sym->s_kind != FVFT && sym->s_kind != FMOS)
- lerror("getnnode() 1");
-
- n = getnode();
- n->tn_type = sym->s_type;
- if (sym->s_scl != ENUMCON) {
- n->tn_op = NAME;
- n->tn_sym = sym;
- if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
- n->tn_lvalue = 1;
- } else {
- n->tn_op = CON;
- n->tn_val = tgetblk(sizeof (val_t));
- *n->tn_val = sym->s_value;
- }
-
- return (n);
-}
-
-/*
- * Create a node for a string.
- */
-tnode_t *
-getsnode(strg_t *strg)
-{
- size_t len;
- tnode_t *n;
-
- len = strg->st_len;
-
- n = getnode();
-
- n->tn_op = STRING;
- n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY);
- n->tn_type->t_dim = len + 1;
- n->tn_lvalue = 1;
-
- n->tn_strg = tgetblk(sizeof (strg_t));
- n->tn_strg->st_tspec = strg->st_tspec;
- n->tn_strg->st_len = len;
-
- if (strg->st_tspec == CHAR) {
- n->tn_strg->st_cp = tgetblk(len + 1);
- (void)memcpy(n->tn_strg->st_cp, strg->st_cp, len + 1);
- free(strg->st_cp);
- } else {
- n->tn_strg->st_wcp = tgetblk((len + 1) * sizeof (wchar_t));
- (void)memcpy(n->tn_strg->st_wcp, strg->st_wcp,
- (len + 1) * sizeof (wchar_t));
- free(strg->st_wcp);
- }
- free(strg);
-
- return (n);
-}
-
-/*
- * Returns a symbol which has the same name as the msym argument and is a
- * member of the struct or union specified by the tn argument.
- */
-sym_t *
-strmemb(tnode_t *tn, op_t op, sym_t *msym)
-{
- str_t *str;
- type_t *tp;
- sym_t *sym, *csym;
- int eq;
- tspec_t t;
-
- /*
- * Remove the member if it was unknown until now (Which means
- * that no defined struct or union has a member with the same name).
- */
- if (msym->s_scl == NOSCL) {
- /* undefined struct/union member: %s */
- error(101, msym->s_name);
- rmsym(msym);
- msym->s_kind = FMOS;
- msym->s_scl = MOS;
- msym->s_styp = tgetblk(sizeof (str_t));
- msym->s_styp->stag = tgetblk(sizeof (sym_t));
- msym->s_styp->stag->s_name = unnamed;
- msym->s_value.v_tspec = INT;
- return (msym);
- }
-
- /* Set str to the tag of which msym is expected to be a member. */
- str = NULL;
- t = (tp = tn->tn_type)->t_tspec;
- if (op == POINT) {
- if (t == STRUCT || t == UNION)
- str = tp->t_str;
- } else if (op == ARROW && t == PTR) {
- t = (tp = tp->t_subt)->t_tspec;
- if (t == STRUCT || t == UNION)
- str = tp->t_str;
- }
-
- /*
- * If this struct/union has a member with the name of msym, return
- * return this it.
- */
- if (str != NULL) {
- for (sym = msym; sym != NULL; sym = sym->s_link) {
- if (sym->s_scl != MOS && sym->s_scl != MOU)
- continue;
- if (sym->s_styp != str)
- continue;
- if (strcmp(sym->s_name, msym->s_name) != 0)
- continue;
- return (sym);
- }
- }
-
- /*
- * Set eq to 0 if there are struct/union members with the same name
- * and different types and/or offsets.
- */
- eq = 1;
- for (csym = msym; csym != NULL; csym = csym->s_link) {
- if (csym->s_scl != MOS && csym->s_scl != MOU)
- continue;
- if (strcmp(msym->s_name, csym->s_name) != 0)
- continue;
- for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) {
- int w;
-
- if (sym->s_scl != MOS && sym->s_scl != MOU)
- continue;
- if (strcmp(csym->s_name, sym->s_name) != 0)
- continue;
- if (csym->s_value.v_quad != sym->s_value.v_quad) {
- eq = 0;
- break;
- }
- w = 0;
- eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w;
- if (!eq)
- break;
- if (csym->s_field != sym->s_field) {
- eq = 0;
- break;
- }
- if (csym->s_field) {
- type_t *tp1, *tp2;
-
- tp1 = csym->s_type;
- tp2 = sym->s_type;
- if (tp1->t_flen != tp2->t_flen) {
- eq = 0;
- break;
- }
- if (tp1->t_foffs != tp2->t_foffs) {
- eq = 0;
- break;
- }
- }
- }
- if (!eq)
- break;
- }
-
- /*
- * Now handle the case in which the left operand refers really
- * to a struct/union, but the right operand is not member of it.
- */
- if (str != NULL) {
- /* illegal member use: %s */
- error(102, msym->s_name);
- return (msym);
- }
-
- /*
- * Now the left operand of ARROW does not point to a struct/union
- * or the left operand of POINT is no struct/union.
- */
- if (eq) {
- if (op == POINT) {
- /* left operand of "." must be struct/union object */
- error(103);
- } else {
- /* left operand of "->" must be pointer to ... */
- error(104);
- }
- } else {
- /* unacceptable operand of %s */
- error(111, modtab[op].m_name);
- }
-
- return (msym);
-}
-
-/*
- * Create a tree node. Called for most operands except function calls,
- * sizeof and casts.
- *
- * op operator
- * ln left operand
- * rn if not NULL, right operand
- */
-tnode_t *
-build(op_t op, tnode_t *ln, tnode_t *rn)
-{
- mod_t *mp;
- tnode_t *ntn;
- type_t *rtp;
-
- mp = &modtab[op];
-
- /* If there was an error in one of the operands, return. */
- if (ln == NULL || (mp->m_binary && rn == NULL))
- return (NULL);
-
- /*
- * Apply class conversions to the left operand, but only if its
- * value is needed or it is compared with null.
- */
- if (mp->m_vctx || mp->m_tctx)
- ln = cconv(ln);
- /*
- * The right operand is almost always in a test or value context,
- * except if it is a struct or union member.
- */
- if (mp->m_binary && op != ARROW && op != POINT)
- rn = cconv(rn);
-
- /*
- * Print some warnings for comparisons of unsigned values with
- * constants lower than or equal to null. This must be done
- * before promote() because otherwise unsigned char and unsigned
- * short would be promoted to int. Also types are tested to be
- * CHAR, which would also become int.
- */
- if (mp->m_comp)
- chkcomp(op, ln, rn);
-
- /*
- * Promote the left operand if it is in a test or value context
- */
- if (mp->m_vctx || mp->m_tctx)
- ln = promote(op, 0, ln);
- /*
- * Promote the right operand, but only if it is no struct or
- * union member, or if it is not to be assigned to the left operand
- */
- if (mp->m_binary && op != ARROW && op != POINT &&
- op != ASSIGN && op != RETURN) {
- rn = promote(op, 0, rn);
- }
-
- /*
- * If the result of the operation is different for signed or
- * unsigned operands and one of the operands is signed only in
- * ANSI C, print a warning.
- */
- if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) {
- /* ANSI C treats constant as unsigned, op %s */
- warning(218, mp->m_name);
- ln->tn_val->v_ansiu = 0;
- }
- if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) {
- /* ANSI C treats constant as unsigned, op %s */
- warning(218, mp->m_name);
- rn->tn_val->v_ansiu = 0;
- }
-
- /* Make sure both operands are of the same type */
- if (mp->m_balance)
- balance(op, &ln, &rn);
-
- /*
- * Check types for compatibility with the operation and mutual
- * compatibility. Return if there are serious problems.
- */
- if (!typeok(op, NULL, ln, rn))
- return (NULL);
-
- /* And now create the node. */
- switch (op) {
- case POINT:
- case ARROW:
- ntn = bldstr(op, ln, rn);
- break;
- case INCAFT:
- case DECAFT:
- case INCBEF:
- case DECBEF:
- ntn = bldincdec(op, ln);
- break;
- case AMPER:
- ntn = bldamper(ln, 0);
- break;
- case STAR:
- ntn = mktnode(STAR, ln->tn_type->t_subt, ln, NULL);
- break;
- case PLUS:
- case MINUS:
- ntn = bldplmi(op, ln, rn);
- break;
- case SHL:
- case SHR:
- ntn = bldshft(op, ln, rn);
- break;
- case COLON:
- ntn = bldcol(ln, rn);
- break;
- case ASSIGN:
- case MULASS:
- case DIVASS:
- case MODASS:
- case ADDASS:
- case SUBASS:
- case SHLASS:
- case SHRASS:
- case ANDASS:
- case XORASS:
- case ORASS:
- case RETURN:
- ntn = bldasgn(op, ln, rn);
- break;
- case COMMA:
- case QUEST:
- ntn = mktnode(op, rn->tn_type, ln, rn);
- break;
- case REAL:
- case IMAG:
- rtp = ln->tn_type;
- if (rtp->t_tspec == COMPLEX)
- rtp = gettyp(FLOAT);
- else if (rtp->t_tspec == DCOMPLEX)
- rtp = gettyp(DOUBLE);
- else if (rtp->t_tspec == LDCOMPLEX)
- rtp = gettyp(LDOUBLE);
- ntn = mktnode(op, rtp, ln, rn);
- break;
- default:
- rtp = mp->m_logop ? gettyp(INT) : ln->tn_type;
- if (!mp->m_binary && rn != NULL)
- lerror("build() 1");
- ntn = mktnode(op, rtp, ln, rn);
- break;
- }
-
- /* Return if an error occurred. */
- if (ntn == NULL)
- return (NULL);
-
- /* Print a warning if precedence confusion is possible */
- if (mp->m_tpconf)
- precconf(ntn);
-
- /*
- * Print a warning if one of the operands is in a context where
- * it is compared with null and if this operand is a constant.
- */
- if (mp->m_tctx) {
- if (ln->tn_op == CON ||
- ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
- if (hflag && !ccflg) {
- /* constant in conditional context */
- warning(161);
- }
- }
- }
-
- /* Fold if the operator requires it */
- if (mp->m_fold) {
- if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
- if (mp->m_tctx) {
- ntn = foldtst(ntn);
- } else if (isftyp(ntn->tn_type->t_tspec)) {
- ntn = foldflt(ntn);
- } else {
- ntn = fold(ntn);
- }
- } else if (op == QUEST && ln->tn_op == CON) {
- ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right;
- }
- }
-
- return (ntn);
-}
-
-/*
- * Perform class conversions.
- *
- * Arrays of type T are converted into pointers to type T.
- * Functions are converted to pointers to functions.
- * Lvalues are converted to rvalues.
- */
-tnode_t *
-cconv(tnode_t *tn)
-{
- type_t *tp;
-
- /*
- * Array-lvalue (array of type T) is converted into rvalue
- * (pointer to type T)
- */
- if (tn->tn_type->t_tspec == ARRAY) {
- if (!tn->tn_lvalue) {
- /* operand of '%s' must be lvalue */
- /* XXX print correct operator */
- (void)gnuism(114, "", modtab[AMPER].m_name);
- }
- tn = mktnode(AMPER, tincref(tn->tn_type->t_subt, PTR),
- tn, NULL);
- }
-
- /*
- * Expression of type function (function with return value of type T)
- * in rvalue-expression (pointer to function with return value
- * of type T)
- */
- if (tn->tn_type->t_tspec == FUNC)
- tn = bldamper(tn, 1);
-
- /* lvalue to rvalue */
- if (tn->tn_lvalue) {
- tp = tduptyp(tn->tn_type);
- tp->t_const = tp->t_volatile = 0;
- tn = mktnode(LOAD, tp, tn, NULL);
- }
-
- return (tn);
-}
-
-/*
- * Perform most type checks. First the types are checked using
- * information from modtab[]. After that it is done by hand for
- * more complicated operators and type combinations.
- *
- * If the types are ok, typeok() returns 1, otherwise 0.
- */
-int
-typeok(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
-{
- mod_t *mp;
- tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC,
- olt = NOTSPEC, ort = NOTSPEC;
- type_t *ltp, *rtp, *lstp, *rstp;
- tnode_t *tn;
-
- mp = &modtab[op];
-
- if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
- lst = (lstp = ltp->t_subt)->t_tspec;
- if (mp->m_binary) {
- if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
- rst = (rstp = rtp->t_subt)->t_tspec;
- }
-
- if (mp->m_rqint) {
- if (op == COMPL && iscomplex(lt)) {
- /* use of '~' for complex conjugation is a GNUism */
- } else
- /* integer types required */
- if (!isityp(lt) || (mp->m_binary && !isityp(rt))) {
- incompat(op, lt, rt);
- return (0);
- }
- } else if (mp->m_rqsclt) {
- /* scalar types required */
- if (!issclt(lt) || (mp->m_binary && !issclt(rt))) {
- incompat(op, lt, rt);
- return (0);
- }
- } else if (mp->m_rqatyp) {
- /* arithmetic types required */
- if (!isatyp(lt) || (mp->m_binary && !isatyp(rt))) {
- incompat(op, lt, rt);
- return (0);
- }
- }
-
- if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) {
- /*
- * For these operations we need the types before promotion
- * and balancing.
- */
- for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) ;
- olt = tn->tn_type->t_tspec;
- for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) ;
- ort = tn->tn_type->t_tspec;
- }
-
- switch (op) {
- case POINT:
- /*
- * Most errors required by ANSI C are reported in strmemb().
- * Here we only must check for totally wrong things.
- */
- if (lt == FUNC || lt == VOID || ltp->t_isfield ||
- ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) {
- /* we already have an error from strmemb() */
- return (0);
- }
- /* Now we have an object we can create a pointer to */
- break;
- case ARROW:
- if (lt != PTR) {
- /* we already have an error from strmemb() */
- return (0);
- }
- break;
- case INCAFT:
- case DECAFT:
- case INCBEF:
- case DECBEF:
- /* operands have scalar types (checked above) */
- if (!ln->tn_lvalue) {
- if (ln->tn_op == CVT && ln->tn_cast &&
- ln->tn_left->tn_op == LOAD) {
- /* a cast does not yield an lvalue */
- error(163);
- }
- /* %soperand of %s must be lvalue */
- error(114, "", mp->m_name);
- return (0);
- } else if (ltp->t_const) {
- /* %soperand of %s must be modifiable lvalue */
- warning(115, "", mp->m_name);
- }
- break;
- case AMPER:
- if (lt == ARRAY || lt == FUNC) {
- /* ok, a warning comes later (in bldamper()) */
- } else if (!ln->tn_lvalue) {
- if (ln->tn_op == CVT && ln->tn_cast &&
- ln->tn_left->tn_op == LOAD) {
- /* a cast does not yield an lvalue */
- error(163);
- }
- /* %soperand of %s must be lvalue */
- error(114, "", mp->m_name);
- return (0);
- } else if (issclt(lt)) {
- if (ltp->t_isfield) {
- /* cannot take address of bit-field */
- error(112);
- return (0);
- }
- } else if (lt != STRUCT && lt != UNION) {
- /* unacceptable operand of %s */
- error(111, mp->m_name);
- return (0);
- }
- if (ln->tn_op == NAME && ln->tn_sym->s_reg) {
- /* cannot take address of register %s */
- error(113, ln->tn_sym->s_name);
- return (0);
- }
- break;
- case STAR:
- /* until now there were no type checks for this operator */
- if (lt != PTR) {
- /* cannot dereference non-pointer type */
- error(96);
- return (0);
- }
- break;
- case PLUS:
- /* operands have scalar types (checked above) */
- if ((lt == PTR && !isityp(rt)) || (rt == PTR && !isityp(lt))) {
- incompat(op, lt, rt);
- return (0);
- }
- break;
- case MINUS:
- /* operands have scalar types (checked above) */
- if (lt == PTR && (!isityp(rt) && rt != PTR)) {
- incompat(op, lt, rt);
- return (0);
- } else if (rt == PTR && lt != PTR) {
- incompat(op, lt, rt);
- return (0);
- }
- if (lt == PTR && rt == PTR) {
- if (!eqtype(lstp, rstp, 1, 0, NULL)) {
- /* illegal pointer subtraction */
- error(116);
- }
- }
- break;
- case SHR:
- /* operands have integer types (checked above) */
- if (pflag && !isutyp(lt)) {
- /*
- * The left operand is signed. This means that
- * the operation is (possibly) nonportable.
- */
- /* bitwise operation on signed value nonportable */
- if (ln->tn_op != CON) {
- /* possibly nonportable */
- warning(117);
- } else if (ln->tn_val->v_quad < 0) {
- warning(120);
- }
- } else if (!sflag && !isutyp(olt) && isutyp(ort)) {
- /*
- * The left operand would become unsigned in
- * traditional C.
- */
- if (hflag &&
- (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
- /* semantics of %s change in ANSI C; use ... */
- warning(118, mp->m_name);
- }
- } else if (!sflag && !isutyp(olt) && !isutyp(ort) &&
- psize(lt) < psize(rt)) {
- /*
- * In traditional C the left operand would be extended,
- * possibly with 1, and then shifted.
- */
- if (hflag &&
- (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
- /* semantics of %s change in ANSI C; use ... */
- warning(118, mp->m_name);
- }
- }
-
- /* right shift of %d-bit quantity by %lld bits */
- if (rn->tn_op == CON && size(olt) <= rn->tn_val->v_quad)
- warning(310, size(olt), rn->tn_val->v_quad);
-
- goto shift;
- case SHL:
- /*
- * ANSI C does not perform balancing for shift operations,
- * but traditional C does. If the width of the right operand
- * is greather than the width of the left operand, than in
- * traditional C the left operand would be extended to the
- * width of the right operand. For SHL this may result in
- * different results.
- */
- if (psize(lt) < psize(rt)) {
- /*
- * XXX If both operands are constant make sure
- * that there is really a difference between
- * ANSI C and traditional C.
- */
- if (hflag)
- /* semantics of %s change in ANSI C; use ... */
- warning(118, mp->m_name);
- }
- shift:
- if (rn->tn_op == CON) {
- if (!isutyp(rt) && rn->tn_val->v_quad < 0) {
- /* negative shift */
- warning(121);
- } else if ((u_quad_t)rn->tn_val->v_quad == size(lt)) {
- /* shift equal to size of object */
- warning(267);
- } else if ((u_quad_t)rn->tn_val->v_quad > size(lt)) {
- /* shift greater than size of object */
- warning(122);
- }
- }
- break;
- case EQ:
- case NE:
- /*
- * Accept some things which are allowed with EQ and NE,
- * but not with ordered comparisons.
- */
- if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
- if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
- break;
- }
- if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) {
- if (ln->tn_op == CON && ln->tn_val->v_quad == 0)
- break;
- }
- /* FALLTHROUGH */
- case LT:
- case GT:
- case LE:
- case GE:
- if ((lt == PTR || rt == PTR) && lt != rt) {
- if (isityp(lt) || isityp(rt)) {
- /* illegal comb. of pointer and int., op %s */
- warning(123, mp->m_name);
- } else {
- incompat(op, lt, rt);
- return (0);
- }
- } else if (lt == PTR && rt == PTR) {
- ptrcmpok(op, ln, rn);
- }
- break;
- case QUEST:
- if (!issclt(lt)) {
- /* first operand must have scalar type, op ? : */
- error(170);
- return (0);
- }
- if (rn->tn_op != COLON)
- lerror("typeok() 2");
- break;
- case COLON:
-
- if (isatyp(lt) && isatyp(rt))
- break;
-
- if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str)
- break;
- if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str)
- break;
-
- /* combination of any pointer and 0, 0L or (void *)0 is ok */
- if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
- if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
- break;
- }
- if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) {
- if (ln->tn_op == CON && ln->tn_val->v_quad == 0)
- break;
- }
-
- if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) {
- /* illegal comb. of ptr. and int., op %s */
- warning(123, mp->m_name);
- break;
- }
-
- if (lt == VOID || rt == VOID) {
- if (lt != VOID || rt != VOID)
- /* incompatible types in conditional */
- warning(126);
- break;
- }
-
- if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) ||
- (lst == FUNC && rst == VOID))) {
- /* (void *)0 handled above */
- if (sflag)
- /* ANSI C forbids conv. of %s to %s, op %s */
- warning(305, "function pointer", "'void *'",
- mp->m_name);
- break;
- }
-
- if (rt == PTR && lt == PTR) {
- if (!eqtype(lstp, rstp, 1, 0, NULL))
- illptrc(mp, ltp, rtp);
- break;
- }
-
- /* incompatible types in conditional */
- error(126);
- return (0);
-
- case ASSIGN:
- case INIT:
- case FARG:
- case RETURN:
- if (!asgntypok(op, farg, ln, rn))
- return (0);
- goto assign;
- case MULASS:
- case DIVASS:
- case MODASS:
- goto assign;
- case ADDASS:
- case SUBASS:
- /* operands have scalar types (checked above) */
- if ((lt == PTR && !isityp(rt)) || rt == PTR) {
- incompat(op, lt, rt);
- return (0);
- }
- goto assign;
- case SHLASS:
- goto assign;
- case SHRASS:
- if (pflag && !isutyp(lt)) {
- /* bitwise operation on s.v. possibly nonportable */
- warning(117);
- }
-
- /* right shift of %d-bit quantity by %d bits */
- if (rn->tn_op == CON && size(olt) <= rn->tn_val->v_quad)
- warning(310, size(olt), rn->tn_val->v_quad);
-
- goto assign;
- case ANDASS:
- case XORASS:
- case ORASS:
- goto assign;
- assign:
- if (!ln->tn_lvalue) {
- if (ln->tn_op == CVT && ln->tn_cast &&
- ln->tn_left->tn_op == LOAD) {
- /* a cast does not yield an lvalue */
- error(163);
- }
- /* %soperand of %s must be lvalue */
- error(114, "left ", mp->m_name);
- return (0);
- } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) &&
- conmemb(ltp))) {
- /* %soperand of %s must be modifiable lvalue */
- warning(115, "left ", mp->m_name);
- }
- break;
- case COMMA:
- if (!modtab[ln->tn_op].m_sideeff)
- nulleff(ln);
- break;
- /* LINTED (enumeration values not handled in switch) */
- }
-
- if (mp->m_badeop &&
- (ltp->t_isenum || (mp->m_binary && rtp->t_isenum))) {
- chkbeop(op, ln, rn);
- } else if (mp->m_enumop && (ltp->t_isenum && rtp->t_isenum)) {
- chkeop2(op, farg, ln, rn);
- } else if (mp->m_enumop && (ltp->t_isenum || rtp->t_isenum)) {
- chkeop1(op, farg, ln, rn);
- }
-
- return (1);
-}
-
-static void
-ptrcmpok(op_t op, tnode_t *ln, tnode_t *rn)
-{
- type_t *ltp, *rtp;
- tspec_t lt, rt;
- const char *lts, *rts;
-
- lt = (ltp = ln->tn_type)->t_subt->t_tspec;
- rt = (rtp = rn->tn_type)->t_subt->t_tspec;
-
- if (lt == VOID || rt == VOID) {
- if (sflag && (lt == FUNC || rt == FUNC)) {
- /* (void *)0 already handled in typeok() */
- *(lt == FUNC ? &lts : &rts) = "function pointer";
- *(lt == VOID ? &lts : &rts) = "'void *'";
- /* ANSI C forbids comparison of %s with %s */
- warning(274, lts, rts);
- }
- return;
- }
-
- if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) {
- illptrc(&modtab[op], ltp, rtp);
- return;
- }
-
- if (lt == FUNC && rt == FUNC) {
- if (sflag && op != EQ && op != NE)
- /* ANSI C forbids ordered comp. of func ptr */
- warning(125);
- }
-}
-
-/*
- * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
- * and prints warnings/errors if necessary.
- * If the types are (almost) compatible, 1 is returned, otherwise 0.
- */
-static int
-asgntypok(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
-{
- tspec_t lt, rt, lst = NOTSPEC, rst = NOTSPEC;
- type_t *ltp, *rtp, *lstp, *rstp;
- mod_t *mp;
- const char *lts, *rts;
- int arg = (farg) ? farg->fa_num : 0;
-
- if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
- lst = (lstp = ltp->t_subt)->t_tspec;
- if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
- rst = (rstp = rtp->t_subt)->t_tspec;
- mp = &modtab[op];
-
- /* be picky about conversion of function return types */
- if (rn->tn_op == CALL) {
- if (size(lt) < size(rt) ||
- (size(lt) == size(rt) && isutyp(lt) && !isutyp(rt))) {
- warning(313, funcname(rn),
- tyname(rn->tn_type), tyname(ln->tn_type));
- }
- }
-
- if (isatyp(lt) && isatyp(rt))
- return (1);
-
- if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION))
- /* both are struct or union */
- return (ltp->t_str == rtp->t_str);
-
- /* 0, 0L and (void *)0 may be assigned to any pointer */
- if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
- if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
- return (1);
- }
-
- if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) {
- /* two pointers, at least one pointer to void */
- if (sflag && (lst == FUNC || rst == FUNC)) {
- /* comb. of ptr to func and ptr to void */
- *(lst == FUNC ? &lts : &rts) = "function pointer";
- *(lst == VOID ? &lts : &rts) = "'void *'";
- switch (op) {
- case INIT:
- case RETURN:
- /* ANSI C forbids conversion of %s to %s */
- warning(303, rts, lts);
- break;
- case FARG:
- /* ANSI C forbids conv. of %s to %s, arg #%d */
- warning(304, rts, lts, arg);
- break;
- default:
- /* ANSI C forbids conv. of %s to %s, op %s */
- warning(305, rts, lts, mp->m_name);
- break;
- }
- }
- }
-
- if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
- eqtype(lstp, rstp, 1, 0, NULL))) {
- /* compatible pointer types (qualifiers ignored) */
- if (((!lstp->t_const && rstp->t_const) ||
- (!lstp->t_volatile && rstp->t_volatile))) {
- /* left side has not all qualifiers of right */
- switch (op) {
- case INIT:
- case RETURN:
- /* incompatible pointer types */
- warning(182);
- break;
- case FARG:
- /* %s arg #%d: incompatible ptr. type */
- warning(153, funcname(farg->fa_func), arg);
- break;
- default:
- /* operands have incompat. ptr. types, op %s */
- warning(128, mp->m_name);
- break;
- }
- }
- return (1);
- }
-
- if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) {
- switch (op) {
- case INIT:
- case RETURN:
- /* illegal combination of pointer and integer */
- warning(183);
- break;
- case FARG:
- /* %s arg #%d: illegal comb. of ptr. and int. */
- warning(154, funcname(farg->fa_func), arg);
- break;
- default:
- /* illegal comb. of ptr. and int., op %s */
- warning(123, mp->m_name);
- break;
- }
- return (1);
- }
-
- if (lt == PTR && rt == PTR) {
- switch (op) {
- case INIT:
- case RETURN:
- illptrc(NULL, ltp, rtp);
- break;
- case FARG:
- /* %s arg #%d: incompatible pointer type */
- warning(153, funcname(farg->fa_func), arg);
- break;
- default:
- illptrc(mp, ltp, rtp);
- break;
- }
- return (1);
- }
-
- switch (op) {
- case INIT:
- /* initialisation type mismatch */
- error(185);
- break;
- case RETURN:
- /* return value type mismatch */
- error(211);
- break;
- case FARG:
- /* %s arg #%d: argument is incompatible with prototype */
- warning(155, funcname(farg->fa_func), arg);
- break;
- default:
- incompat(op, lt, rt);
- break;
- }
-
- return (0);
-}
-
-/*
- * Prints a warning if an operator, which should be senseless for an
- * enum type, is applied to an enum type.
- */
-static void
-chkbeop(op_t op, tnode_t *ln, tnode_t *rn)
-{
- mod_t *mp;
-
- if (!eflag)
- return;
-
- mp = &modtab[op];
-
- if (!(ln->tn_type->t_isenum ||
- (mp->m_binary && rn->tn_type->t_isenum))) {
- return;
- }
-
- /*
- * Enum as offset to a pointer is an exception (otherwise enums
- * could not be used as array indizes).
- */
- if (op == PLUS &&
- ((ln->tn_type->t_isenum && rn->tn_type->t_tspec == PTR) ||
- (rn->tn_type->t_isenum && ln->tn_type->t_tspec == PTR))) {
- return;
- }
-
- /* dubious operation on enum, op %s */
- warning(241, mp->m_name);
-
-}
-
-/*
- * Prints a warning if an operator is applied to two different enum types.
- */
-static void
-chkeop2(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
-{
- mod_t *mp;
- int arg = (farg) ? farg->fa_num : 0;
-
- mp = &modtab[op];
-
- if (ln->tn_type->t_enum != rn->tn_type->t_enum) {
- switch (op) {
- case INIT:
- /* enum type mismatch in initialisation */
- warning(210);
- break;
- case FARG:
- /* %s arg #%d: enum type mismatch */
- warning(156, funcname(farg->fa_func), arg);
- break;
- case RETURN:
- /* return value type mismatch */
- warning(211);
- break;
- default:
- /* enum type mismatch, op %s */
- warning(130, mp->m_name);
- break;
- }
-#if 0
- } else if (mp->m_comp && op != EQ && op != NE) {
- if (eflag)
- /* dubious comparisons of enums */
- warning(243, mp->m_name);
-#endif
- }
-}
-
-/*
- * Prints a warning if an operator has both enum end other integer
- * types.
- */
-static void
-chkeop1(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn)
-{
- int arg = (farg) ? farg->fa_num : 0;
-
- if (!eflag)
- return;
-
- switch (op) {
- case INIT:
- /*
- * Initializations with 0 should be allowed. Otherwise,
- * we should complain about all uninitialized enums,
- * consequently.
- */
- if (!rn->tn_type->t_isenum && rn->tn_op == CON &&
- isityp(rn->tn_type->t_tspec) && rn->tn_val->v_quad == 0) {
- return;
- }
- /* initialisation of '%s' with '%s' */
- warning(277, tyname(ln->tn_type), tyname(rn->tn_type));
- break;
- case FARG:
- /* %s arg #%d: combination of '%s' and '%s' */
- warning(278, funcname(farg->fa_func), arg, tyname(ln->tn_type), tyname(rn->tn_type));
- break;
- case RETURN:
- /* combination of '%s' and '%s' in return */
- warning(279, tyname(ln->tn_type), tyname(rn->tn_type));
- break;
- default:
- /* combination of '%s' and %s, op %s */
- warning(242, tyname(ln->tn_type), tyname(rn->tn_type),
- modtab[op].m_name);
- break;
- }
-}
-
-/*
- * Build and initialize a new node.
- */
-static tnode_t *
-mktnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn)
-{
- tnode_t *ntn;
- tspec_t t;
-
- ntn = getnode();
-
- ntn->tn_op = op;
- ntn->tn_type = type;
- ntn->tn_left = ln;
- ntn->tn_right = rn;
-
- if (op == STAR || op == FSEL) {
- if (ln->tn_type->t_tspec == PTR) {
- t = ln->tn_type->t_subt->t_tspec;
- if (t != FUNC && t != VOID)
- ntn->tn_lvalue = 1;
- } else {
- lerror("mktnode() 2");
- }
- } else if (op == REAL || op == IMAG) {
- ntn->tn_lvalue = ln->tn_lvalue;
- }
-
- return (ntn);
-}
-
-/*
- * Performs usual conversion of operands to (unsigned) int.
- *
- * If the operand is a function argument with no type information
- * (no prototype or variable # of args), convert float to double.
- */
-tnode_t *
-promote(op_t op, int farg, tnode_t *tn)
-{
- tspec_t t;
- type_t *ntp;
- int len;
-
- t = tn->tn_type->t_tspec;
-
- if (!isatyp(t))
- return (tn);
-
- /*
- * ANSI C requires that the result is always of type INT
- * if INT can represent all possible values of the previous
- * type (it is "value preserving" rather than "sign
- * preserving").
- *
- * XXX: Adjust value-preserving rules for longs and long
- * longs, too.
- */
- if (tn->tn_type->t_isfield) {
- len = tn->tn_type->t_flen;
- if (size(INT) > len) {
- t = INT;
- } else {
- if (size(INT) != len)
- lerror("promote() 1");
- if (isutyp(t)) {
- t = UINT;
- } else {
- t = INT;
- }
- }
- } else if (t == CHAR || t == UCHAR || t == SCHAR) {
- t = (size(CHAR) < size(INT) || t != UCHAR) ?
- INT : UINT;
- } else if (t == SHORT || t == USHORT) {
- t = (size(SHORT) < size(INT) || t == SHORT) ?
- INT : UINT;
- } else if (t == ENUM) {
- t = INT;
- } else if (farg && t == FLOAT) {
- t = DOUBLE;
- }
-
- if (t != tn->tn_type->t_tspec) {
- ntp = tduptyp(tn->tn_type);
- ntp->t_tspec = t;
- /*
- * Keep t_isenum so we are later able to check compatibility
- * of enum types.
- */
- tn = convert(op, NULL, ntp, tn);
- }
-
- return (tn);
-}
-
-/*
- * Insert conversions which are necessary to give both operands the same
- * type. This is done in different ways for traditional C and ANSI C.
- */
-static void
-balance(op_t op, tnode_t **lnp, tnode_t **rnp)
-{
- tspec_t lt, rt, t;
- int i;
- type_t *ntp;
- static tspec_t tl[] = {
- LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT,
- };
-
- lt = (*lnp)->tn_type->t_tspec;
- rt = (*rnp)->tn_type->t_tspec;
-
- if (!isatyp(lt) || !isatyp(rt))
- return;
-
- if (lt == rt) {
- t = lt;
- } else if (lt == LDOUBLE || rt == LDOUBLE) {
- t = LDOUBLE;
- } else if (lt == DOUBLE || rt == DOUBLE) {
- t = DOUBLE;
- } else if (lt == FLOAT || rt == FLOAT) {
- t = FLOAT;
- } else {
- /*
- * If type A has more bits than type B it should
- * be able to hold all possible values of type B.
- */
- if (size(lt) > size(rt)) {
- t = lt;
- } else if (size(lt) < size(rt)) {
- t = rt;
- } else {
- for (i = 3; tl[i] != INT; i++) {
- if (tl[i] == lt || tl[i] == rt)
- break;
- }
- if ((isutyp(lt) || isutyp(rt)) &&
- !isutyp(tl[i])) {
- i--;
- }
- t = tl[i];
- }
- }
-
- if (t != lt) {
- ntp = tduptyp((*lnp)->tn_type);
- ntp->t_tspec = t;
- *lnp = convert(op, NULL, ntp, *lnp);
- }
- if (t != rt) {
- ntp = tduptyp((*rnp)->tn_type);
- ntp->t_tspec = t;
- *rnp = convert(op, NULL, ntp, *rnp);
- }
-}
-
-/*
- * Insert a conversion operator, which converts the type of the node
- * to another given type.
- * If op is FARG, farg contains the passed argument information.
- */
-tnode_t *
-convert(op_t op, farg_t *farg, type_t *tp, tnode_t *tn)
-{
- tnode_t *ntn;
- tspec_t nt, ot, ost = NOTSPEC;
- int arg = (farg) ? farg->fa_num : 0;
-
- if (tn->tn_lvalue)
- lerror("convert() 1");
-
- nt = tp->t_tspec;
- if ((ot = tn->tn_type->t_tspec) == PTR)
- ost = tn->tn_type->t_subt->t_tspec;
-
- if (op == FARG)
- nt = fcnconv(farg, nt, ot, tp, tn);
-
- if (isityp(nt) && isityp(ot)) {
- iiconv(op, farg, nt, ot, tp, tn);
- } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) &&
- tn->tn_op == CON && tn->tn_val->v_quad == 0) {
- /* 0, 0L and (void *)0 may be assigned to any pointer. */
- } else if (isityp(nt) && ot == PTR) {
- piconv(op, nt, tp, tn);
- } else if (nt == PTR && ot == PTR) {
- ppconv(op, tn, tp);
- } else if (isftyp(ot) && !isftyp(nt)) {
- /* conversion from floating point to fixed point */
- if (tn->tn_op == CON) {
- /* ok. cvtcon() warns if constant out of range */
- } else {
- if (op == FARG)
- /* %s arg #%d: converted from '%s' to '%s' */
- warning(259, funcname(farg->fa_func), arg,
- tyname(tn->tn_type), tyname(tp));
- else
- warning(132, tyname(tn->tn_type),
- tyname(tp));
- }
- }
-
- ntn = getnode();
- ntn->tn_op = CVT;
- ntn->tn_type = tp;
- ntn->tn_cast = op == CVT;
- if (tn->tn_op != CON || nt == VOID) {
- ntn->tn_left = tn;
- } else {
- ntn->tn_op = CON;
- ntn->tn_val = tgetblk(sizeof (val_t));
- cvtcon(op, farg, ntn->tn_type, ntn->tn_val, tn->tn_val);
- }
-
- return (ntn);
-}
-
-/*
- * Print warnings for conversions of function call arguments. Conversions
- * happen differently between standard C and traditional C, and also happen
- * differently in standard C depending on whether a prototype is present.
- *
- * Errors/Warnings about illegal type combinations are already printed
- * in asgntypok().
- */
-static tspec_t
-fcnconv(farg_t *farg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn)
-{
- tnode_t *ptn;
- type_t *fcn = farg->fa_func->tn_type->t_subt;
- tspec_t pt;
- int arg = farg->fa_num;
-
- /* In standard C, if the function call is governed by a prototype,
- * the arguments don't necessarily undergo the usual argument conversions
- * before the call. They can be converted directly to the type of the
- * formal parameter, without necessarily widening/narrowing.
- */
- if (fcn->t_proto || !isatyp(nt) || !isatyp(ot))
- return nt;
-
- /* get default promotion */
- ptn = promote(NOOP, 1, tn);
- pt = ptn->tn_type->t_tspec;
-
- /*
- * If the type of the formal parameter is char/short, a warning
- * would be useless, because functions declared the old style
- * can't expect char/short arguments.
- */
- if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT)
- return pt;
-
- /* return if types are the same with and without promotion */
- if (nt == pt || (nt == ENUM && pt == INT))
- return pt;
-
- if (isftyp(nt) != isftyp(pt) || psize(nt) != psize(pt)) {
- /* representation and/or width change */
- if (styp(nt) != SHORT || !isityp(pt) || psize(pt) > psize(INT)) {
- if (ptn->tn_op == CON) {
- /* ok. promote() warns if constant out of range */
- } else {
- /* %s arg #%d: converted from '%s' to '%s' */
- warning(259, funcname(farg->fa_func), arg,
- tyname(tn->tn_type), tyname(tp));
- }
- }
- } else if (hflag) {
- /*
- * they differ in sign or base type (char, short, int,
- * long, long long, float, double, long double)
- *
- * if they differ only in sign and the argument is a constant
- * and the msb of the argument is not set, print no warning
- */
- if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(pt) &&
- msb(ptn->tn_val->v_quad, ot, -1) == 0) {
- /* ok */
- } else if (ptn->tn_op != CON) {
- /* %s arg #%d: converted from '%s' to '%s' */
- warning(259, funcname(farg->fa_func), arg,
- tyname(tn->tn_type), tyname(tp));
- }
- }
-
- return pt;
-}
-
-/*
- * Print warnings for conversions of integer types which may cause
- * problems.
- */
-/* ARGSUSED */
-static void
-iiconv(op_t op, farg_t *farg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn)
-{
- int arg = (farg) ? farg->fa_num : 0;
-
- if (tn->tn_op == CON)
- return;
-
- if (op == CVT)
- return;
-
- /* logical ops return int, so silently convert int to _Bool */
- if (ot == INT && nt == BOOL)
- return;
-
- if (rank(nt) < rank(ot)) {
- /* coercion from greater to lesser width */
- if (op == FARG) {
- warning(259, funcname(farg->fa_func), arg,
- tyname(tn->tn_type), tyname(tp));
- } else {
- warning(132, tyname(tn->tn_type), tyname(tp));
- }
- } else if (!isutyp(ot) && isutyp(nt)) {
- /* signed to unsigned conversion */
- if (op == FARG) {
- warning(259, funcname(farg->fa_func), arg,
- tyname(tn->tn_type), tyname(tp));
- } else {
- warning(132, tyname(tn->tn_type), tyname(tp));
- }
- } else if (isutyp(ot) && !isutyp(nt) && rank(nt) == rank(ot)) {
- /* signed to unsigned conversion */
- if (op == FARG) {
- warning(259, funcname(farg->fa_func), arg,
- tyname(tn->tn_type), tyname(tp));
- } else {
- warning(132, tyname(tn->tn_type), tyname(tp));
- }
- }
-}
-
-/*
- * Print warnings for dubious conversions of pointer to integer.
- */
-static void
-piconv(op_t op, tspec_t nt, type_t *tp, tnode_t *tn)
-{
- if (tn->tn_op == CON)
- return;
-
- if (op != CVT) {
- /* We already have an error. */
- return;
- }
-
- if (psize(nt) < psize(PTR)) {
- if (pflag && size(nt) >= size(PTR)) {
- /* conv. of pointer to %s may lose bits */
- warning(134, tyname(tp));
- } else {
- /* conv. of pointer to %s loses bits */
- warning(133, tyname(tp));
- }
- }
-}
-
-/*
- * Print warnings for questionable pointer conversions.
- */
-static void
-ppconv(op_t op, tnode_t *tn, type_t *tp)
-{
- tspec_t nt, ot;
- const char *nts, *ots;
-
- /*
- * We already have an error (pointers of different types
- * without a cast) or we will not get a warning.
- */
- if (op != CVT)
- return;
-
- nt = tp->t_subt->t_tspec;
- ot = tn->tn_type->t_subt->t_tspec;
-
- if (nt == VOID || ot == VOID) {
- if (sflag && (nt == FUNC || ot == FUNC)) {
- /* (void *)0 already handled in convert() */
- *(nt == FUNC ? &nts : &ots) = "function pointer";
- *(nt == VOID ? &nts : &ots) = "'void *'";
- /* ANSI C forbids conversion of %s to %s */
- warning(303, ots, nts);
- }
- return;
- } else if (nt == FUNC && ot == FUNC) {
- return;
- } else if (nt == FUNC || ot == FUNC) {
- /* questionable conversion of function pointer */
- warning(229);
- return;
- }
-
- if (getbound(tp->t_subt) > getbound(tn->tn_type->t_subt)) {
- if (hflag)
- /* possible pointer alignment problem */
- warning(135);
- }
- if (((nt == STRUCT || nt == UNION) &&
- tp->t_subt->t_str != tn->tn_type->t_subt->t_str) ||
- (psize(nt) != CHAR_BIT && psize(nt) != psize(ot))) {
- if (cflag) {
- /* pointer casts may be troublesome */
- warning(247);
- }
- }
-}
-
-/*
- * Converts a typed constant to a constant of another type.
- *
- * op operator which requires conversion
- * farg if op is FARG, the passed argument info (else NULL)
- * tp type to which to convert the constant
- * nv new constant
- * v old constant
- */
-void
-cvtcon(op_t op, farg_t *farg, type_t *tp, val_t *nv, val_t *v)
-{
- tspec_t ot, nt;
- ldbl_t max = 0, min = 0;
- int sz, rchk;
- quad_t xmask, xmsk1;
- int osz, nsz, arg = (farg) ? farg->fa_num : 0;
-
- ot = v->v_tspec;
- nt = nv->v_tspec = tp->t_tspec;
- rchk = 0;
-
- if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) {
- switch (nt) {
- case BOOL:
- max = 1; min = 0; break;
- case CHAR:
- max = CHAR_MAX; min = CHAR_MIN; break;
- case UCHAR:
- max = UCHAR_MAX; min = 0; break;
- case SCHAR:
- max = SCHAR_MAX; min = SCHAR_MIN; break;
- case SHORT:
- max = SHRT_MAX; min = SHRT_MIN; break;
- case USHORT:
- max = USHRT_MAX; min = 0; break;
- case ENUM:
- case INT:
- max = INT_MAX; min = INT_MIN; break;
- case UINT:
- max = (u_int)UINT_MAX; min = 0; break;
- case LONG:
- max = LONG_MAX; min = LONG_MIN; break;
- case ULONG:
- max = (u_long)ULONG_MAX; min = 0; break;
- case QUAD:
- max = QUAD_MAX; min = QUAD_MIN; break;
- case UQUAD:
- max = (u_quad_t)UQUAD_MAX; min = 0; break;
- case FLOAT:
- max = FLT_MAX; min = -FLT_MAX; break;
- case DOUBLE:
- max = DBL_MAX; min = -DBL_MAX; break;
- case PTR:
- /* Already an error because of float --> ptr */
- case LDOUBLE:
- max = LDBL_MAX; min = -LDBL_MAX; break;
- case COMPLEX:
- max = FLT_MAX; min = -FLT_MAX; break;
- case DCOMPLEX:
- max = DBL_MAX; min = -DBL_MAX; break;
- case LDCOMPLEX:
- max = LDBL_MAX; min = -LDBL_MAX; break;
- case IMAGINARY:
- case DIMAGINARY:
- case LDIMAGINARY:
- max = 0; min = 0; break;
- default:
- lerror("cvtcon() 1");
- }
- if (v->v_ldbl > max || v->v_ldbl < min) {
- if (nt == LDOUBLE || nt == LDCOMPLEX)
- lerror("cvtcon() 2");
- if (op == FARG) {
- /* %s arg #%d: conv. of %s to %s is out of range */
- warning(295, funcname(farg->fa_func), arg,
- tyname(gettyp(ot)), tyname(tp));
- } else {
- /* conversion of %s to %s is out of range */
- warning(119, tyname(gettyp(ot)), tyname(tp));
- }
- v->v_ldbl = v->v_ldbl > 0 ? max : min;
- }
- if (nt == FLOAT) {
- nv->v_ldbl = (float)v->v_ldbl;
- } else if (nt == DOUBLE) {
- nv->v_ldbl = (double)v->v_ldbl;
- } else if (nt == LDOUBLE) {
- nv->v_ldbl = v->v_ldbl;
- } else {
- nv->v_quad = (nt == PTR || isutyp(nt)) ?
- (u_quad_t)v->v_ldbl : (quad_t)v->v_ldbl;
- }
- } else {
- if (nt == FLOAT || nt == COMPLEX) {
- nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
- (float)(u_quad_t)v->v_quad : (float)v->v_quad;
- } else if (nt == DOUBLE || nt == DCOMPLEX) {
- nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
- (double)(u_quad_t)v->v_quad : (double)v->v_quad;
- } else if (nt == LDOUBLE || nt == LDCOMPLEX) {
- nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
- (ldbl_t)(u_quad_t)v->v_quad : (ldbl_t)v->v_quad;
- } else if (nt == IMAGINARY || nt == DIMAGINARY ||
- nt == LDIMAGINARY) {
- nv->v_ldbl = 0;
- } else {
- rchk = 1; /* Check for lost precision. */
- nv->v_quad = v->v_quad;
- }
- }
-
- if (v->v_ansiu && isftyp(nt)) {
- /* ANSI C treats constant as unsigned */
- warning(157);
- v->v_ansiu = 0;
- } else if (v->v_ansiu && (isityp(nt) && !isutyp(nt) &&
- psize(nt) > psize(ot))) {
- /* ANSI C treats constant as unsigned */
- warning(157);
- v->v_ansiu = 0;
- }
-
- if (nt != FLOAT && nt != DOUBLE && nt != LDOUBLE) {
- sz = tp->t_isfield ? tp->t_flen : size(nt);
- nv->v_quad = xsign(nv->v_quad, nt, sz);
- }
-
- if (rchk && op != CVT) {
- osz = size(ot);
- nsz = tp->t_isfield ? tp->t_flen : size(nt);
- xmask = qlmasks[nsz] ^ qlmasks[osz];
- xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1];
- /*
- * For bitwise operations we are not interested in the
- * value, but in the bits itself.
- */
- if (op == ORASS || op == OR || op == XOR) {
- /*
- * Print a warning if bits which were set are
- * lost due to the conversion.
- * This can happen with operator ORASS only.
- */
- if (nsz < osz && (v->v_quad & xmask) != 0) {
- /* constant truncated by conv., op %s */
- warning(306, modtab[op].m_name);
- }
- } else if (op == ANDASS || op == AND) {
- /*
- * Print a warning if additional bits are not all 1
- * and the most significant bit of the old value is 1,
- * or if at least one (but not all) removed bit was 0.
- */
- if (nsz > osz &&
- (nv->v_quad & qbmasks[osz - 1]) != 0 &&
- (nv->v_quad & xmask) != xmask) {
- /*
- * extra bits set to 0 in conversion
- * of '%s' to '%s', op %s
- */
- warning(309, tyname(gettyp(ot)),
- tyname(tp), modtab[op].m_name);
- } else if (nsz < osz &&
- (v->v_quad & xmask) != xmask &&
- (v->v_quad & xmask) != 0) {
- /* const. truncated by conv., op %s */
- warning(306, modtab[op].m_name);
- }
- } else if ((nt != PTR && isutyp(nt)) &&
- (ot != PTR && !isutyp(ot)) && v->v_quad < 0) {
- if ((nt == CHAR || nt == UCHAR || nt == SCHAR) &&
- v->v_lspec == CHAR) {
- /*
- * Don't warn when assigning a character
- * literal to any kind of character (signed,
- * unsigned, or unspecified).
- */
- } else if (op == ASSIGN) {
- /* assignment of negative constant to ... */
- warning(164);
- } else if (op == INIT) {
- /* initialisation of unsigned with neg. ... */
- warning(221);
- } else if (op == FARG) {
- /* %s arg #%d: conversion of neg. const... */
- warning(296, funcname(farg->fa_func), arg);
- } else if (modtab[op].m_comp) {
- /* we get this warning already in chkcomp() */
- } else {
- /* conversion of negative constant to ... */
- warning(222);
- }
- } else if (nv->v_quad != v->v_quad && nsz <= osz &&
- (v->v_quad & xmask) != 0 &&
- (isutyp(ot) || (v->v_quad & xmsk1) != xmsk1)) {
- /*
- * Loss of significant bit(s). All truncated bits
- * of unsigned types or all truncated bits plus the
- * msb of the target for signed types are considered
- * to be significant bits. Loss of significant bits
- * means that at least on of the bits was set in an
- * unsigned type or that at least one, but not all of
- * the bits was set in an signed type.
- * Loss of significant bits means that it is not
- * possible, also not with necessary casts, to convert
- * back to the original type. A example for a
- * necessary cast is:
- * char c; int i; c = 128;
- * i = c; ** yields -128 **
- * i = (unsigned char)c; ** yields 128 **
- */
- if ((nt == CHAR || nt == UCHAR || nt == SCHAR) &&
- v->v_lspec == CHAR) {
- /*
- * Don't warn when assigning a character
- * literal to any kind of character (signed,
- * unsigned, or unspecified).
- */
- } else if (op == ASSIGN && tp->t_isfield) {
- /* precision lost in bit-field assignment */
- warning(166);
- } else if (op == ASSIGN) {
- /* constant truncated by assignment */
- warning(165);
- } else if (op == INIT && tp->t_isfield) {
- /* bit-field initializer does not fit */
- warning(180);
- } else if (op == INIT) {
- /* initializer does not fit */
- warning(178);
- } else if (op == CASE) {
- /* case label affected by conversion */
- warning(196);
- } else if (op == FARG) {
- /* %s arg #%d: conv. of %s to %s is out of rng. */
- warning(295, funcname(farg->fa_func), arg,
- tyname(gettyp(ot)), tyname(tp));
- } else {
- /* conversion of %s to %s is out of range */
- warning(119, tyname(gettyp(ot)), tyname(tp));
- }
- } else if (nv->v_quad != v->v_quad) {
- if ((nt == CHAR || nt == UCHAR || nt == SCHAR) &&
- v->v_lspec == CHAR) {
- /*
- * Don't warn when assigning a character
- * literal to any kind of character (signed,
- * unsigned, or unspecified).
- */
- } else if (op == ASSIGN && tp->t_isfield) {
- /* precision lost in bit-field assignment */
- warning(166);
- } else if (op == INIT && tp->t_isfield) {
- /* bit-field initializer out of range */
- warning(11);
- } else if (op == CASE) {
- /* case label affected by conversion */
- warning(196);
- } else if (op == FARG) {
- /* %s arg #%d: conv. of %s to %s is out of rng. */
- warning(295, funcname(farg->fa_func), arg,
- tyname(gettyp(ot)), tyname(tp));
- } else {
- /* conversion of %s to %s is out of range */
- warning(119, tyname(gettyp(ot)), tyname(tp));
- }
- }
- }
-}
-
-/*
- * Called if incompatible types were detected.
- * Prints a appropriate warning.
- */
-static void
-incompat(op_t op, tspec_t lt, tspec_t rt)
-{
- mod_t *mp;
-
- mp = &modtab[op];
-
- if (lt == VOID || (mp->m_binary && rt == VOID)) {
- /* void type illegal in expression */
- error(109);
- } else if (op == ASSIGN) {
- if ((lt == STRUCT || lt == UNION) &&
- (rt == STRUCT || rt == UNION)) {
- /* assignment of different structures */
- error(240);
- } else {
- /* assignment type mismatch */
- error(171);
- }
- } else if (mp->m_binary) {
- /* operands of %s have incompatible types */
- error(107, mp->m_name);
- } else {
- /* operand of %s has incompatible type */
- error(108, mp->m_name);
- }
-}
-
-/*
- * Called if incompatible pointer types are detected.
- * Print an appropriate warning.
- */
-static void
-illptrc(mod_t *mp, type_t *ltp, type_t *rtp)
-{
- tspec_t lt, rt;
-
- if (ltp->t_tspec != PTR || rtp->t_tspec != PTR)
- lerror("illptrc() 1");
-
- lt = ltp->t_subt->t_tspec;
- rt = rtp->t_subt->t_tspec;
-
- if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) {
- if (mp == NULL) {
- /* illegal structure pointer combination */
- warning(244);
- } else {
- /* illegal structure pointer combination, op %s */
- warning(245, mp->m_name);
- }
- } else {
- if (mp == NULL) {
- /* illegal pointer combination */
- warning(184);
- } else {
- /* illegal pointer combination, op %s */
- warning(124, mp->m_name);
- }
- }
-}
-
-/*
- * Make sure type (*tpp)->t_subt has at least the qualifiers
- * of tp1->t_subt and tp2->t_subt.
- */
-static void
-mrgqual(type_t **tpp, type_t *tp1, type_t *tp2)
-{
- if ((*tpp)->t_tspec != PTR ||
- tp1->t_tspec != PTR || tp2->t_tspec != PTR) {
- lerror("mrgqual()");
- }
-
- if ((*tpp)->t_subt->t_const ==
- (tp1->t_subt->t_const | tp2->t_subt->t_const) &&
- (*tpp)->t_subt->t_volatile ==
- (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) {
- return;
- }
-
- *tpp = tduptyp(*tpp);
- (*tpp)->t_subt = tduptyp((*tpp)->t_subt);
- (*tpp)->t_subt->t_const =
- tp1->t_subt->t_const | tp2->t_subt->t_const;
- (*tpp)->t_subt->t_volatile =
- tp1->t_subt->t_volatile | tp2->t_subt->t_volatile;
-}
-
-/*
- * Returns 1 if the given structure or union has a constant member
- * (maybe recursively).
- */
-static int
-conmemb(type_t *tp)
-{
- sym_t *m;
- tspec_t t;
-
- if ((t = tp->t_tspec) != STRUCT && t != UNION)
- lerror("conmemb()");
- for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) {
- tp = m->s_type;
- if (tp->t_const)
- return (1);
- if ((t = tp->t_tspec) == STRUCT || t == UNION) {
- if (conmemb(m->s_type))
- return (1);
- }
- }
- return (0);
-}
-
-const char *
-tyname(type_t *tp)
-{
- tspec_t t;
- const char *s;
-
- if ((t = tp->t_tspec) == INT && tp->t_isenum)
- t = ENUM;
-
- switch (t) {
- case BOOL: s = "_Bool"; break;
- case CHAR: s = "char"; break;
- case UCHAR: s = "unsigned char"; break;
- case SCHAR: s = "signed char"; break;
- case SHORT: s = "short"; break;
- case USHORT: s = "unsigned short"; break;
- case INT: s = "int"; break;
- case UINT: s = "unsigned int"; break;
- case LONG: s = "long"; break;
- case ULONG: s = "unsigned long"; break;
- case QUAD: s = "long long"; break;
- case UQUAD: s = "unsigned long long"; break;
- case FLOAT: s = "float"; break;
- case DOUBLE: s = "double"; break;
- case LDOUBLE: s = "long double"; break;
- case COMPLEX: s = "float _Complex"; break;
- case DCOMPLEX: s = "double _Complex"; break;
- case LDCOMPLEX: s = "long double _Complex"; break;
- case IMAGINARY: s = "float _Imaginary"; break;
- case DIMAGINARY: s = "double _Imaginary"; break;
- case LDIMAGINARY:s = "long double _Imaginary"; break;
- case PTR: s = "pointer"; break;
- case ENUM: s = "enum"; break;
- case STRUCT: s = "struct"; break;
- case UNION: s = "union"; break;
- case FUNC: s = "function"; break;
- case ARRAY: s = "array"; break;
- default:
- lerror("tyname()");
- }
- return (s);
-}
-
-/*
- * Create a new node for one of the operators POINT and ARROW.
- */
-static tnode_t *
-bldstr(op_t op, tnode_t *ln, tnode_t *rn)
-{
- tnode_t *ntn, *ctn;
- int nolval;
-
- if (rn->tn_op != NAME)
- lerror("bldstr() 1");
- if (rn->tn_sym->s_value.v_tspec != INT)
- lerror("bldstr() 2");
- if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU)
- lerror("bldstr() 3");
-
- /*
- * Remember if the left operand is an lvalue (structure members
- * are lvalues if and only if the structure itself is an lvalue).
- */
- nolval = op == POINT && !ln->tn_lvalue;
-
- if (op == POINT) {
- ln = bldamper(ln, 1);
- } else if (ln->tn_type->t_tspec != PTR) {
- lerror("bldstr() 4");
- ln = convert(NOOP, NULL, tincref(gettyp(VOID), PTR), ln);
- }
-
-#if PTRDIFF_IS_LONG
- ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT);
-#else
- ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT);
-#endif
-
- ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn);
- if (ln->tn_op == CON)
- ntn = fold(ntn);
-
- if (rn->tn_type->t_isfield) {
- ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL);
- } else {
- ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL);
- }
-
- if (nolval)
- ntn->tn_lvalue = 0;
-
- return (ntn);
-}
-
-/*
- * Create a node for INCAFT, INCBEF, DECAFT and DECBEF.
- */
-static tnode_t *
-bldincdec(op_t op, tnode_t *ln)
-{
- tnode_t *cn, *ntn;
-
- if (ln == NULL)
- lerror("bldincdec() 1");
-
- if (ln->tn_type->t_tspec == PTR) {
- cn = plength(ln->tn_type);
- } else {
- cn = getinode(INT, (quad_t)1);
- }
- ntn = mktnode(op, ln->tn_type, ln, cn);
-
- return (ntn);
-}
-
-/*
- * Create a tree node for the & operator
- */
-static tnode_t *
-bldamper(tnode_t *tn, int noign)
-{
- tnode_t *ntn;
- tspec_t t;
-
- if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
- /* & before array or function: ignored */
- return (tn);
- }
-
- /* eliminate &* */
- if (tn->tn_op == STAR &&
- tn->tn_left->tn_type->t_tspec == PTR &&
- tn->tn_left->tn_type->t_subt == tn->tn_type) {
- return (tn->tn_left);
- }
-
- ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL);
-
- return (ntn);
-}
-
-/*
- * Create a node for operators PLUS and MINUS.
- */
-static tnode_t *
-bldplmi(op_t op, tnode_t *ln, tnode_t *rn)
-{
- tnode_t *ntn, *ctn;
- type_t *tp;
-
- /* If pointer and integer, then pointer to the lhs. */
- if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) {
- ntn = ln;
- ln = rn;
- rn = ntn;
- }
-
- if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) {
-
- if (!isityp(rn->tn_type->t_tspec))
- lerror("bldplmi() 1");
-
- ctn = plength(ln->tn_type);
- if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
- rn = convert(NOOP, NULL, ctn->tn_type, rn);
- rn = mktnode(MULT, rn->tn_type, rn, ctn);
- if (rn->tn_left->tn_op == CON)
- rn = fold(rn);
- ntn = mktnode(op, ln->tn_type, ln, rn);
-
- } else if (rn->tn_type->t_tspec == PTR) {
-
- if (ln->tn_type->t_tspec != PTR || op != MINUS)
- lerror("bldplmi() 2");
-#if PTRDIFF_IS_LONG
- tp = gettyp(LONG);
-#else
- tp = gettyp(INT);
-#endif
- ntn = mktnode(op, tp, ln, rn);
- if (ln->tn_op == CON && rn->tn_op == CON)
- ntn = fold(ntn);
- ctn = plength(ln->tn_type);
- balance(NOOP, &ntn, &ctn);
- ntn = mktnode(DIV, tp, ntn, ctn);
-
- } else {
-
- ntn = mktnode(op, ln->tn_type, ln, rn);
-
- }
- return (ntn);
-}
-
-/*
- * Create a node for operators SHL and SHR.
- */
-static tnode_t *
-bldshft(op_t op, tnode_t *ln, tnode_t *rn)
-{
- tspec_t t;
- tnode_t *ntn;
-
- if ((t = rn->tn_type->t_tspec) != INT && t != UINT)
- rn = convert(CVT, NULL, gettyp(INT), rn);
- ntn = mktnode(op, ln->tn_type, ln, rn);
- return (ntn);
-}
-
-/*
- * Create a node for COLON.
- */
-static tnode_t *
-bldcol(tnode_t *ln, tnode_t *rn)
-{
- tspec_t lt, rt, pdt;
- type_t *rtp;
- tnode_t *ntn;
-
- lt = ln->tn_type->t_tspec;
- rt = rn->tn_type->t_tspec;
-#if PTRDIFF_IS_LONG
- pdt = LONG;
-#else
- pdt = INT;
-#endif
-
- /*
- * Arithmetic types are balanced, all other type combinations
- * still need to be handled.
- */
- if (isatyp(lt) && isatyp(rt)) {
- rtp = ln->tn_type;
- } else if (lt == VOID || rt == VOID) {
- rtp = gettyp(VOID);
- } else if (lt == STRUCT || lt == UNION) {
- /* Both types must be identical. */
- if (rt != STRUCT && rt != UNION)
- lerror("bldcol() 1");
- if (ln->tn_type->t_str != rn->tn_type->t_str)
- lerror("bldcol() 2");
- if (incompl(ln->tn_type)) {
- /* unknown operand size, op %s */
- error(138, modtab[COLON].m_name);
- return (NULL);
- }
- rtp = ln->tn_type;
- } else if (lt == PTR && isityp(rt)) {
- if (rt != pdt) {
- rn = convert(NOOP, NULL, gettyp(pdt), rn);
- rt = pdt;
- }
- rtp = ln->tn_type;
- } else if (rt == PTR && isityp(lt)) {
- if (lt != pdt) {
- ln = convert(NOOP, NULL, gettyp(pdt), ln);
- lt = pdt;
- }
- rtp = rn->tn_type;
- } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) {
- if (rt != PTR)
- lerror("bldcol() 4");
- rtp = ln->tn_type;
- mrgqual(&rtp, ln->tn_type, rn->tn_type);
- } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) {
- if (lt != PTR)
- lerror("bldcol() 5");
- rtp = rn->tn_type;
- mrgqual(&rtp, ln->tn_type, rn->tn_type);
- } else {
- if (lt != PTR || rt != PTR)
- lerror("bldcol() 6");
- /*
- * XXX For now we simply take the left type. This is
- * probably wrong, if one type contains a function prototype
- * and the other one, at the same place, only an old style
- * declaration.
- */
- rtp = ln->tn_type;
- mrgqual(&rtp, ln->tn_type, rn->tn_type);
- }
-
- ntn = mktnode(COLON, rtp, ln, rn);
-
- return (ntn);
-}
-
-/*
- * Create a node for an assignment operator (both = and op= ).
- */
-static tnode_t *
-bldasgn(op_t op, tnode_t *ln, tnode_t *rn)
-{
- tspec_t lt, rt;
- tnode_t *ntn, *ctn;
-
- if (ln == NULL || rn == NULL)
- lerror("bldasgn() 1");
-
- lt = ln->tn_type->t_tspec;
- rt = rn->tn_type->t_tspec;
-
- if ((op == ADDASS || op == SUBASS) && lt == PTR) {
- if (!isityp(rt))
- lerror("bldasgn() 2");
- ctn = plength(ln->tn_type);
- if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
- rn = convert(NOOP, NULL, ctn->tn_type, rn);
- rn = mktnode(MULT, rn->tn_type, rn, ctn);
- if (rn->tn_left->tn_op == CON)
- rn = fold(rn);
- }
-
- if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) {
- if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str)
- lerror("bldasgn() 3");
- if (incompl(ln->tn_type)) {
- if (op == RETURN) {
- /* cannot return incomplete type */
- error(212);
- } else {
- /* unknown operand size, op %s */
- error(138, modtab[op].m_name);
- }
- return (NULL);
- }
- }
-
- if (op == SHLASS || op == SHRASS) {
- if (rt != INT) {
- rn = convert(NOOP, NULL, gettyp(INT), rn);
- rt = INT;
- }
- } else {
- if (op == ASSIGN || lt != PTR) {
- if (lt != rt ||
- (ln->tn_type->t_isfield && rn->tn_op == CON)) {
- rn = convert(op, NULL, ln->tn_type, rn);
- rt = lt;
- }
- }
- }
-
- ntn = mktnode(op, ln->tn_type, ln, rn);
-
- return (ntn);
-}
-
-/*
- * Check for division by zero. Returns 1 if a division by zero is
- * present, 0 otherwise.
- */
-static int
-chkdbz(op_t op, tnode_t *rn)
-{
- int code;
-
- switch (op) {
- case DIV:
- case DIVASS:
- code = 139; /* division by 0 */
- break;
- case MOD:
- case MODASS:
- code = 140; /* modular division by 0 */
- break;
- default:
- return 0;
- }
-
- /* no way of checking unless right side is a constant */
- if (rn->tn_op != CON)
- return 0;
-
- if (isftyp(rn->tn_type->t_tspec)) {
- if (rn->tn_val->v_ldbl == 0.0) {
- /* division by 0 */
- warning(code);
- return 1;
- }
- } else {
- if (rn->tn_val->v_quad == 0) {
- /* division by 0 */
- warning(code);
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
- * Get length of type tp->t_subt.
- */
-static tnode_t *
-plength(type_t *tp)
-{
- int elem, elsz;
- tspec_t st;
-
- if (tp->t_tspec != PTR)
- lerror("plength() 1");
- tp = tp->t_subt;
-
- elem = 1;
- elsz = 0;
-
- while (tp->t_tspec == ARRAY) {
- elem *= tp->t_dim;
- tp = tp->t_subt;
- }
-
- switch (tp->t_tspec) {
- case FUNC:
- /* pointer to function is not allowed here */
- error(110);
- break;
- case VOID:
- /* cannot do pointer arithmetic on operand of ... */
- (void)gnuism(136);
- break;
- case STRUCT:
- case UNION:
- if ((elsz = tp->t_str->size) == 0)
- /* cannot do pointer arithmetic on operand of ... */
- error(136);
- break;
- case ENUM:
- if (incompl(tp)) {
- /* cannot do pointer arithmetic on operand of ... */
- warning(136);
- }
- /* FALLTHROUGH */
- default:
- if ((elsz = size(tp->t_tspec)) == 0) {
- /* cannot do pointer arithmetic on operand of ... */
- error(136);
- } else if (elsz == -1) {
- lerror("plength() 2");
- }
- break;
- }
-
- if (elem == 0 && elsz != 0) {
- /* cannot do pointer arithmetic on operand of ... */
- error(136);
- }
-
- if (elsz == 0)
- elsz = CHAR_BIT;
-
-#if PTRDIFF_IS_LONG
- st = LONG;
-#else
- st = INT;
-#endif
-
- return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
-}
-
-/*
- * Do only as much as necessary to compute constant expressions.
- * Called only if the operator allows folding and (both) operands
- * are constants.
- */
-static tnode_t *
-fold(tnode_t *tn)
-{
- val_t *v;
- tspec_t t;
- int utyp, ovfl;
- quad_t sl, sr, q, mask;
- u_quad_t ul, ur;
- tnode_t *cn;
-
- v = xcalloc(1, sizeof (val_t));
- v->v_tspec = t = tn->tn_type->t_tspec;
-
- utyp = t == PTR || isutyp(t);
- ul = sl = tn->tn_left->tn_val->v_quad;
- if (modtab[tn->tn_op].m_binary)
- ur = sr = tn->tn_right->tn_val->v_quad;
-
- ovfl = 0;
-
- switch (tn->tn_op) {
- case UPLUS:
- q = sl;
- break;
- case UMINUS:
- q = -sl;
- if (msb(q, t, -1) == msb(sl, t, -1))
- ovfl = 1;
- break;
- case COMPL:
- q = ~sl;
- break;
- case MULT:
- q = utyp ? ul * ur : sl * sr;
- if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1)))
- ovfl = 1;
- break;
- case DIV:
- if (chkdbz(tn->tn_op, tn->tn_right)) {
- q = utyp ? 0U: 0;
- } else {
- q = utyp ? ul / ur : sl / sr;
- }
- break;
- case MOD:
- if (chkdbz(tn->tn_op, tn->tn_right)) {
- q = 0;
- } else {
- q = utyp ? ul % ur : sl % sr;
- }
- break;
- case PLUS:
- q = utyp ? ul + ur : sl + sr;
- if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) {
- if (msb(q, t, -1) == 0)
- ovfl = 1;
- } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) {
- if (msb(q, t, -1) != 0)
- ovfl = 1;
- }
- break;
- case MINUS:
- q = utyp ? ul - ur : sl - sr;
- if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) {
- if (msb(q, t, -1) == 0)
- ovfl = 1;
- } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) {
- if (msb(q, t, -1) != 0)
- ovfl = 1;
- }
- break;
- case SHL:
- q = utyp ? ul << sr : sl << sr;
- break;
- case SHR:
- /*
- * The sign must be explicitly extended because
- * shifts of signed values are implementation dependent.
- */
- q = ul >> sr;
- q = xsign(q, t, size(t) - (int)sr);
- break;
- case LT:
- q = utyp ? ul < ur : sl < sr;
- break;
- case LE:
- q = utyp ? ul <= ur : sl <= sr;
- break;
- case GE:
- q = utyp ? ul >= ur : sl >= sr;
- break;
- case GT:
- q = utyp ? ul > ur : sl > sr;
- break;
- case EQ:
- q = utyp ? ul == ur : sl == sr;
- break;
- case NE:
- q = utyp ? ul != ur : sl != sr;
- break;
- case AND:
- q = utyp ? ul & ur : sl & sr;
- break;
- case XOR:
- q = utyp ? ul ^ ur : sl ^ sr;
- break;
- case OR:
- q = utyp ? ul | ur : sl | sr;
- break;
- case REAL:
- case IMAG:
- q = sl;
- default:
- lerror("fold() 5");
- }
-
- mask = qlmasks[size(t)];
-
- /* XXX does not work for quads. */
- if (ovfl || ((q | mask) != ~(u_quad_t)0 && (q & ~mask) != 0)) {
- if (hflag)
- /* integer overflow detected, op %s */
- warning(141, modtab[tn->tn_op].m_name);
- }
-
- v->v_quad = xsign(q, t, -1);
-
- cn = getcnode(tn->tn_type, v);
-
- return (cn);
-}
-
-/*
- * Same for operators whose operands are compared with 0 (test context).
- */
-static tnode_t *
-foldtst(tnode_t *tn)
-{
- int l, r;
- val_t *v;
-
- v = xcalloc(1, sizeof (val_t));
- v->v_tspec = tn->tn_type->t_tspec;
- if (tn->tn_type->t_tspec != INT)
- lerror("foldtst() 1");
-
- if (isftyp(tn->tn_left->tn_type->t_tspec)) {
- l = tn->tn_left->tn_val->v_ldbl != 0.0;
- } else {
- l = tn->tn_left->tn_val->v_quad != 0;
- }
-
- if (modtab[tn->tn_op].m_binary) {
- if (isftyp(tn->tn_right->tn_type->t_tspec)) {
- r = tn->tn_right->tn_val->v_ldbl != 0.0;
- } else {
- r = tn->tn_right->tn_val->v_quad != 0;
- }
- }
-
- switch (tn->tn_op) {
- case NOT:
- if (hflag)
- /* constant argument to NOT */
- warning(239);
- v->v_quad = !l;
- break;
- case LOGAND:
- v->v_quad = l && r;
- break;
- case LOGOR:
- v->v_quad = l || r;
- break;
- default:
- lerror("foldtst() 1");
- }
-
- return (getcnode(tn->tn_type, v));
-}
-
-/*
- * Same for operands with floating point type.
- */
-static tnode_t *
-foldflt(tnode_t *tn)
-{
- val_t *v;
- tspec_t t;
- ldbl_t l, r;
-
- v = xcalloc(1, sizeof (val_t));
- v->v_tspec = t = tn->tn_type->t_tspec;
-
- if (!isftyp(t))
- lerror("foldflt() 1");
-
- if (t != tn->tn_left->tn_type->t_tspec)
- lerror("foldflt() 2");
- if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec)
- lerror("foldflt() 3");
-
- l = tn->tn_left->tn_val->v_ldbl;
- if (modtab[tn->tn_op].m_binary)
- r = tn->tn_right->tn_val->v_ldbl;
-
- switch (tn->tn_op) {
- case UPLUS:
- v->v_ldbl = l;
- break;
- case UMINUS:
- v->v_ldbl = -l;
- break;
- case MULT:
- v->v_ldbl = l * r;
- break;
- case DIV:
- if (chkdbz(tn->tn_op, tn->tn_right)) {
- if (t == FLOAT) {
- v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX;
- } else if (t == DOUBLE) {
- v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX;
- } else {
- v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX;
- }
- } else {
- v->v_ldbl = l / r;
- }
- break;
- case PLUS:
- v->v_ldbl = l + r;
- break;
- case MINUS:
- v->v_ldbl = l - r;
- break;
- case LT:
- v->v_quad = l < r;
- break;
- case LE:
- v->v_quad = l <= r;
- break;
- case GE:
- v->v_quad = l >= r;
- break;
- case GT:
- v->v_quad = l > r;
- break;
- case EQ:
- v->v_quad = l == r;
- break;
- case NE:
- v->v_quad = l != r;
- break;
- case REAL:
- case IMAG:
- v->v_ldbl = l;
- break;
- default:
- lerror("foldflt() 4");
- }
-
- if (isnan((double)v->v_ldbl))
- lerror("foldflt() 5");
- if (isinf((double)v->v_ldbl) ||
- (t == FLOAT &&
- (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
- (t == DOUBLE &&
- (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
- /* floating point overflow detected, op %s */
- warning(142, modtab[tn->tn_op].m_name);
- if (t == FLOAT) {
- v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX;
- } else if (t == DOUBLE) {
- v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX;
- } else {
- v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX;
- }
- }
-
- return (getcnode(tn->tn_type, v));
-}
-
-/*
- * Create a constant node for sizeof(term).
- */
-tnode_t *
-bldszoftrm(tnode_t *tn)
-{
- switch (tn->tn_op) {
- case POINT:
- case STAR:
- case NAME:
- case STRING:
- case REAL:
- case IMAG:
- break;
- default:
- warning(312, modtab[tn->tn_op].m_name);
- }
-
-
- return bldszof(tn->tn_type);
-}
-
-/*
- * Create a constant node for sizeof.
- */
-tnode_t *
-bldszof(type_t *tp)
-{
- int elem, elsz;
- tspec_t st;
-
- elem = 1;
- while (tp->t_tspec == ARRAY) {
- elem *= tp->t_dim;
- tp = tp->t_subt;
- }
- if (elem == 0) {
- /* cannot take size of incomplete type */
- error(143);
- elem = 1;
- }
- switch (tp->t_tspec) {
- case FUNC:
- /* cannot take size of function */
- error(144);
- elsz = 1;
- break;
- case STRUCT:
- case UNION:
- if (incompl(tp)) {
- /* cannot take size of incomplete type */
- error(143);
- elsz = 1;
- } else {
- elsz = tp->t_str->size;
- }
- break;
- case ENUM:
- if (incompl(tp)) {
- /* cannot take size of incomplete type */
- warning(143);
- }
- /* FALLTHROUGH */
- default:
- if (tp->t_isfield) {
- /* cannot take size of bit-field */
- error(145);
- }
- if (tp->t_tspec == VOID) {
- /* cannot take size of void */
- error(146);
- elsz = 1;
- } else {
- elsz = size(tp->t_tspec);
- if (elsz <= 0)
- lerror("bldszof() 1");
- }
- break;
- }
-
-#if SIZEOF_IS_ULONG
- st = ULONG;
-#else
- st = UINT;
-#endif
-
- return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
-}
-
-/*
- * Type casts.
- */
-tnode_t *
-cast(tnode_t *tn, type_t *tp)
-{
- tspec_t nt, ot;
-
- if (tn == NULL)
- return (NULL);
-
- tn = cconv(tn);
-
- nt = tp->t_tspec;
- ot = tn->tn_type->t_tspec;
-
- if (nt == VOID) {
- /*
- * XXX ANSI C requires scalar types or void (Plauger&Brodie).
- * But this seams really questionable.
- */
- } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) {
- /* invalid cast expression */
- error(147);
- return (NULL);
- } else if (ot == STRUCT || ot == UNION) {
- /* invalid cast expression */
- error(147);
- return (NULL);
- } else if (ot == VOID) {
- /* improper cast of void expression */
- error(148);
- return (NULL);
- } else if (isityp(nt) && issclt(ot)) {
- /* ok */
- } else if (isftyp(nt) && isatyp(ot)) {
- /* ok */
- } else if (nt == PTR && isityp(ot)) {
- /* ok */
- } else if (nt == PTR && ot == PTR) {
- if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) {
- if (hflag)
- /* cast discards 'const' from ... */
- warning(275);
- }
- } else {
- /* invalid cast expression */
- error(147);
- return (NULL);
- }
-
- tn = convert(CVT, NULL, tp, tn);
- tn->tn_cast = 1;
-
- return (tn);
-}
-
-/*
- * Create the node for a function argument.
- * All necessary conversions and type checks are done in funccall(), because
- * in funcarg() we have no information about expected argument types.
- */
-tnode_t *
-funcarg(tnode_t *args, tnode_t *arg)
-{
- tnode_t *ntn;
-
- /*
- * If there was a serious error in the expression for the argument,
- * create a dummy argument so the positions of the remaining arguments
- * will not change.
- */
- if (arg == NULL)
- arg = getinode(INT, (quad_t)0);
-
- ntn = mktnode(PUSH, arg->tn_type, arg, args);
-
- return (ntn);
-}
-
-/*
- * Create the node for a function call. Also check types of
- * function arguments and insert conversions, if necessary.
- */
-tnode_t *
-funccall(tnode_t *func, tnode_t *args)
-{
- tnode_t *ntn;
- op_t fcop;
-
- if (func == NULL)
- return (NULL);
-
- if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
- fcop = CALL;
- } else {
- fcop = ICALL;
- }
-
- /*
- * after cconv() func will always be a pointer to a function
- * if it is a valid function designator.
- */
- func = cconv(func);
-
- if (func->tn_type->t_tspec != PTR ||
- func->tn_type->t_subt->t_tspec != FUNC) {
- /* illegal function */
- error(149);
- return (NULL);
- }
-
- args = chkfarg(func, args);
-
- ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args);
-
- return (ntn);
-}
-
-/*
- * Check types of all function arguments and insert conversions,
- * if necessary.
- *
- * func: called function
- * args: arguments to function
- */
-static tnode_t *
-chkfarg(tnode_t *func, tnode_t *args)
-{
- type_t *ftp;
- tnode_t *arg;
- sym_t *asym;
- farg_t farg;
- tspec_t at;
- int narg, npar, n, i;
-
- ftp = func->tn_type->t_subt;
-
- /* get # of args in the prototype */
- npar = 0;
- for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt)
- npar++;
-
- /* get # of args in function call */
- narg = 0;
- for (arg = args; arg != NULL; arg = arg->tn_right)
- narg++;
-
- asym = ftp->t_args;
- if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
- /* argument mismatch: %d arg%s passed, %d expected */
- error(150, narg, narg > 1 ? "s" : "", npar);
- asym = NULL;
- }
-
- for (n = 1; n <= narg; n++) {
-
- /*
- * The rightmost argument is at the top of the argument
- * subtree.
- */
- for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
-
- /* some things which are never allowed */
- if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
- /* void expressions may not be arguments, arg #%d */
- error(151, n);
- return (NULL);
- } else if ((at == STRUCT || at == UNION) &&
- incompl(arg->tn_left->tn_type)) {
- /* argument cannot have unknown size, arg #%d */
- error(152, n);
- return (NULL);
- } else if (isityp(at) && arg->tn_left->tn_type->t_isenum &&
- incompl(arg->tn_left->tn_type)) {
- /* argument cannot have unknown size, arg #%d */
- warning(152, n);
- }
-
- /* class conversions (arg in value context) */
- arg->tn_left = cconv(arg->tn_left);
- farg.fa_num = n;
- farg.fa_sym = asym;
- farg.fa_func = func;
- if (asym != NULL) {
- arg->tn_left = parg(&farg, arg->tn_left);
- } else {
- arg->tn_left = promote(NOOP, 1, arg->tn_left);
- }
- arg->tn_type = arg->tn_left->tn_type;
-
- if (asym != NULL)
- asym = asym->s_nxt;
- }
-
- return (args);
-}
-
-/*
- * Compare the type of an argument with the corresponding type of a
- * prototype parameter. If it is a valid combination, but both types
- * are not the same, insert a conversion to convert the argument into
- * the type of the parameter.
- *
- * n: position of arg
- * tp: expected type (from prototype)
- * tn: argument
- */
-static tnode_t *
-parg(farg_t *farg, tnode_t *tn)
-{
- tnode_t *ln;
- type_t *tp;
- int warn;
-
- tp = farg->fa_sym->s_type;
- ln = xcalloc(1, sizeof (tnode_t));
- ln->tn_type = tduptyp(tp);
- ln->tn_type->t_const = 0;
- ln->tn_lvalue = 1;
- if (typeok(FARG, farg, ln, tn)) {
- if (!eqtype(tp, tn->tn_type, 1, 0, (warn = 0, &warn)) || warn)
- tn = convert(FARG, farg, tp, tn);
- }
- free(ln);
- return (tn);
-}
-
-/*
- * Return the value of an integral constant expression.
- * If the expression is not constant or its type is not an integer
- * type, an error message is printed.
- */
-val_t *
-constant(tnode_t *tn)
-{
- val_t *v;
-
- if (tn != NULL)
- tn = cconv(tn);
- if (tn != NULL)
- tn = promote(NOOP, 0, tn);
-
- v = xcalloc(1, sizeof (val_t));
-
- if (tn == NULL) {
- if (nerr == 0)
- lerror("constant() 1");
- v->v_tspec = INT;
- v->v_quad = 1;
- return (v);
- }
-
- v->v_tspec = tn->tn_type->t_tspec;
-
- if (tn->tn_op == CON) {
- if (tn->tn_type->t_tspec != tn->tn_val->v_tspec)
- lerror("constant() 2");
- if (isityp(tn->tn_val->v_tspec)) {
- v->v_ansiu = tn->tn_val->v_ansiu;
- v->v_quad = tn->tn_val->v_quad;
- return (v);
- }
- v->v_quad = tn->tn_val->v_ldbl;
- } else {
- v->v_quad = 1;
- }
-
- /* integral constant expression expected */
- error(55);
-
- if (!isityp(v->v_tspec))
- v->v_tspec = INT;
-
- return (v);
-}
-
-/*
- * Perform some tests on expressions which can't be done in build() and
- * functions called by build(). These tests must be done here because
- * we need some information about the context in which the operations
- * are performed.
- * After all tests are performed, expr() frees the memory which is used
- * for the expression.
- */
-void
-expr(tnode_t *tn, int vctx, int tctx)
-{
- if (tn == NULL && nerr == 0)
- lerror("expr() 1");
-
- if (tn == NULL) {
- tfreeblk();
- return;
- }
-
- /* expr() is also called in global initialisations */
- if (dcs->d_ctx != EXTERN)
- chkreach();
-
- chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0);
- if (tn->tn_op == ASSIGN) {
- if (hflag && tctx && !tn->tn_parn)
- /* assignment in conditional context */
- warning(159);
- } else if (tn->tn_op == CON) {
- if (hflag && tctx && !ccflg) {
- if (!isityp(tn->tn_type->t_tspec) ||
- (tn->tn_val->v_quad != 0 &&
- tn->tn_val->v_quad != 1)) {
- /* constant in conditional context */
- warning(161);
- }
- }
- } else if (tn->tn_op == CALL && tn->tn_left->tn_op == AMPER) {
- if (tn->tn_left->tn_left->tn_sym->s_noreturn)
- reached = rchflg = 0;
- }
-
- if (!modtab[tn->tn_op].m_sideeff) {
- /*
- * for left operands of COMMA this warning is already
- * printed
- */
- if (tn->tn_op != COMMA && !vctx && !tctx)
- nulleff(tn);
- }
- if (dflag)
- displexpr(tn, 0);
-
- /* free the tree memory */
- tfreeblk();
-}
-
-static void
-nulleff(tnode_t *tn)
-{
- if (!hflag)
- return;
- if (nulleffexpr(tn)) {
- /* expression has null effect */
- warning(129);
- }
-}
-
-static int
-nulleffexpr(tnode_t *tn)
-{
- int r1, r2;
-
- if (modtab[tn->tn_op].m_sideeff)
- return (0);
-
- switch (tn->tn_op) {
- case CVT:
- if (tn->tn_type->t_tspec == VOID)
- return (0);
- else
- return (nulleffexpr(tn->tn_left));
- case LOGAND:
- case LOGOR:
- /*
- * && and || have a null effect if the right operand
- * has null effect.
- */
- return (nulleffexpr(tn->tn_right));
- case QUEST:
- /*
- * ? has null effect if both of its right * operands
- * have null effect
- */
- return (nulleffexpr(tn->tn_right));
- case COLON:
- case COMMA:
- /*
- * : and , have null effect if both of the operands have
- * null effect
- */
- r1 = nulleffexpr(tn->tn_left);
- r2 = nulleffexpr(tn->tn_right);
- return (r1 && r2);
- default:
- return (1);
- }
-}
-
-/*
- * Dump an expression to stdout
- * only used for debugging
- */
-void
-displexpr(tnode_t *tn, int offs)
-{
- u_quad_t uq;
-
- if (tn == NULL) {
- (void)printf("%*s%s\n", offs, "", "NULL");
- return;
- }
- (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name);
-
- if (tn->tn_op == NAME) {
- (void)printf("%s: %s ",
- tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl));
- } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) {
- (void)printf("%#g ", (double)tn->tn_val->v_ldbl);
- } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) {
- uq = tn->tn_val->v_quad;
- (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl,
- (long)uq & 0xffffffffl);
- } else if (tn->tn_op == CON) {
- if (tn->tn_type->t_tspec != PTR)
- lerror("displexpr() 1");
- (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4),
- (u_long)tn->tn_val->v_quad);
- } else if (tn->tn_op == STRING) {
- if (tn->tn_strg->st_tspec == CHAR) {
- (void)printf("\"%s\"", tn->tn_strg->st_cp);
- } else {
- char *s;
- size_t n;
- n = MB_CUR_MAX * (tn->tn_strg->st_len + 1);
- s = xmalloc(n);
- (void)wcstombs(s, tn->tn_strg->st_wcp, n);
- (void)printf("L\"%s\"", s);
- free(s);
- }
- (void)printf(" ");
- } else if (tn->tn_op == FSEL) {
- (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs,
- tn->tn_type->t_flen);
- }
- (void)printf("%s\n", ttos(tn->tn_type));
- if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING)
- return;
- displexpr(tn->tn_left, offs + 2);
- if (modtab[tn->tn_op].m_binary ||
- (tn->tn_op == PUSH && tn->tn_right != NULL)) {
- displexpr(tn->tn_right, offs + 2);
- }
-}
-
-/*
- * Called by expr() to recursively perform some tests.
- */
-/* ARGSUSED */
-void
-chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc,
- int szof)
-{
- tnode_t *ln, *rn;
- mod_t *mp;
- int nrvdisc, cvctx, ctctx;
- op_t op;
- scl_t sc;
- dinfo_t *di;
-
- if (tn == NULL)
- return;
-
- ln = tn->tn_left;
- rn = tn->tn_right;
- mp = &modtab[op = tn->tn_op];
-
- switch (op) {
- case AMPER:
- if (ln->tn_op == NAME && (reached || rchflg)) {
- if (!szof)
- setsflg(ln->tn_sym);
- setuflg(ln->tn_sym, fcall, szof);
- }
- if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
- /* check the range of array indices */
- chkaidx(ln->tn_left, 1);
- break;
- case LOAD:
- if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
- /* check the range of array indices */
- chkaidx(ln->tn_left, 0);
- /* FALLTHROUGH */
- case PUSH:
- case INCBEF:
- case DECBEF:
- case INCAFT:
- case DECAFT:
- case ADDASS:
- case SUBASS:
- case MULASS:
- case DIVASS:
- case MODASS:
- case ANDASS:
- case ORASS:
- case XORASS:
- case SHLASS:
- case SHRASS:
- case REAL:
- case IMAG:
- if (ln->tn_op == NAME && (reached || rchflg)) {
- sc = ln->tn_sym->s_scl;
- /*
- * Look if there was an asm statement in one of the
- * compound statements we are in. If not, we don't
- * print a warning.
- */
- for (di = dcs; di != NULL; di = di->d_nxt) {
- if (di->d_asm)
- break;
- }
- if (sc != EXTERN && sc != STATIC &&
- !ln->tn_sym->s_set && !szof && di == NULL) {
- /* %s may be used before set */
- warning(158, ln->tn_sym->s_name);
- setsflg(ln->tn_sym);
- }
- setuflg(ln->tn_sym, 0, 0);
- }
- break;
- case ASSIGN:
- if (ln->tn_op == NAME && !szof && (reached || rchflg)) {
- setsflg(ln->tn_sym);
- if (ln->tn_sym->s_scl == EXTERN)
- outusg(ln->tn_sym);
- }
- if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
- /* check the range of array indices */
- chkaidx(ln->tn_left, 0);
- break;
- case CALL:
- if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME)
- lerror("chkmisc() 1");
- if (!szof)
- outcall(tn, vctx || tctx, rvdisc);
- break;
- case EQ:
- /* equality operator "==" found where "=" was exp. */
- if (hflag && eqwarn)
- warning(160);
- break;
- case CON:
- case NAME:
- case STRING:
- return;
- /* LINTED (enumeration values not handled in switch) */
- }
-
- cvctx = mp->m_vctx;
- ctctx = mp->m_tctx;
- /*
- * values of operands of ':' are not used if the type of at least
- * one of the operands (for gcc compatibility) is void
- * XXX test/value context of QUEST should probably be used as
- * context for both operands of COLON
- */
- if (op == COLON && tn->tn_type->t_tspec == VOID)
- cvctx = ctctx = 0;
- nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID;
- chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof);
-
- switch (op) {
- case PUSH:
- if (rn != NULL)
- chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof);
- break;
- case LOGAND:
- case LOGOR:
- chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof);
- break;
- case COLON:
- chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof);
- break;
- default:
- if (mp->m_binary)
- chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof);
- break;
- }
-
-}
-
-/*
- * Checks the range of array indices, if possible.
- * amper is set if only the address of the element is used. This
- * means that the index is allowd to refer to the first element
- * after the array.
- */
-static void
-chkaidx(tnode_t *tn, int amper)
-{
- int dim;
- tnode_t *ln, *rn;
- int elsz;
- quad_t con;
-
- ln = tn->tn_left;
- rn = tn->tn_right;
-
- /* We can only check constant indices. */
- if (rn->tn_op != CON)
- return;
-
- /* Return if the left node does not stem from an array. */
- if (ln->tn_op != AMPER)
- return;
- if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
- return;
- if (ln->tn_left->tn_type->t_tspec != ARRAY)
- return;
-
- /*
- * For incomplete array types, we can print a warning only if
- * the index is negative.
- */
- if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
- return;
-
- /* Get the size of one array element */
- if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0)
- return;
- elsz /= CHAR_BIT;
-
- /* Change the unit of the index from bytes to element size. */
- if (isutyp(rn->tn_type->t_tspec)) {
- con = (u_quad_t)rn->tn_val->v_quad / elsz;
- } else {
- con = rn->tn_val->v_quad / elsz;
- }
-
- dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
-
- if (!isutyp(rn->tn_type->t_tspec) && con < 0) {
- /* array subscript cannot be negative: %ld */
- warning(167, (long)con);
- } else if (dim > 0 && (u_quad_t)con >= dim) {
- /* array subscript cannot be > %d: %ld */
- warning(168, dim - 1, (long)con);
- }
-}
-
-/*
- * Check for ordered comparisons of unsigned values with 0.
- */
-static void
-chkcomp(op_t op, tnode_t *ln, tnode_t *rn)
-{
- tspec_t lt, rt;
- mod_t *mp;
-
- lt = ln->tn_type->t_tspec;
- rt = rn->tn_type->t_tspec;
- mp = &modtab[op];
-
- if (ln->tn_op != CON && rn->tn_op != CON)
- return;
-
- if (!isityp(lt) || !isityp(rt))
- return;
-
- if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
- (rn->tn_val->v_quad < 0 ||
- rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
- /* nonportable character comparison, op %s */
- warning(230, mp->m_name);
- return;
- }
- if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
- (ln->tn_val->v_quad < 0 ||
- ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
- /* nonportable character comparison, op %s */
- warning(230, mp->m_name);
- return;
- }
- if (isutyp(lt) && !isutyp(rt) &&
- rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
- if (rn->tn_val->v_quad < 0) {
- /* comparison of %s with %s, op %s */
- warning(162, tyname(ln->tn_type), "negative constant",
- mp->m_name);
- } else if (op == LT || op == GE || (hflag && op == LE)) {
- /* comparison of %s with %s, op %s */
- warning(162, tyname(ln->tn_type), "0", mp->m_name);
- }
- return;
- }
- if (isutyp(rt) && !isutyp(lt) &&
- ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
- if (ln->tn_val->v_quad < 0) {
- /* comparison of %s with %s, op %s */
- warning(162, "negative constant", tyname(rn->tn_type),
- mp->m_name);
- } else if (op == GT || op == LE || (hflag && op == GE)) {
- /* comparison of %s with %s, op %s */
- warning(162, "0", tyname(rn->tn_type), mp->m_name);
- }
- return;
- }
-}
-
-/*
- * Takes an expression and returns 0 if this expression can be used
- * for static initialisation, otherwise -1.
- *
- * Constant initialisation expressions must be costant or an address
- * of a static object with an optional offset. In the first case,
- * the result is returned in *offsp. In the second case, the static
- * object is returned in *symp and the offset in *offsp.
- *
- * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and
- * CON. Type conversions are allowed if they do not change binary
- * representation (including width).
- */
-int
-conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp)
-{
- sym_t *sym;
- ptrdiff_t offs1, offs2;
- tspec_t t, ot;
-
- switch (tn->tn_op) {
- case MINUS:
- if (tn->tn_right->tn_op != CON)
- return (-1);
- /* FALLTHROUGH */
- case PLUS:
- offs1 = offs2 = 0;
- if (tn->tn_left->tn_op == CON) {
- offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
- if (conaddr(tn->tn_right, &sym, &offs2) == -1)
- return (-1);
- } else if (tn->tn_right->tn_op == CON) {
- offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad;
- if (tn->tn_op == MINUS)
- offs2 = -offs2;
- if (conaddr(tn->tn_left, &sym, &offs1) == -1)
- return (-1);
- } else {
- return (-1);
- }
- *symp = sym;
- *offsp = offs1 + offs2;
- break;
- case AMPER:
- if (tn->tn_left->tn_op == NAME) {
- *symp = tn->tn_left->tn_sym;
- *offsp = 0;
- } else if (tn->tn_left->tn_op == STRING) {
- /*
- * If this would be the front end of a compiler we
- * would return a label instead of 0.
- */
- *offsp = 0;
- }
- break;
- case CVT:
- t = tn->tn_type->t_tspec;
- ot = tn->tn_left->tn_type->t_tspec;
- if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) {
- return (-1);
- } else if (psize(t) != psize(ot)) {
- return (-1);
- }
- if (conaddr(tn->tn_left, symp, offsp) == -1)
- return (-1);
- break;
- default:
- return (-1);
- }
- return (0);
-}
-
-/*
- * Concatenate two string constants.
- */
-strg_t *
-catstrg(strg_t *strg1, strg_t *strg2)
-{
- size_t len1, len2, len;
-
- if (strg1->st_tspec != strg2->st_tspec) {
- /* cannot concatenate wide and regular string literals */
- error(292);
- return (strg1);
- }
-
- len = (len1 = strg1->st_len) + (len2 = strg2->st_len);
-
- if (strg1->st_tspec == CHAR) {
- strg1->st_cp = xrealloc(strg1->st_cp, len + 1);
- (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1);
- free(strg2->st_cp);
- } else {
- strg1->st_wcp = xrealloc(strg1->st_wcp,
- (len + 1) * sizeof (wchar_t));
- (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp,
- (len2 + 1) * sizeof (wchar_t));
- free(strg2->st_wcp);
- }
- strg1->st_len = len;
- free(strg2);
-
- return (strg1);
-}
-
-/*
- * Print a warning if the given node has operands which should be
- * parenthesized.
- *
- * XXX Does not work if an operand is a constant expression. Constant
- * expressions are already folded.
- */
-static void
-precconf(tnode_t *tn)
-{
- tnode_t *ln, *rn;
- op_t lop, rop = NOOP;
- int lparn, rparn;
- mod_t *mp;
- int warn;
-
- if (!hflag)
- return;
-
- mp = &modtab[tn->tn_op];
-
- lparn = 0;
- for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
- lparn |= ln->tn_parn;
- lparn |= ln->tn_parn;
- lop = ln->tn_op;
-
- if (mp->m_binary) {
- rparn = 0;
- for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left)
- rparn |= rn->tn_parn;
- rparn |= rn->tn_parn;
- rop = rn->tn_op;
- }
-
- warn = 0;
-
- switch (tn->tn_op) {
- case SHL:
- case SHR:
- if (!lparn && (lop == PLUS || lop == MINUS)) {
- warn = 1;
- } else if (!rparn && (rop == PLUS || rop == MINUS)) {
- warn = 1;
- }
- break;
- case LOGOR:
- if (!lparn && lop == LOGAND) {
- warn = 1;
- } else if (!rparn && rop == LOGAND) {
- warn = 1;
- }
- break;
- case AND:
- case XOR:
- case OR:
- if (!lparn && lop != tn->tn_op) {
- if (lop == PLUS || lop == MINUS) {
- warn = 1;
- } else if (lop == AND || lop == XOR) {
- warn = 1;
- }
- }
- if (!warn && !rparn && rop != tn->tn_op) {
- if (rop == PLUS || rop == MINUS) {
- warn = 1;
- } else if (rop == AND || rop == XOR) {
- warn = 1;
- }
- }
- break;
- /* LINTED (enumeration values not handled in switch) */
- }
-
- if (warn) {
- /* precedence confusion possible: parenthesize! */
- warning(169);
- }
-
-}
-
-/*
- * Return the function name of a function (or of a pointer to a
- * function).
- */
-const char *
-funcname(tnode_t *tn)
-{
- /* dereference function pointer */
- switch (tn->tn_op) {
- case AMPER:
- return funcname(tn->tn_left);
- case LOAD:
- /* called as (*fptr)(args) */
- return funcname(tn->tn_left);
- case CALL:
- return funcname(tn->tn_left);
- case NAME:
- return tn->tn_sym->s_name;
- default:
- return "<unknown>";
- }
-}
diff --git a/usr.bin/xlint/lint2/Makefile b/usr.bin/xlint/lint2/Makefile
deleted file mode 100644
index e6ac091582b..00000000000
--- a/usr.bin/xlint/lint2/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# $OpenBSD: Makefile,v 1.2 1996/06/26 05:44:21 deraadt Exp $
-# $NetBSD: Makefile,v 1.2 1995/07/03 21:24:39 cgd Exp $
-
-.PATH: ${.CURDIR}/../lint1
-
-PROG= lint2
-SRCS= main2.c hash.c read.c mem.c mem2.c chk.c msg.c emit.c emit2.c
-NOMAN=
-CFLAGS+=-I${.CURDIR}/../lint1
-LINTFLAGS=-abehrz
-
-BINDIR= /usr/libexec
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/xlint/lint2/chk.c b/usr.bin/xlint/lint2/chk.c
deleted file mode 100644
index 3e4839106da..00000000000
--- a/usr.bin/xlint/lint2/chk.c
+++ /dev/null
@@ -1,1412 +0,0 @@
-/* $OpenBSD: chk.c,v 1.26 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <complex.h>
-#include <err.h>
-
-#include "lint2.h"
-
-/* various type information */
-ttab_t ttab[NTSPEC];
-
-
-static void chkund(hte_t *);
-static void chkdnu(hte_t *);
-static void chkdnud(hte_t *);
-static void chkmd(hte_t *);
-static void chkvtui(hte_t *, sym_t *, sym_t *);
-static void chkvtdi(hte_t *, sym_t *, sym_t *);
-static void chkfaui(hte_t *, sym_t *, sym_t *);
-static void chkau(hte_t *, int, sym_t *, sym_t *, pos_t *,
- fcall_t *, fcall_t *, type_t *, type_t *);
-static void chkrvu(hte_t *, sym_t *);
-static void chkadecl(hte_t *, sym_t *, sym_t *);
-static void printflike(hte_t *,fcall_t *, int, const char *, type_t **);
-static void scanflike(hte_t *, fcall_t *, int, const char *, type_t **);
-static void badfmt(hte_t *, fcall_t *);
-static void inconarg(hte_t *, fcall_t *, int);
-static void tofewarg(hte_t *, fcall_t *);
-static void tomanyarg(hte_t *, fcall_t *);
-static int eqtype(type_t *, type_t *, int, int, int, int *);
-static int eqargs(type_t *, type_t *, int *);
-static int mnoarg(type_t *, int *);
-
-
-void
-inittyp(void)
-{
- int i;
- static struct {
- tspec_t it_tspec;
- ttab_t it_ttab;
- } ittab[] = {
- { SIGNED, { 0, 0, 0,
- SIGNED, UNSIGN,
- 0, 0, 0, 0, 0, "signed" } },
- { UNSIGN, { 0, 0, 0,
- SIGNED, UNSIGN,
- 0, 0, 0, 0, 0, "unsigned" } },
- { BOOL, { sizeof (_Bool) * CHAR_BIT, CHAR_BIT, 1,
- BOOL, BOOL,
- 1, 1, 0, 1, 1, "_Bool" } },
- { CHAR, { CHAR_BIT, CHAR_BIT, 20,
- SCHAR, UCHAR,
- 1, 0, 0, 1, 1, "char" } },
- { SCHAR, { CHAR_BIT, CHAR_BIT, 20,
- SCHAR, UCHAR,
- 1, 0, 0, 1, 1, "signed char" } },
- { UCHAR, { CHAR_BIT, CHAR_BIT, 20,
- SCHAR, UCHAR,
- 1, 1, 0, 1, 1, "unsigned char" } },
- { SHORT, { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT, 30,
- SHORT, USHORT,
- 1, 0, 0, 1, 1, "short" } },
- { USHORT, { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT, 30,
- SHORT, USHORT,
- 1, 1, 0, 1, 1, "unsigned short" } },
- { INT, { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
- INT, UINT,
- 1, 0, 0, 1, 1, "int" } },
- { UINT, { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT, 40,
- INT, UINT,
- 1, 1, 0, 1, 1, "unsigned int" } },
- { LONG, { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT, 50,
- LONG, ULONG,
- 1, 0, 0, 1, 1, "long" } },
- { ULONG, { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT, 50,
- LONG, ULONG,
- 1, 1, 0, 1, 1, "unsigned long" } },
- { QUAD, { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
- QUAD, UQUAD,
- 1, 0, 0, 1, 1, "long long" } },
- { UQUAD, { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT, 60,
- QUAD, UQUAD,
- 1, 1, 0, 1, 1, "unsigned long long" } },
- { FLOAT, { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT, -1,
- FLOAT, FLOAT,
- 0, 0, 1, 1, 1, "float" } },
- { DOUBLE, { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT, -1,
- DOUBLE, DOUBLE,
- 0, 0, 1, 1, 1, "double" } },
- { LDOUBLE, { sizeof (ldbl_t) * CHAR_BIT, 16 * CHAR_BIT, -1,
- LDOUBLE, LDOUBLE,
- 0, 0, 1, 1, 1, "long double" } },
- { COMPLEX, { sizeof (float _Complex) * CHAR_BIT,
- 8 * CHAR_BIT, -1,
- COMPLEX, COMPLEX,
- 0, 0, 1, 1, 3, "float _Complex" } },
- { DCOMPLEX, { sizeof (double _Complex) * CHAR_BIT,
- 16 * CHAR_BIT, -1,
- DCOMPLEX, DCOMPLEX,
- 0, 0, 1, 1, 3, "double _Complex" } },
- { LDCOMPLEX,{ sizeof (long double _Complex) * CHAR_BIT,
- 32 * CHAR_BIT, -1,
- LDCOMPLEX, LDCOMPLEX,
- 0, 0, 1, 1, 3, "long double _Complex" } },
- { VOID, { -1, -1, -1,
- VOID, VOID,
- 0, 0, 0, 0, 0, "void" } },
- { STRUCT, { -1, -1, -1,
- STRUCT, STRUCT,
- 0, 0, 0, 0, 0, "struct" } },
- { UNION, { -1, -1, -1,
- UNION, UNION,
- 0, 0, 0, 0, 0, "union" } },
- { ENUM, { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT, 40,
- ENUM, ENUM,
- 1, 0, 0, 1, 1, "enum" } },
- { PTR, { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT, -1,
- PTR, PTR,
- 0, 1, 0, 0, 1, "pointer" } },
- { ARRAY, { -1, -1, -1,
- ARRAY, ARRAY,
- 0, 0, 0, 0, 0, "array" } },
- { FUNC, { -1, -1, -1,
- FUNC, FUNC,
- 0, 0, 0, 0, 0, "function" } },
- };
-
- for (i = 0; i < sizeof (ittab) / sizeof (ittab[0]); i++)
- STRUCT_ASSIGN(ttab[ittab[i].it_tspec], ittab[i].it_ttab);
- if (!pflag) {
- for (i = 0; i < NTSPEC; i++)
- ttab[i].tt_psz = ttab[i].tt_sz;
- }
-}
-
-
-/*
- * If there is a symbol named "main", mark it as used.
- */
-void
-mainused(void)
-{
- hte_t *hte;
-
- if ((hte = hsearch("main", 0)) != NULL)
- hte->h_used = 1;
-}
-
-/*
- * Performs all tests for a single name
- */
-void
-chkname(hte_t *hte)
-{
- sym_t *sym, *def, *pdecl, *decl;
-
- if (uflag) {
- chkund(hte);
- chkdnu(hte);
- if (xflag)
- chkdnud(hte);
- }
- chkmd(hte);
-
- /* Get definition, prototype declaration and declaration */
- def = pdecl = decl = NULL;
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- if (def == NULL && (sym->s_def == DEF || sym->s_def == TDEF))
- def = sym;
- if (pdecl == NULL && sym->s_def == DECL &&
- TP(sym->s_type)->t_tspec == FUNC &&
- TP(sym->s_type)->t_proto) {
- pdecl = sym;
- }
- if (decl == NULL && sym->s_def == DECL)
- decl = sym;
- }
-
- /* A prototype is better than an old style declaration. */
- if (pdecl != NULL)
- decl = pdecl;
-
- chkvtui(hte, def, decl);
-
- chkvtdi(hte, def, decl);
-
- chkfaui(hte, def, decl);
-
- chkrvu(hte, def);
-
- chkadecl(hte, def, decl);
-}
-
-/*
- * Print a warning if the name has been used, but not defined.
- */
-static void
-chkund(hte_t *hte)
-{
- fcall_t *fcall;
- usym_t *usym;
-
- if (!hte->h_used || hte->h_def)
- return;
-
- if ((fcall = hte->h_calls) != NULL) {
- /* %s: %s used, but not defined */
- msg(0, mkpos(&fcall->f_pos), hte->h_name);
- } else if ((usym = hte->h_usyms) != NULL) {
- /* %s: %s used, but not defined */
- msg(0, mkpos(&usym->u_pos), hte->h_name);
- }
-}
-
-/*
- * Print a warning if the name has been defined, but never used.
- */
-static void
-chkdnu(hte_t *hte)
-{
- sym_t *sym;
-
- if (!hte->h_def || hte->h_used)
- return;
-
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- if (sym->s_def == DEF || sym->s_def == TDEF) {
- /* %s: %s defined, but never used */
- msg(1, mkpos(&sym->s_pos), hte->h_name);
- break;
- }
- }
-}
-
-/*
- * Print a warning if the name has been declared, but is not used
- * or defined.
- */
-static void
-chkdnud(hte_t *hte)
-{
- sym_t *sym;
-
- if (hte->h_syms == NULL || hte->h_used || hte->h_def)
- return;
-
- if ((sym = hte->h_syms) != NULL) {
- if (sym->s_def != DECL)
- errx(1, "internal error: chkdnud() 1");
-
- /* don't warn if the name was declared in a separate header */
- if (sym->s_pos.p_src != sym->s_pos.p_isrc) {
- return;
- }
-
- /* %s: %s declared, but never used or defined */
- msg(2, mkpos(&sym->s_pos), hte->h_name);
- }
-}
-
-/*
- * Print a warning if there is more than one definition for
- * this name.
- */
-static void
-chkmd(hte_t *hte)
-{
- sym_t *sym, *def1;
- char *pos1;
-
- if (!hte->h_def)
- return;
-
- def1 = NULL;
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- /*
- * ANSI C allows tentative definitions of the same name in
- * only one compilation unit.
- */
- if (sym->s_def != DEF && (!sflag || sym->s_def != TDEF))
- continue;
- if (def1 == NULL) {
- def1 = sym;
- continue;
- }
- pos1 = xstrdup(mkpos(&def1->s_pos));
- /* %s: %s multiply defined (%s) */
- msg(3, pos1, hte->h_name, mkpos(&sym->s_pos));
- free(pos1);
- }
-}
-
-/*
- * Print a warning if the return value assumed for a function call
- * differs from the return value of the function definition or
- * function declaration.
- *
- * If no definition/declaration can be found, the assumed return values
- * are always int. So there is no need to compare with another function
- * call as it's done for function arguments.
- */
-static void
-chkvtui(hte_t *hte, sym_t *def, sym_t *decl)
-{
- fcall_t *call;
- char *pos1;
- type_t *tp1, *tp2;
- /* LINTED (automatic hides external declaration: warn) */
- int warn, eq;
- tspec_t t1;
-
- if (hte->h_calls == NULL)
- return;
-
- if (def == NULL)
- def = decl;
- if (def == NULL)
- return;
-
- t1 = (tp1 = TP(def->s_type)->t_subt)->t_tspec;
- for (call = hte->h_calls; call != NULL; call = call->f_nxt) {
- tp2 = TP(call->f_type)->t_subt;
- eq = eqtype(tp1, tp2, 1, 0, 0, (warn = 0, &warn));
- if (!call->f_rused) {
- /* no return value used */
- if ((t1 == STRUCT || t1 == UNION) && !eq) {
- /*
- * If a function returns a struct or union it
- * must be declared to return a struct or
- * union, also if the return value is ignored.
- * This is necessary because the caller must
- * allocate stack space for the return value.
- * If it does not, the return value would over-
- * write other data.
- * XXX Following massage may be confusing
- * because it appears also if the return value
- * was declared inconsistently. But this
- * behaviour matches pcc based lint, so it is
- * accepted for now.
- */
- pos1 = xstrdup(mkpos(&def->s_pos));
- /* %s: %s must be decl. before use (%s) */
- msg(17, pos1, hte->h_name,
- mkpos(&call->f_pos));
- free(pos1);
- }
- continue;
- }
- if (!eq || (sflag && warn)) {
- pos1 = xstrdup(mkpos(&def->s_pos));
- /* %s: %s used inconsistently (%s) */
- msg(4, pos1, hte->h_name, mkpos(&call->f_pos));
- free(pos1);
- }
- }
-}
-
-/*
- * Print a warning if a definition/declaration does not match another
- * definition/declaration of the same name. For functions, only the
- * types of return values are tested.
- */
-static void
-chkvtdi(hte_t *hte, sym_t *def, sym_t *decl)
-{
- sym_t *sym;
- type_t *tp1, *tp2;
- /* LINTED (automatic hides external declaration: warn) */
- int eq, warn;
- char *pos1;
-
- if (def == NULL)
- def = decl;
- if (def == NULL)
- return;
-
- tp1 = TP(def->s_type);
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- if (sym == def)
- continue;
- tp2 = TP(sym->s_type);
- warn = 0;
- if (tp1->t_tspec == FUNC && tp2->t_tspec == FUNC) {
- eq = eqtype(tp1->t_subt, tp2->t_subt, 1, 0, 0, &warn);
- } else {
- eq = eqtype(tp1, tp2, 0, 0, 0, &warn);
- }
- if (!eq || (sflag && warn)) {
- pos1 = xstrdup(mkpos(&def->s_pos));
- /* %s: %s declared inconsistently (%s) */
- msg(5, pos1, hte->h_name, mkpos(&sym->s_pos));
- free(pos1);
- }
- }
-}
-
-/*
- * Print a warning if a function is called with arguments which does
- * not match the function definition, declaration or another call
- * of the same function.
- */
-static void
-chkfaui(hte_t *hte, sym_t *def, sym_t *decl)
-{
- type_t *tp1, *tp2, **ap1, **ap2;
- pos_t *pos1p;
- fcall_t *calls, *call, *call1;
- int n, as;
- char *pos1;
- arginf_t *ai;
-
- if ((calls = hte->h_calls) == NULL)
- return;
-
- /*
- * If we find a function definition, we use this for comparison,
- * otherwise the first prototype we can find. If there is no
- * definition or prototype declaration, the first function call
- * is used.
- */
- tp1 = NULL;
- call1 = NULL;
- if (def != NULL) {
- if ((tp1 = TP(def->s_type))->t_tspec != FUNC)
- return;
- pos1p = &def->s_pos;
- } else if (decl != NULL && TP(decl->s_type)->t_proto) {
- if ((tp1 = TP(decl->s_type))->t_tspec != FUNC)
- return;
- pos1p = &decl->s_pos;
- }
- if (tp1 == NULL) {
- call1 = calls;
- calls = calls->f_nxt;
- if ((tp1 = TP(call1->f_type))->t_tspec != FUNC)
- return;
- pos1p = &call1->f_pos;
- }
-
- n = 1;
- for (call = calls; call != NULL; call = call->f_nxt) {
- if ((tp2 = TP(call->f_type))->t_tspec != FUNC)
- continue;
- ap1 = tp1->t_args;
- ap2 = tp2->t_args;
- n = 0;
- while (*ap1 != NULL && *ap2 != NULL) {
- if (def != NULL && def->s_va && n >= def->s_nva)
- break;
- n++;
- chkau(hte, n, def, decl, pos1p, call1, call,
- *ap1, *ap2);
- ap1++;
- ap2++;
- }
- if (*ap1 == *ap2) {
- /* equal # of arguments */
- } else if (def != NULL && def->s_va && n >= def->s_nva) {
- /*
- * function definition with VARARGS; The # of
- * arguments of the call must be at least as large
- * as the parameter of VARARGS.
- */
- } else if (*ap2 != NULL && tp1->t_proto && tp1->t_vararg) {
- /*
- * prototype with ... and function call with
- * at least the same # of arguments as declared
- * in the prototype.
- */
- } else {
- pos1 = xstrdup(mkpos(pos1p));
- /* %s: %s called with varying # of args (%s) */
- msg(7, pos1, hte->h_name, mkpos(&call->f_pos));
- free(pos1);
- continue;
- }
-
- /* perform SCANFLIKE/PRINTFLIKE tests */
- if (def == NULL || (!def->s_prfl && !def->s_scfl))
- continue;
- as = def->s_prfl ? def->s_nprfl : def->s_nscfl;
- for (ai = call->f_args; ai != NULL; ai = ai->a_nxt) {
- if (ai->a_num == as)
- break;
- }
- if (ai == NULL || !ai->a_fmt)
- continue;
- if (def->s_prfl) {
- printflike(hte, call, n, ai->a_fstrg, ap2);
- } else {
- scanflike(hte, call, n, ai->a_fstrg, ap2);
- }
- }
-}
-
-/*
- * Check a single argument in a function call.
- *
- * hte a pointer to the hash table entry of the function
- * n the number of the argument (1..)
- * def the function definition or NULL
- * decl prototype declaration, old style declaration or NULL
- * pos1p position of definition, declaration of first call
- * call1 first call, if both def and decl are old style def/decl
- * call checked call
- * arg1 currently checked argument of def/decl/call1
- * arg2 currently checked argument of call
- *
- */
-static void
-chkau(hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p,
- fcall_t *call1, fcall_t *call, type_t *arg1, type_t *arg2)
-{
- /* LINTED (automatic hides external declaration: warn) */
- int promote, asgn, warn;
- tspec_t t1, t2;
- arginf_t *ai, *ai1;
- char *pos1;
-
- /*
- * If a function definition is available (def != NULL), we compair the
- * function call (call) with the definition. Otherwise, if a function
- * definition is available and it is not an old style definition
- * (decl != NULL && TP(decl->s_type)->t_proto), we compair the call
- * with this declaration. Otherwise we compair it with the first
- * call we have found (call1).
- */
-
- /* arg1 must be promoted if it stems from an old style definition */
- promote = def != NULL && def->s_osdef;
-
- /*
- * If we compair with a definition or declaration, we must perform
- * the same checks for qualifiers in indirected types as in
- * assignments.
- */
- asgn = def != NULL || (decl != NULL && TP(decl->s_type)->t_proto);
-
- warn = 0;
- if (eqtype(arg1, arg2, 1, promote, asgn, &warn) && (!sflag || !warn))
- return;
-
- /*
- * Other lint implementations print warnings as soon as the type
- * of an argument does not match exactly the expected type. The
- * result are lots of warnings which are really not necessary.
- * We print a warning only if
- * (0) at least one type is not an interger type and types differ
- * (1) hflag is set and types differ
- * (2) types differ, except in signedness
- * If the argument is an integer constant whose msb is not set,
- * signedness is ignored (e.g. 0 matches both signed and unsigned
- * int). This is with and without hflag.
- * If the argument is an integer constant with value 0 and the
- * expected argument is of type pointer and the width of the
- * interger constant is the same as the width of the pointer,
- * no warning is printed.
- */
- t1 = arg1->t_tspec;
- t2 = arg2->t_tspec;
- if (isityp(t1) && isityp(t2) && !arg1->t_isenum && !arg2->t_isenum) {
- if (promote) {
- /*
- * XXX Here is a problem: Althrough it is possible to
- * pass an int where a char/short it expected, there
- * may be loss in significant digits. We should first
- * check for const arguments if they can be converted
- * into the original parameter type.
- */
- if (t1 == FLOAT) {
- t1 = DOUBLE;
- } else if (t1 == CHAR || t1 == SCHAR) {
- t1 = INT;
- } else if (t1 == UCHAR) {
- t1 = INT;
- } else if (t1 == SHORT) {
- t1 = INT;
- } else if (t1 == USHORT) {
- /* CONSTCOND */
- t1 = INT_MAX < USHRT_MAX ? UINT : INT;
- }
- }
-
- if (styp(t1) == styp(t2)) {
-
- /*
- * types differ only in signedness; get information
- * about arguments
- */
-
- /*
- * treat a definition like a call with variable
- * arguments
- */
- ai1 = call1 != NULL ? call1->f_args : NULL;
-
- /*
- * if two calls are compared, ai1 is set to the
- * information for the n-th argument, if this was
- * a constant, otherwise to NULL
- */
- for ( ; ai1 != NULL; ai1 = ai1->a_nxt) {
- if (ai1->a_num == n)
- break;
- }
- /*
- * ai is set to the information of the n-th arg
- * of the (second) call, if this was a constant,
- * otherwise to NULL
- */
- for (ai = call->f_args; ai != NULL; ai = ai->a_nxt) {
- if (ai->a_num == n)
- break;
- }
-
- if (ai1 == NULL && ai == NULL) {
- /* no constant at all */
- if (!hflag)
- return;
- } else if (ai1 == NULL || ai == NULL) {
- /* one constant */
- if (ai == NULL)
- ai = ai1;
- if (ai->a_zero || ai->a_pcon)
- /* same value in signed and unsigned */
- return;
- /* value (not representation) differently */
- } else {
- /*
- * two constants, one signed, one unsigned;
- * if the msb of one of the constants is set,
- * the argument is used inconsistently.
- */
- if (!ai1->a_ncon && !ai->a_ncon)
- return;
- }
- }
-
- } else if (t1 == PTR && isityp(t2) && psize(t1) == psize(t2)) {
- for (ai = call->f_args; ai != NULL; ai = ai->a_nxt) {
- if (ai->a_num == n)
- break;
- }
- if (ai != NULL && ai->a_zero)
- return;
- }
-
- pos1 = xstrdup(mkpos(pos1p));
- /* %s: %s arg %d used inconsistently (%s) */
- msg(6, pos1, hte->h_name, n, mkpos(&call->f_pos));
- free(pos1);
-}
-
-/*
- * Compare the types in the NULL-terminated array ap with the format
- * string fmt.
- */
-static void
-printflike(hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap)
-{
- const char *fp;
- int fc;
- int fwidth, prec, left, sign, space, alt, zero;
- tspec_t sz, t1, t2 = NOTSPEC;
- type_t *tp;
-
- fp = fmt;
- fc = *fp++;
-
- for ( ; ; ) {
- if (fc == '\0') {
- if (*ap != NULL)
- tomanyarg(hte, call);
- break;
- }
- if (fc != '%') {
- badfmt(hte, call);
- break;
- }
- fc = *fp++;
- fwidth = prec = left = sign = space = alt = zero = 0;
- sz = NOTSPEC;
-
- /* Flags */
- for ( ; ; ) {
- if (fc == '-') {
- if (left)
- break;
- left = 1;
- } else if (fc == '+') {
- if (sign)
- break;
- sign = 1;
- } else if (fc == ' ') {
- if (space)
- break;
- space = 1;
- } else if (fc == '#') {
- if (alt)
- break;
- alt = 1;
- } else if (fc == '0') {
- if (zero)
- break;
- zero = 1;
- } else {
- break;
- }
- fc = *fp++;
- }
-
- /* field width */
- if (isdigit(fc)) {
- fwidth = 1;
- do { fc = *fp++; } while (isdigit(fc)) ;
- } else if (fc == '*') {
- fwidth = 1;
- fc = *fp++;
- if ((tp = *ap++) == NULL) {
- tofewarg(hte, call);
- break;
- }
- n++;
- if ((t1 = tp->t_tspec) != INT && (hflag || t1 != UINT))
- inconarg(hte, call, n);
- }
-
- /* precision */
- if (fc == '.') {
- fc = *fp++;
- prec = 1;
- if (isdigit(fc)) {
- do { fc = *fp++; } while (isdigit(fc));
- } else if (fc == '*') {
- fc = *fp++;
- if ((tp = *ap++) == NULL) {
- tofewarg(hte, call);
- break;
- }
- n++;
- if (tp->t_tspec != INT)
- inconarg(hte, call, n);
- } else {
- badfmt(hte, call);
- break;
- }
- }
-
- if (fc == 'h') {
- sz = SHORT;
- } else if (fc == 'l') {
- sz = LONG;
- } else if (fc == 'q') {
- sz = QUAD;
- } else if (fc == 'L') {
- sz = LDOUBLE;
- }
- if (sz != NOTSPEC)
- fc = *fp++;
-
- if (fc == '%' || fc == 'm') {
- if (sz != NOTSPEC || left || sign || space ||
- alt || zero || prec || fwidth) {
- badfmt(hte, call);
- }
- fc = *fp++;
- continue;
- }
-
- if (fc == '\0') {
- badfmt(hte, call);
- break;
- }
-
- if ((tp = *ap++) == NULL) {
- tofewarg(hte, call);
- break;
- }
- n++;
- if ((t1 = tp->t_tspec) == PTR)
- t2 = tp->t_subt->t_tspec;
-
- if (fc == 'd' || fc == 'i') {
- if (alt || sz == LDOUBLE) {
- badfmt(hte, call);
- break;
- }
- int_conv:
- if (sz == LONG) {
- if (t1 != LONG && (hflag || t1 != ULONG))
- inconarg(hte, call, n);
- } else if (sz == QUAD) {
- if (t1 != QUAD && (hflag || t1 != UQUAD))
- inconarg(hte, call, n);
- } else {
- /*
- * SHORT is always promoted to INT, USHORT
- * to INT or UINT.
- */
- if (t1 != INT && (hflag || t1 != UINT))
- inconarg(hte, call, n);
- }
- } else if (fc == 'o' || fc == 'u' || fc == 'x' || fc == 'X') {
- if ((alt && fc == 'u') || sz == LDOUBLE)
- badfmt(hte, call);
- uint_conv:
- if (sz == LONG) {
- if (t1 != ULONG && (hflag || t1 != LONG))
- inconarg(hte, call, n);
- } else if (sz == QUAD) {
- if (t1 != UQUAD && (hflag || t1 != QUAD))
- inconarg(hte, call, n);
- } else if (sz == SHORT) {
- /* USHORT was promoted to INT or UINT */
- if (t1 != UINT && t1 != INT)
- inconarg(hte, call, n);
- } else {
- if (t1 != UINT && (hflag || t1 != INT))
- inconarg(hte, call, n);
- }
- } else if (fc == 'D' || fc == 'O' || fc == 'U') {
- /* DOU are deprecated */
- badfmt(hte, call);
- sz = LONG;
- if (fc == 'D') {
- goto int_conv;
- } else {
- goto uint_conv;
- }
- } else if (fc == 'e' || fc == 'E' ||
- fc == 'f' || fc == 'F' ||
- fc == 'g' || fc == 'G' ||
- fc == 'a' || fc == 'A') {
- if (sz == NOTSPEC)
- sz = DOUBLE;
- if (sz != DOUBLE && sz != LDOUBLE)
- badfmt(hte, call);
- if (t1 != sz)
- inconarg(hte, call, n);
- } else if (fc == 'c') {
- if (sz != NOTSPEC || alt || zero)
- badfmt(hte, call);
- if (t1 != INT)
- inconarg(hte, call, n);
- } else if (fc == 's') {
- if (sz != NOTSPEC || alt || zero)
- badfmt(hte, call);
- if (t1 != PTR ||
- (t2 != CHAR && t2 != UCHAR && t2 != SCHAR)) {
- inconarg(hte, call, n);
- }
- } else if (fc == 'p') {
- if (fwidth || prec || sz != NOTSPEC || alt || zero)
- badfmt(hte, call);
- if (t1 != PTR || (hflag && t2 != VOID))
- inconarg(hte, call, n);
- } else if (fc == 'n') {
- if (fwidth || prec || alt || zero || sz == LDOUBLE)
- badfmt(hte, call);
- if (t1 != PTR) {
- inconarg(hte, call, n);
- } else if (sz == LONG) {
- if (t2 != LONG && t2 != ULONG)
- inconarg(hte, call, n);
- } else if (sz == SHORT) {
- if (t2 != SHORT && t2 != USHORT)
- inconarg(hte, call, n);
- } else {
- if (t2 != INT && t2 != UINT)
- inconarg(hte, call, n);
- }
- } else {
- badfmt(hte, call);
- break;
- }
-
- fc = *fp++;
- }
-}
-
-/*
- * Compare the types in the NULL-terminated array ap with the format
- * string fmt.
- */
-static void
-scanflike(hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap)
-{
- const char *fp;
- int fc;
- int noasgn, fwidth;
- tspec_t sz, t1 = NOTSPEC, t2 = NOTSPEC;
- type_t *tp;
-
- fp = fmt;
- fc = *fp++;
-
- for ( ; ; ) {
- if (fc == '\0') {
- if (*ap != NULL)
- tomanyarg(hte, call);
- break;
- }
- if (fc != '%') {
- badfmt(hte, call);
- break;
- }
- fc = *fp++;
-
- noasgn = fwidth = 0;
- sz = NOTSPEC;
-
- if (fc == '*') {
- noasgn = 1;
- fc = *fp++;
- }
-
- if (isdigit(fc)) {
- fwidth = 1;
- do { fc = *fp++; } while (isdigit(fc));
- }
-
- if (fc == 'h') {
- sz = SHORT;
- } else if (fc == 'l') {
- sz = LONG;
- } else if (fc == 'q') {
- sz = QUAD;
- } else if (fc == 'L') {
- sz = LDOUBLE;
- }
- if (sz != NOTSPEC)
- fc = *fp++;
-
- if (fc == '%') {
- if (sz != NOTSPEC || noasgn || fwidth)
- badfmt(hte, call);
- fc = *fp++;
- continue;
- }
-
- if (!noasgn) {
- if ((tp = *ap++) == NULL) {
- tofewarg(hte, call);
- break;
- }
- n++;
- if ((t1 = tp->t_tspec) == PTR)
- t2 = tp->t_subt->t_tspec;
- }
-
- if (fc == 'd' || fc == 'i' || fc == 'n') {
- if (sz == LDOUBLE)
- badfmt(hte, call);
- if (sz != SHORT && sz != LONG && sz != QUAD)
- sz = INT;
- conv:
- if (!noasgn) {
- if (t1 != PTR) {
- inconarg(hte, call, n);
- } else if (t2 != styp(sz)) {
- inconarg(hte, call, n);
- } else if (hflag && t2 != sz) {
- inconarg(hte, call, n);
- } else if (tp->t_subt->t_const) {
- inconarg(hte, call, n);
- }
- }
- } else if (fc == 'o' || fc == 'u' || fc == 'x') {
- if (sz == LDOUBLE)
- badfmt(hte, call);
- if (sz == SHORT) {
- sz = USHORT;
- } else if (sz == LONG) {
- sz = ULONG;
- } else if (sz == QUAD) {
- sz = UQUAD;
- } else {
- sz = UINT;
- }
- goto conv;
- } else if (fc == 'D') {
- badfmt(hte, call);
- sz = LONG;
- goto conv;
- } else if (fc == 'O') {
- badfmt(hte, call);
- sz = ULONG;
- goto conv;
- } else if (fc == 'X') {
- /*
- * XXX valid in ANSI C, but in NetBSD's libc imple-
- * mented as "lx". Thats why it should be avoided.
- */
- badfmt(hte, call);
- sz = ULONG;
- goto conv;
- } else if (fc == 'e' || fc == 'E' ||
- fc == 'f' || fc == 'F' ||
- fc == 'g' || fc == 'G' ||
- fc == 'a' || fc == 'A') {
- if (sz == NOTSPEC) {
- sz = FLOAT;
- } else if (sz == LONG) {
- sz = DOUBLE;
- } else if (sz != LDOUBLE) {
- badfmt(hte, call);
- sz = FLOAT;
- }
- goto conv;
- } else if (fc == 's' || fc == '[' || fc == 'c') {
- if (sz != NOTSPEC)
- badfmt(hte, call);
- if (fc == '[') {
- if ((fc = *fp++) == '-') {
- badfmt(hte, call);
- fc = *fp++;
- }
- if (fc != ']') {
- badfmt(hte, call);
- if (fc == '\0')
- break;
- }
- }
- if (!noasgn) {
- if (t1 != PTR) {
- inconarg(hte, call, n);
- } else if (t2 != CHAR && t2 != UCHAR &&
- t2 != SCHAR) {
- inconarg(hte, call, n);
- }
- }
- } else if (fc == 'p') {
- if (sz != NOTSPEC)
- badfmt(hte, call);
- if (!noasgn) {
- if (t1 != PTR || t2 != PTR) {
- inconarg(hte, call, n);
- } else if (tp->t_subt->t_subt->t_tspec!=VOID) {
- if (hflag)
- inconarg(hte, call, n);
- }
- }
- } else {
- badfmt(hte, call);
- break;
- }
-
- fc = *fp++;
- }
-}
-
-static void
-badfmt(hte_t *hte, fcall_t *call)
-{
- /* %s: malformed format string argument to %s */
- msg(13, mkpos(&call->f_pos), hte->h_name);
-}
-
-static void
-inconarg(hte_t *hte, fcall_t *call, int n)
-{
- /* %s: arg %d to %s is inconsistent with format */
- msg(14, mkpos(&call->f_pos), n, hte->h_name);
-}
-
-static void
-tofewarg(hte_t *hte, fcall_t *call)
-{
- /* %s: too few format args to %s */
- msg(15, mkpos(&call->f_pos), hte->h_name);
-}
-
-static void
-tomanyarg(hte_t *hte, fcall_t *call)
-{
- /* %s: too many format args to %s */
- msg(16, mkpos(&call->f_pos), hte->h_name);
-}
-
-
-/*
- * Print warnings for return values which are used, but not returned,
- * or return values which are always or sometimes ignored.
- */
-static void
-chkrvu(hte_t *hte, sym_t *def)
-{
- fcall_t *call;
- int used, ignored;
-
- if (def == NULL)
- /* don't know wheter or not the functions returns a value */
- return;
-
- if (hte->h_calls == NULL)
- return;
-
- if (def->s_rval) {
- /* function has return value */
- used = ignored = 0;
- for (call = hte->h_calls; call != NULL; call = call->f_nxt) {
- used |= call->f_rused || call->f_rdisc;
- ignored |= !call->f_rused && !call->f_rdisc;
- }
- /*
- * XXX as soon as we are able to disable single warnings
- * the following dependencies from hflag should be removed.
- * but for now I do'nt want to be botherd by this warnings
- * which are almost always useless.
- */
- if (!used && ignored) {
- if (hflag)
- /* %s returns value which is always ignored */
- msg(8, hte->h_name);
- } else if (used && ignored) {
- if (hflag)
- /* %s returns value which is sometimes ign. */
- msg(9, hte->h_name);
- }
- } else {
- /* function has no return value */
- for (call = hte->h_calls; call != NULL; call = call->f_nxt) {
- if (call->f_rused)
- /* %s: return value of %s is used, but none ret. */
- msg(10, mkpos(&call->f_pos), hte->h_name);
- }
- }
-}
-
-/*
- * Print warnings for inconsistent argument declarations.
- */
-static void
-chkadecl(hte_t *hte, sym_t *def, sym_t *decl)
-{
- /* LINTED (automatic hides external declaration: warn) */
- int osdef, eq, warn, n;
- sym_t *sym1, *sym;
- type_t **ap1, **ap2, *tp1, *tp2;
- char *pos1;
- const char *pos2;
-
- osdef = 0;
- if (def != NULL) {
- osdef = def->s_osdef;
- sym1 = def;
- } else if (decl != NULL && TP(decl->s_type)->t_proto) {
- sym1 = decl;
- } else {
- return;
- }
- if (TP(sym1->s_type)->t_tspec != FUNC)
- return;
-
- /*
- * XXX Prototypes should also be compared with old style function
- * declarations.
- */
-
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- if (sym == sym1 || !TP(sym->s_type)->t_proto)
- continue;
- ap1 = TP(sym1->s_type)->t_args;
- ap2 = TP(sym->s_type)->t_args;
- n = 0;
- while (*ap1 != NULL && *ap2 != NULL) {
- warn = 0;
- eq = eqtype(*ap1, *ap2, 1, osdef, 0, &warn);
- if (!eq || warn) {
- pos1 = xstrdup(mkpos(&sym1->s_pos));
- pos2 = mkpos(&sym->s_pos);
- /* %s: %s arg %d declared inconsistently ... */
- msg(11, pos1, hte->h_name, n + 1, pos2);
- free(pos1);
- }
- n++;
- ap1++;
- ap2++;
- }
- if (*ap1 == *ap2) {
- tp1 = TP(sym1->s_type);
- tp2 = TP(sym->s_type);
- if (tp1->t_vararg == tp2->t_vararg)
- continue;
- if (tp2->t_vararg &&
- sym1->s_va && sym1->s_nva == n && !sflag) {
- continue;
- }
- }
- /* %s: %s declared with varying # of args (%s) */
- pos1 = xstrdup(mkpos(&sym1->s_pos));
- msg(12, pos1, hte->h_name, mkpos(&sym->s_pos));
- free(pos1);
- }
-}
-
-
-/*
- * Check compatibility of two types. Returns 1 if types are compatible,
- * otherwise 0.
- *
- * ignqual if set, ignore qualifiers of outhermost type; used for
- * function arguments
- * promote if set, promote left type before comparison; used for
- * comparisons of arguments with parameters of old style
- * definitions
- * asgn left indirected type must have at least the same qualifiers
- * like right indirected type (for assignments and function
- * arguments)
- * *warn set to 1 if an old style declaration was compared with
- * an incompatible prototype declaration
- */
-static int
-eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int asgn, int *warn)
-{
- tspec_t t, to;
- int indir;
-
- to = NOTSPEC;
- indir = 0;
-
- while (tp1 != NULL && tp2 != NULL) {
-
- t = tp1->t_tspec;
- if (promot) {
- if (t == FLOAT) {
- t = DOUBLE;
- } else if (t == CHAR || t == SCHAR) {
- t = INT;
- } else if (t == UCHAR) {
- t = INT;
- } else if (t == SHORT) {
- t = INT;
- } else if (t == USHORT) {
- /* CONSTCOND */
- t = INT_MAX < USHRT_MAX ? UINT : INT;
- }
- }
-
- if (asgn && to == PTR) {
- if (indir == 1 && (t == VOID || tp2->t_tspec == VOID))
- return (1);
- }
-
- if (t != tp2->t_tspec) {
- /*
- * Give pointer to types which differ only in
- * signedness a chance if not sflag and not hflag.
- */
- if (sflag || hflag || to != PTR)
- return (0);
- if (styp(t) != styp(tp2->t_tspec))
- return (0);
- }
-
- if (tp1->t_isenum && tp2->t_isenum) {
- if (tp1->t_istag && tp2->t_istag) {
- return (tp1->t_tag == tp2->t_tag);
- } else if (tp1->t_istynam && tp2->t_istynam) {
- return (tp1->t_tynam == tp2->t_tynam);
- } else {
- return (0);
- }
- }
-
- /*
- * XXX Handle combinations of enum and int if eflag is set.
- * But note: enum and 0 should be allowed.
- */
-
- if (asgn && indir == 1) {
- if (!tp1->t_const && tp2->t_const)
- return (0);
- if (!tp1->t_volatile && tp2->t_volatile)
- return (0);
- } else if (!ignqual) {
- if (tp1->t_const != tp2->t_const)
- return (0);
- if (tp1->t_const != tp2->t_const)
- return (0);
- }
-
- if (t == STRUCT || t == UNION) {
- if (tp1->t_istag && tp2->t_istag) {
- return (tp1->t_tag == tp2->t_tag);
- } else if (tp1->t_istynam && tp2->t_istynam) {
- return (tp1->t_tynam == tp2->t_tynam);
- } else {
- return (0);
- }
- }
-
- if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
- if (tp1->t_dim != 0 && tp2->t_dim != 0)
- return (0);
- }
-
- if (t == FUNC) {
- if (tp1->t_proto && tp2->t_proto) {
- if (!eqargs(tp1, tp2, warn))
- return (0);
- } else if (tp1->t_proto) {
- if (!mnoarg(tp1, warn))
- return (0);
- } else if (tp2->t_proto) {
- if (!mnoarg(tp2, warn))
- return (0);
- }
- }
-
- tp1 = tp1->t_subt;
- tp2 = tp2->t_subt;
- ignqual = promot = 0;
- to = t;
- indir++;
-
- }
-
- return (tp1 == tp2);
-}
-
-/*
- * Compares arguments of two prototypes
- */
-static int
-eqargs(type_t *tp1, type_t *tp2, int *warn)
-{
- type_t **a1, **a2;
-
- if (tp1->t_vararg != tp2->t_vararg)
- return (0);
-
- a1 = tp1->t_args;
- a2 = tp2->t_args;
-
- while (*a1 != NULL && *a2 != NULL) {
-
- if (eqtype(*a1, *a2, 1, 0, 0, warn) == 0)
- return (0);
-
- a1++;
- a2++;
-
- }
-
- return (*a1 == *a2);
-}
-
-/*
- * mnoarg() (matches functions with no argument type information)
- * returns 1 if all parameters of a prototype are compatible with
- * and old style function declaration.
- * This is the case if following conditions are met:
- * 1. the prototype must have a fixed number of parameters
- * 2. no parameter is of type float
- * 3. no parameter is converted to another type if integer promotion
- * is applied on it
- */
-static int
-mnoarg(type_t *tp, int *warn)
-{
- type_t **arg;
- tspec_t t;
-
- if (tp->t_vararg && warn != NULL)
- *warn = 1;
- for (arg = tp->t_args; *arg != NULL; arg++) {
- if ((t = (*arg)->t_tspec) == FLOAT)
- return (0);
- if (t == CHAR || t == SCHAR || t == UCHAR)
- return (0);
- if (t == SHORT || t == USHORT)
- return (0);
- }
- return (1);
-}
diff --git a/usr.bin/xlint/lint2/emit2.c b/usr.bin/xlint/lint2/emit2.c
deleted file mode 100644
index 2e60ceec3a8..00000000000
--- a/usr.bin/xlint/lint2/emit2.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* $OpenBSD: emit2.c,v 1.7 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <err.h>
-
-#include "lint2.h"
-
-static void outtype(type_t *);
-static void outdef(hte_t *, sym_t *);
-static void dumpname(hte_t *);
-
-/*
- * Write type into the output buffer.
- */
-static void
-outtype(type_t *tp)
-{
- int t, s, na;
- tspec_t ts;
- type_t **ap;
-
- while (tp != NULL) {
- if ((ts = tp->t_tspec) == INT && tp->t_isenum)
- ts = ENUM;
- switch (ts) {
- case BOOL: t = 'B'; s = '\0'; break;
- case CHAR: t = 'C'; s = '\0'; break;
- case SCHAR: t = 'C'; s = 's'; break;
- case UCHAR: t = 'C'; s = 'u'; break;
- case SHORT: t = 'S'; s = '\0'; break;
- case USHORT: t = 'S'; s = 'u'; break;
- case INT: t = 'I'; s = '\0'; break;
- case UINT: t = 'I'; s = 'u'; break;
- case LONG: t = 'L'; s = '\0'; break;
- case ULONG: t = 'L'; s = 'u'; break;
- case QUAD: t = 'Q'; s = '\0'; break;
- case UQUAD: t = 'Q'; s = 'u'; break;
- case FLOAT: t = 'D'; s = 's'; break;
- case DOUBLE: t = 'D'; s = '\0'; break;
- case LDOUBLE: t = 'D'; s = 'l'; break;
- case COMPLEX: t = 'X'; s = 's'; break;
- case DCOMPLEX: t = 'X'; s = '\0'; break;
- case LDCOMPLEX: t = 'X'; s = 'l'; break;
- case IMAGINARY: t = 'J'; s = 's'; break;
- case DIMAGINARY: t = 'J'; s = '\0'; break;
- case LDIMAGINARY:t = 'J'; s = 'l'; break;
- case VOID: t = 'V'; s = '\0'; break;
- case PTR: t = 'P'; s = '\0'; break;
- case ARRAY: t = 'A'; s = '\0'; break;
- case ENUM: t = 'T'; s = 'e'; break;
- case STRUCT: t = 'T'; s = 's'; break;
- case UNION: t = 'T'; s = 'u'; break;
- case FUNC:
- if (tp->t_args != NULL && !tp->t_proto) {
- t = 'f';
- } else {
- t = 'F';
- }
- s = '\0';
- break;
- default:
- errx(1, "internal error: outtype() 1");
- }
- if (tp->t_const)
- outchar('c');
- if (tp->t_volatile)
- outchar('v');
- if (s != '\0')
- outchar(s);
- outchar(t);
- if (ts == ARRAY) {
- outint(tp->t_dim);
- } else if (ts == ENUM || ts == STRUCT || ts == UNION) {
- if (tp->t_istag) {
- outint(1);
- outname(tp->t_tag->h_name);
- } else if (tp->t_istynam) {
- outint(2);
- outname(tp->t_tynam->h_name);
- } else {
- outint(0);
- }
- } else if (ts == FUNC && tp->t_args != NULL) {
- na = 0;
- for (ap = tp->t_args; *ap != NULL; ap++)
- na++;
- if (tp->t_vararg)
- na++;
- outint(na);
- for (ap = tp->t_args; *ap != NULL; ap++)
- outtype(*ap);
- if (tp->t_vararg)
- outchar('E');
- }
- tp = tp->t_subt;
- }
-}
-
-/*
- * Write a definition.
- */
-static void
-outdef(hte_t *hte, sym_t *sym)
-{
- /* reset output buffer */
- outclr();
-
- /* line number in C source file */
- outint(0);
-
- /* this is a definition */
- outchar('d');
-
- /* index of file where symbol was defined and line number of def. */
- outint(0);
- outchar('.');
- outint(0);
-
- /* flags */
- if (sym->s_va) {
- outchar('v'); /* varargs */
- outint(sym->s_nva);
- }
- if (sym->s_scfl) {
- outchar('S'); /* scanflike */
- outint(sym->s_nscfl);
- }
- if (sym->s_prfl) {
- outchar('P'); /* printflike */
- outint(sym->s_nprfl);
- }
- /* definition or tentative definition */
- outchar(sym->s_def == DEF ? 'd' : 't');
- if (TP(sym->s_type)->t_tspec == FUNC) {
- if (sym->s_rval)
- outchar('r'); /* fkt. has return value */
- if (sym->s_osdef)
- outchar('o'); /* old style definition */
- }
- outchar('u'); /* used (no warning if not used) */
-
- /* name */
- outname(hte->h_name);
-
- /* type */
- outtype(TP(sym->s_type));
-}
-
-/*
- * Write the first definition of a name into the lint library.
- */
-static void
-dumpname(hte_t *hte)
-{
- sym_t *sym, *def;
-
- /* static and undefined symbols are not written */
- if (hte->h_static || !hte->h_def)
- return;
-
- /*
- * If there is a definition, write it. Otherwise write a tentative
- * definition. This is necessary because more than one tentative
- * definition is allowed (except with sflag).
- */
- def = NULL;
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- if (sym->s_def == DEF) {
- def = sym;
- break;
- }
- if (sym->s_def == TDEF && def == NULL)
- def = sym;
- }
- if (def == NULL)
- errx(1, "internal error: dumpname() %s", hte->h_name);
-
- outdef(hte, def);
-}
-
-/*
- * Write a new lint library.
- */
-void
-outlib(const char *name)
-{
- /* Open of output file and initialisation of the output buffer */
- outopen(name);
-
- /* write name of lint library */
- outsrc(name);
-
- /* name of lint lib has index 0 */
- outclr();
- outint(0);
- outchar('s');
- outstrg(name);
-
- /* write all definitions with external linkage */
- forall(dumpname);
-
- /* close the output */
- outclose();
-}
diff --git a/usr.bin/xlint/lint2/externs2.h b/usr.bin/xlint/lint2/externs2.h
deleted file mode 100644
index 0e54ce8dabe..00000000000
--- a/usr.bin/xlint/lint2/externs2.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* $OpenBSD: externs2.h,v 1.6 2006/05/29 20:47:22 cloder Exp $ */
-/* $NetBSD: externs2.h,v 1.2 1995/07/03 21:24:46 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * main.c
- */
-extern int xflag;
-extern int uflag;
-extern int Cflag;
-extern const char *libname;
-extern int pflag;
-extern int sflag;
-extern int Hflag;
-extern int hflag;
-extern int Fflag;
-
-
-/*
- * hash.c
- */
-extern void inithash(void);
-extern hte_t *hsearch(const char *, int);
-extern void forall(void (*)(hte_t *));
-
-/*
- * read.c
- */
-extern const char **fnames;
-extern type_t **tlst;
-extern int csrcfile;
-
-extern void readfile(const char *);
-extern void mkstatic(hte_t *);
-
-/*
- * mem2.c
- */
-extern void initmem(void);
-extern void *xalloc(size_t);
-
-/*
- * chk.c
- */
-extern void inittyp(void);
-extern void mainused(void);
-extern void chkname(hte_t *);
-
-/*
- * msg.c
- */
-extern void msg(int, ...);
-extern const char *mkpos(pos_t *);
-
-/*
- * emit2.c
- */
-extern void outlib(const char *);
diff --git a/usr.bin/xlint/lint2/hash.c b/usr.bin/xlint/lint2/hash.c
deleted file mode 100644
index 028c9b6dc51..00000000000
--- a/usr.bin/xlint/lint2/hash.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* $OpenBSD: hash.c,v 1.6 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: hash.c,v 1.2 1995/07/03 21:24:47 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <limits.h>
-
-#include "lint2.h"
-
-/* pointer to hash table, initialized in inithash() */
-static hte_t **htab;
-
-static int hash(const char *);
-
-/*
- * Initialize hash table.
- */
-void
-inithash(void)
-{
- htab = xcalloc(HSHSIZ2, sizeof (hte_t *));
-}
-
-/*
- * Compute hash value from a string.
- */
-static int
-hash(const char *s)
-{
- u_int v;
- const u_char *us;
-
- v = 0;
- for (us = (const u_char *)s; *us != '\0'; us++) {
- v = (v << sizeof (v)) + *us;
- v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
- }
- return (v % HSHSIZ2);
-}
-
-/*
- * Look for a hash table entry. If no hash table entry for the
- * given name exists and mknew is set, create a new one.
- */
-hte_t *
-hsearch(const char *s, int mknew)
-{
- int h;
- hte_t *hte;
-
- h = hash(s);
- for (hte = htab[h]; hte != NULL; hte = hte->h_link) {
- if (strcmp(hte->h_name, s) == 0)
- break;
- }
-
- if (hte != NULL || !mknew)
- return (hte);
-
- /* create a new hte */
- hte = xalloc(sizeof (hte_t));
- memset(hte, 0, sizeof (hte_t));
- hte->h_name = xstrdup(s);
- hte->h_lsym = &hte->h_syms;
- hte->h_lcall = &hte->h_calls;
- hte->h_lusym = &hte->h_usyms;
- hte->h_link = htab[h];
- htab[h] = hte;
-
- return (hte);
-}
-
-/*
- * Call function f for each name in the hash table.
- */
-void
-forall(void (*f)(hte_t *))
-{
- int i;
- hte_t *hte;
-
- for (i = 0; i < HSHSIZ2; i++) {
- for (hte = htab[i]; hte != NULL; hte = hte->h_link)
- (*f)(hte);
- }
-}
diff --git a/usr.bin/xlint/lint2/lint2.h b/usr.bin/xlint/lint2/lint2.h
deleted file mode 100644
index 8ddc1a9d80d..00000000000
--- a/usr.bin/xlint/lint2/lint2.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/* $OpenBSD: lint2.h,v 1.3 2005/11/20 17:42:50 deraadt Exp $ */
-/* $NetBSD: lint2.h,v 1.2 1995/07/03 21:24:49 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "lint.h"
-
-/*
- * Types are described by structures of type type_t.
- */
-typedef struct type {
- tspec_t t_tspec; /* type specifier */
- u_int t_const : 1; /* constant */
- u_int t_volatile : 1; /* volatile */
- u_int t_vararg : 1; /* function has variable number of arguments */
- u_int t_isenum : 1; /* enum type */
- u_int t_proto : 1; /* this is a prototype */
- u_int t_istag : 1; /* tag with _t_tag valid */
- u_int t_istynam : 1; /* tag with _t_tynam valid */
- union {
- int _t_dim; /* if the type is an ARRAY than this
- is the dimension of the array. */
- struct hte *_t_tag; /* hash table entry of tag if
- t_isenum, STRUCT or UNION */
- struct hte *_t_tynam; /* hash table entry of typename if
- t_isenum, STRUCT or UNION */
- struct type **_t_args; /* list of argument types if this
- is a prototype */
- } t_u;
- struct type *t_subt; /* indirected type (array element, pointed to
- type, type of return value) */
-} type_t;
-
-#define t_dim t_u._t_dim
-#define t_tag t_u._t_tag
-#define t_tynam t_u._t_tynam
-#define t_args t_u._t_args
-
-/*
- * argument information
- *
- * Such a structure is created for each argument of a function call
- * which is an integer constant or a constant string.
- */
-typedef struct arginf {
- int a_num; /* # of argument (1..) */
- u_int a_zero : 1; /* argument is 0 */
- u_int a_pcon : 1; /* msb of argument is not set */
- u_int a_ncon : 1; /* msb of argument is set */
- u_int a_fmt : 1; /* a_fstrg points to format string */
- char *a_fstrg; /* format string */
- struct arginf *a_nxt; /* information for next const. argument */
-} arginf_t;
-
-/*
- * Keeps information about position in source file.
- */
-typedef struct {
- u_short p_src; /* index of name of translation unit
- (the name which was specified at the
- command line) */
- u_short p_line; /* line number in p_src */
- u_short p_isrc; /* index of (included) file */
- u_short p_iline; /* line number in p_iline */
-} pos_t;
-
-/*
- * Used for definitions and declarations
- *
- * To save memory, variable sized structures are used. If
- * all s_va, s_prfl and s_scfl are not set, the memory allocated
- * for a symbol is only large enough to keep the first member of
- * struct sym, s_s.
- */
-typedef struct sym {
- struct {
- pos_t s_pos; /* pos of def./decl. */
-#ifndef lint
- u_int s_def : 3; /* DECL, TDEF or DEF */
-#else
- def_t s_def;
-#endif
- u_int s_rval : 1; /* function has return value */
- u_int s_osdef : 1; /* old style function definition */
- u_int s_static : 1; /* symbol is static */
- u_int s_va : 1; /* check only first s_nva arguments */
- u_int s_prfl : 1; /* printflike */
- u_int s_scfl : 1; /* scanflike */
- u_short s_type; /* type */
- struct sym *s_nxt; /* next symbol with same name */
- } s_s;
- short s_nva;
- short s_nprfl;
- short s_nscfl;
-} sym_t;
-
-#define s_pos s_s.s_pos
-#define s_rval s_s.s_rval
-#define s_osdef s_s.s_osdef
-#define s_static s_s.s_static
-#define s_def s_s.s_def
-#define s_va s_s.s_va
-#define s_prfl s_s.s_prfl
-#define s_scfl s_s.s_scfl
-#define s_type s_s.s_type
-#define s_nxt s_s.s_nxt
-
-/*
- * Used to store informations about function calls.
- */
-typedef struct fcall {
- pos_t f_pos; /* position of call */
- u_int f_rused : 1; /* return value used */
- u_int f_rdisc : 1; /* return value discarded (casted to void) */
- u_short f_type; /* types of expected return value and args */
- arginf_t *f_args; /* information about constant arguments */
- struct fcall *f_nxt; /* next call of same function */
-} fcall_t;
-
-/*
- * Used to store information about usage of symbols other
- * than for function calls.
- */
-typedef struct usym {
- pos_t u_pos; /* position */
- struct usym *u_nxt; /* next usage */
-} usym_t;
-
-/*
- * hash table entry
- */
-typedef struct hte {
- const char *h_name; /* name */
- u_int h_used : 1; /* symbol is used */
- u_int h_def : 1; /* symbol is defined */
- u_int h_static : 1; /* static symbol */
- sym_t *h_syms; /* declarations and definitions */
- sym_t **h_lsym; /* points to s_nxt of last decl./def. */
- fcall_t *h_calls; /* function calls */
- fcall_t **h_lcall; /* points to f_nxt of last call */
- usym_t *h_usyms; /* usage info */
- usym_t **h_lusym; /* points to u_nxt of last usage info */
- struct hte *h_link; /* next hte with same hash function */
-} hte_t;
-
-/* maps type indices into pointers to type structs */
-#define TP(idx) (tlst[idx])
-
-#include "externs2.h"
diff --git a/usr.bin/xlint/lint2/main2.c b/usr.bin/xlint/lint2/main2.c
deleted file mode 100644
index bd80c945aa6..00000000000
--- a/usr.bin/xlint/lint2/main2.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* $OpenBSD: main2.c,v 1.10 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: main2.c,v 1.2 1995/07/03 21:24:53 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "lint2.h"
-
-/* warnings for symbols which are declared but not defined or used */
-int xflag;
-
-/*
- * warnings for symbols which are used and not defined or defined
- * and not used
- */
-int uflag = 1;
-
-/* Create a lint library in the current directory with name libname. */
-int Cflag;
-const char *libname;
-
-int pflag;
-
-/*
- * warnings for (tentative) definitions of the same name in more than
- * one translation unit
- */
-int sflag;
-
-/*
- * If a complaint stems from a included file, print the name of the included
- * file instead of the name spezified at the command line followed by '?'
- */
-int Hflag;
-
-int hflag;
-
-/* Print full path names, not only the last component */
-int Fflag = 1;
-
-/*
- * List of libraries (from -l flag). These libraries are read after all
- * other input files has been read and, for Cflag, after the new lint library
- * has been written.
- */
-const char **libs;
-
-static void usage(void);
-
-
-int
-main(int argc, char *argv[])
-{
- int c, i;
- size_t len;
- char *lname;
-
- libs = xcalloc(1, sizeof (char *));
-
- opterr = 0;
- while ((c = getopt(argc, argv, "hpstxuC:HFl:")) != -1) {
- switch (c) {
- case 's':
- sflag = 1;
- break;
- case 'u':
- uflag = 0;
- break;
- case 'x':
- xflag = 1;
- break;
- case 'p':
- pflag = 1;
- break;
- case 'C':
- len = strlen(optarg);
- lname = xmalloc(len + 10);
- (void)snprintf(lname, len + 10, "llib-l%s.ln", optarg);
- libname = lname;
- Cflag = 1;
- uflag = 0;
- break;
- case 'H':
- Hflag = 1;
- break;
- case 'h':
- hflag = 1;
- break;
- case 'F':
- Fflag = 1;
- break;
- case 'l':
- for (i = 0; libs[i] != NULL; i++) ;
- libs = xrealloc(libs, (i + 2) * sizeof (char *));
- libs[i] = xstrdup(optarg);
- libs[i + 1] = NULL;
- break;
- case '?':
- usage();
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- usage();
-
- initmem();
-
- /* initialize hash table */
- inithash();
-
- inittyp();
-
- for (i = 0; i < argc; i++)
- readfile(argv[i]);
-
- /* write the lint library */
- if (Cflag) {
- forall(mkstatic);
- outlib(libname);
- }
-
- /* read additional libraries */
- for (i = 0; libs[i] != NULL; i++)
- readfile(libs[i]);
-
- forall(mkstatic);
-
- mainused();
-
- /* perform all tests */
- forall(chkname);
-
- exit(0);
- /* NOTREACHED */
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr,
- "usage: lint2 -hpstxuHF -Clib -l lib ... src1 ...\n");
- exit(1);
-}
-
diff --git a/usr.bin/xlint/lint2/mem2.c b/usr.bin/xlint/lint2/mem2.c
deleted file mode 100644
index 6f60ac50283..00000000000
--- a/usr.bin/xlint/lint2/mem2.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* $OpenBSD: mem2.c,v 1.5 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: mem2.c,v 1.3 1995/10/02 17:27:11 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <string.h>
-#include <err.h>
-
-#include "lint2.h"
-
-/* length of new allocated memory blocks */
-static size_t mblklen;
-
-/* offset of next free byte in mbuf */
-static size_t nxtfree;
-
-/* current buffer to server memory requests from */
-static void *mbuf;
-
-void
-initmem(void)
-{
- int pgsz;
-
- pgsz = getpagesize();
- mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz;
-
- nxtfree = mblklen;
-}
-
-/*
- * Allocate memory in large chunks to avoid space and time overhead of
- * malloc(). This is possible because memory allocated by xalloc()
- * need never to be freed.
- */
-void *
-xalloc(size_t sz)
-{
- void *ptr;
- int prot, flags;
-
- sz = ALIGN(sz);
- if (nxtfree + sz > mblklen) {
- /* use mmap() instead of malloc() to avoid malloc overhead. */
- prot = PROT_READ | PROT_WRITE;
- flags = MAP_ANON | MAP_PRIVATE;
- mbuf = mmap(NULL, mblklen, prot, flags, -1, (off_t)0);
- if (mbuf == MAP_FAILED)
- err(1, "can't map memory");
- if (ALIGN((u_long)mbuf) != (u_long)mbuf)
- errx(1, "mapped address is not aligned");
- (void)memset(mbuf, 0, mblklen);
- nxtfree = 0;
- }
-
- ptr = (char *)mbuf + nxtfree;
- nxtfree += sz;
-
- return (ptr);
-}
diff --git a/usr.bin/xlint/lint2/msg.c b/usr.bin/xlint/lint2/msg.c
deleted file mode 100644
index ec61ad92a2c..00000000000
--- a/usr.bin/xlint/lint2/msg.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* $OpenBSD: msg.c,v 1.9 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: msg.c,v 1.2 1995/07/03 21:24:56 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "lint2.h"
-
-
-static const char *msgs[] = {
- "%s: %s used, but not defined", /* 0 */
- "%s: %s defined, but never used", /* 1 */
- "%s: %s declared, but never used or defined", /* 2 */
- "%s: %s multiply defined (%s)", /* 3 */
- "%s: %s used inconsistently (%s)", /* 4 */
- "%s: %s declared inconsistently (%s)", /* 5 */
- "%s: %s arg %d used inconsistently (%s)", /* 6 */
- "%s: %s called with varying # of args (%s)", /* 7 */
- "%s returns value which is always ignored", /* 8 */
- "%s returns value which is sometimes ignored", /* 9 */
- "%s: return value of %s is used, but none returned", /* 10 */
- "%s: %s arg %d declared inconsistently (%s)", /* 11 */
- "%s: %s declared with varying # of args (%s)", /* 12 */
- "%s: malformed format string to %s", /* 13 */
- "%s, arg %d to %s inconsistent with format", /* 14 */
- "%s: too few format args to %s", /* 15 */
- "%s: too many format args to %s", /* 16 */
- "%s: %s must be declared before use (%s)", /* 17 */
-};
-
-static const char *lbasename(const char *);
-
-void
-msg(int n, ...)
-{
- va_list ap;
-
- va_start(ap, n);
-
- (void)vprintf(msgs[n], ap);
- (void)printf("\n");
-
- va_end(ap);
-}
-
-/*
- * Return a pointer to the last component of a path.
- */
-static const char *
-lbasename(const char *path)
-{
- const char *cp, *cp1, *cp2;
-
- if (Fflag)
- return (path);
-
- cp = cp1 = cp2 = path;
- while (*cp != '\0') {
- if (*cp++ == '/') {
- cp2 = cp1;
- cp1 = cp;
- }
- }
- return (*cp1 == '\0' ? cp2 : cp1);
-}
-
-/*
- * Create a string which describes a position in a source file.
- */
-const char *
-mkpos(pos_t *posp)
-{
- size_t len;
- const char *fn;
- static char *buf;
- static size_t blen = 0;
- int qm, src, line;
-
- if (Hflag && posp->p_src != posp->p_isrc) {
- src = posp->p_isrc;
- line = posp->p_iline;
- } else {
- src = posp->p_src;
- line = posp->p_line;
- }
- qm = !Hflag && posp->p_src != posp->p_isrc;
-
- len = strlen(fn = lbasename(fnames[src]));
- len += 3 * sizeof (u_short) + 4;
-
- if (len > blen)
- buf = xrealloc(buf, blen = len);
- if (line != 0) {
- (void)snprintf(buf, blen, "%s%s:%hu",
- fn, qm ? "?" : "", line);
- } else {
- (void)snprintf(buf, blen, "%s", fn);
- }
-
- return (buf);
-}
-
diff --git a/usr.bin/xlint/lint2/read.c b/usr.bin/xlint/lint2/read.c
deleted file mode 100644
index 7564eba0fd9..00000000000
--- a/usr.bin/xlint/lint2/read.c
+++ /dev/null
@@ -1,1132 +0,0 @@
-/* $OpenBSD: read.c,v 1.12 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: read.c,v 1.2 1995/07/03 21:24:59 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <err.h>
-
-#include "lint2.h"
-
-
-/* index of current (included) source file */
-static int srcfile;
-
-/*
- * The array pointed to by inpfns maps the file name indices of input files
- * to the file name indices used in lint2
- */
-static short *inpfns;
-static size_t ninpfns;
-
-/*
- * The array pointed to by *fnames maps file name indizes to file names.
- * Indices of type short are used instead of pointers to save memory.
- */
-const char **fnames;
-static size_t nfnames;
-
-/*
- * Types are shared (to save memory for the types itself) and accessed
- * via indices (to save memory for references to types (indices are short)).
- * To share types, a equal type must be located fast. This is done by a
- * hash table. Access by indices is done via an array of pointers to the
- * types.
- */
-typedef struct thtab {
- const char *th_name;
- u_short th_idx;
- struct thtab *th_nxt;
-} thtab_t;
-static thtab_t **thtab; /* hash table */
-type_t **tlst; /* array for indexed access */
-static size_t tlstlen; /* length of tlst */
-
-/* index of current C source file (as spezified at the command line) */
-int csrcfile;
-
-
-static void inperr(void);
-static void setsrc(const char *);
-static void setfnid(int, const char *);
-static void funccall(pos_t *, const char *);
-static void decldef(pos_t *, const char *);
-static void usedsym(pos_t *, const char *);
-static u_short inptype(const char *, const char **);
-static int gettlen(const char *, const char **);
-static u_short findtype(const char *, size_t, int);
-static u_short storetyp(type_t *, const char *, size_t, int);
-static int thash(const char *, size_t);
-static char *inpqstrg(const char *, const char **);
-static const char *inpname(const char *, const char **);
-static int getfnidx(const char *);
-
-void
-readfile(const char *name)
-{
- FILE *inp;
- size_t len;
- const char *cp;
- char *line, *eptr, rt;
- int cline, isrc, iline;
- pos_t pos;
-
- if (inpfns == NULL)
- inpfns = xcalloc(ninpfns = 128, sizeof (short));
- if (fnames == NULL)
- fnames = xcalloc(nfnames = 256, sizeof (char *));
- if (tlstlen == 0)
- tlst = xcalloc(tlstlen = 256, sizeof (type_t *));
- if (thtab == NULL)
- thtab = xcalloc(THSHSIZ2, sizeof (thtab_t));
-
- srcfile = getfnidx(name);
-
- if ((inp = fopen(name, "r")) == NULL)
- err(1, "cannot open %s", name);
-
- while ((line = fgetln(inp, &len)) != NULL) {
-
- if (len == 0 || line[len - 1] != '\n')
- inperr();
- line[len - 1] = '\0';
- cp = line;
-
- /* line number in csrcfile */
- cline = (int)strtol(cp, &eptr, 10);
- if (cp == eptr) {
- cline = -1;
- } else {
- cp = eptr;
- }
-
- /* record type */
- if (*cp != '\0') {
- rt = *cp++;
- } else {
- inperr();
- }
-
- if (rt == 'S') {
- setsrc(cp);
- continue;
- } else if (rt == 's') {
- setfnid(cline, cp);
- continue;
- }
-
- /*
- * Index of (included) source file. If this index is
- * different from csrcfile, it refers to an included
- * file.
- */
- isrc = (int)strtol(cp, &eptr, 10);
- if (cp == eptr)
- inperr();
- cp = eptr;
- if (isrc < 0 || isrc >= ninpfns)
- inperr();
- isrc = inpfns[isrc];
-
- /* line number in isrc */
- if (*cp++ != '.')
- inperr();
- iline = (int)strtol(cp, &eptr, 10);
- if (cp == eptr)
- inperr();
- cp = eptr;
-
- pos.p_src = (u_short)csrcfile;
- pos.p_line = (u_short)cline;
- pos.p_isrc = (u_short)isrc;
- pos.p_iline = (u_short)iline;
-
- /* process rest of this record */
- switch (rt) {
- case 'c':
- funccall(&pos, cp);
- break;
- case 'd':
- decldef(&pos, cp);
- break;
- case 'u':
- usedsym(&pos, cp);
- break;
- default:
- inperr();
- }
-
- }
-
- if (ferror(inp))
- err(1, "read error on %s", name);
-
- (void)fclose(inp);
-}
-
-
-static void
-inperr(void)
-{
- errx(1, "input file error: %s", fnames[srcfile]);
-}
-
-/*
- * Set the name of the C source file of the .ln file which is
- * currently read.
- */
-static void
-setsrc(const char *cp)
-{
- csrcfile = getfnidx(cp);
-}
-
-/*
- * setfnid() gets as input an index as used in an input file and the
- * associated file name. If necessary, it creates a new lint2 file
- * name index for this file name and creates the mapping of the index
- * as used in the input file to the index used in lint2.
- */
-static void
-setfnid(int fid, const char *cp)
-{
- if (fid == -1)
- inperr();
-
- if (fid >= ninpfns) {
- inpfns = xrealloc(inpfns, (ninpfns * 2) * sizeof (short));
- (void)memset(inpfns + ninpfns, 0, ninpfns * sizeof (short));
- ninpfns *= 2;
- }
- /*
- * Should always be true because indices written in the output
- * file by lint1 are always the previous index + 1.
- */
- if (fid >= ninpfns)
- errx(1, "internal error: setfnid()");
- inpfns[fid] = (u_short)getfnidx(cp);
-}
-
-/*
- * Process a function call record (c-record).
- */
-static void
-funccall(pos_t *posp, const char *cp)
-{
- arginf_t *ai, **lai;
- char c, *eptr;
- int rused, rdisc;
- hte_t *hte;
- fcall_t *fcall;
-
- fcall = xalloc(sizeof (fcall_t));
- STRUCT_ASSIGN(fcall->f_pos, *posp);
-
- /* read flags */
- rused = rdisc = 0;
- lai = &fcall->f_args;
- while ((c = *cp) == 'u' || c == 'i' || c == 'd' ||
- c == 'z' || c == 'p' || c == 'n' || c == 's') {
- cp++;
- switch (c) {
- case 'u':
- if (rused || rdisc)
- inperr();
- rused = 1;
- break;
- case 'i':
- if (rused || rdisc)
- inperr();
- break;
- case 'd':
- if (rused || rdisc)
- inperr();
- rdisc = 1;
- break;
- case 'z':
- case 'p':
- case 'n':
- case 's':
- ai = xalloc(sizeof (arginf_t));
- ai->a_num = (int)strtol(cp, &eptr, 10);
- if (cp == eptr)
- inperr();
- cp = eptr;
- if (c == 'z') {
- ai->a_pcon = ai->a_zero = 1;
- } else if (c == 'p') {
- ai->a_pcon = 1;
- } else if (c == 'n') {
- ai->a_ncon = 1;
- } else {
- ai->a_fmt = 1;
- ai->a_fstrg = inpqstrg(cp, &cp);
- }
- *lai = ai;
- lai = &ai->a_nxt;
- break;
- }
- }
- fcall->f_rused = rused;
- fcall->f_rdisc = rdisc;
-
- /* read name of function */
- hte = hsearch(inpname(cp, &cp), 1);
- hte->h_used = 1;
-
- fcall->f_type = inptype(cp, &cp);
-
- *hte->h_lcall = fcall;
- hte->h_lcall = &fcall->f_nxt;
-
- if (*cp != '\0')
- inperr();
-}
-
-/*
- * Process a declaration or definition (d-record).
- */
-static void
-decldef(pos_t *posp, const char *cp)
-{
- sym_t *symp, sym;
- char c, *ep;
- int used;
- hte_t *hte;
-
- (void)memset(&sym, 0, sizeof (sym));
- STRUCT_ASSIGN(sym.s_pos, *posp);
- sym.s_def = NODECL;
-
- used = 0;
-
- while ((c = *cp) == 't' || c == 'd' || c == 'e' || c == 'u' ||
- c == 'r' || c == 'o' || c == 's' || c == 'v' ||
- c == 'P' || c == 'S') {
- cp++;
- switch (c) {
- case 't':
- if (sym.s_def != NODECL)
- inperr();
- sym.s_def = TDEF;
- break;
- case 'd':
- if (sym.s_def != NODECL)
- inperr();
- sym.s_def = DEF;
- break;
- case 'e':
- if (sym.s_def != NODECL)
- inperr();
- sym.s_def = DECL;
- break;
- case 'u':
- if (used)
- inperr();
- used = 1;
- break;
- case 'r':
- if (sym.s_rval)
- inperr();
- sym.s_rval = 1;
- break;
- case 'o':
- if (sym.s_osdef)
- inperr();
- sym.s_osdef = 1;
- break;
- case 's':
- if (sym.s_static)
- inperr();
- sym.s_static = 1;
- break;
- case 'v':
- if (sym.s_va)
- inperr();
- sym.s_va = 1;
- sym.s_nva = (short)strtol(cp, &ep, 10);
- if (cp == ep)
- inperr();
- cp = ep;
- break;
- case 'P':
- if (sym.s_prfl)
- inperr();
- sym.s_prfl = 1;
- sym.s_nprfl = (short)strtol(cp, &ep, 10);
- if (cp == ep)
- inperr();
- cp = ep;
- break;
- case 'S':
- if (sym.s_scfl)
- inperr();
- sym.s_scfl = 1;
- sym.s_nscfl = (short)strtol(cp, &ep, 10);
- if (cp == ep)
- inperr();
- cp = ep;
- break;
- }
- }
-
- /* read symbol name */
- hte = hsearch(inpname(cp, &cp), 1);
- hte->h_used |= used;
- if (sym.s_def == DEF || sym.s_def == TDEF)
- hte->h_def = 1;
-
- sym.s_type = inptype(cp, &cp);
-
- /*
- * Allocate memory for this symbol only if it was not already
- * declared or tentatively defined at the same location with
- * the same type. Works only for symbols with external linkage,
- * because static symbols, tentatively defined at the same location
- * but in different translation units are really different symbols.
- */
- for (symp = hte->h_syms; symp != NULL; symp = symp->s_nxt) {
- if (symp->s_pos.p_isrc == sym.s_pos.p_isrc &&
- symp->s_pos.p_iline == sym.s_pos.p_iline &&
- symp->s_type == sym.s_type &&
- ((symp->s_def == DECL && sym.s_def == DECL) ||
- (!sflag && symp->s_def == TDEF && sym.s_def == TDEF)) &&
- !symp->s_static && !sym.s_static) {
- break;
- }
- }
-
- if (symp == NULL) {
- /* allocsym reserviert keinen Platz fuer s_nva */
- if (sym.s_va || sym.s_prfl || sym.s_scfl) {
- symp = xalloc(sizeof (sym_t));
- STRUCT_ASSIGN(*symp, sym);
- } else {
- symp = xalloc(sizeof (symp->s_s));
- STRUCT_ASSIGN(symp->s_s, sym.s_s);
- }
- *hte->h_lsym = symp;
- hte->h_lsym = &symp->s_nxt;
- }
-
- if (*cp != '\0')
- inperr();
-}
-
-/*
- * Read an u-record (emited by lint1 if a symbol was used).
- */
-static void
-usedsym(pos_t *posp, const char *cp)
-{
- usym_t *usym;
- hte_t *hte;
-
- usym = xalloc(sizeof (usym_t));
- STRUCT_ASSIGN(usym->u_pos, *posp);
-
- /* needed as delimiter between two numbers */
- if (*cp++ != 'x')
- inperr();
-
- hte = hsearch(inpname(cp, &cp), 1);
- hte->h_used = 1;
-
- *hte->h_lusym = usym;
- hte->h_lusym = &usym->u_nxt;
-}
-
-/*
- * Read a type and return the index of this type.
- */
-static u_short
-inptype(const char *cp, const char **epp)
-{
- char c, s, *eptr;
- const char *ep;
- type_t *tp;
- int narg, i, osdef;
- size_t tlen;
- u_short tidx;
- int h;
-
- /* If we have this type already, return it's index. */
- tlen = gettlen(cp, &ep);
- h = thash(cp, tlen);
- if ((tidx = findtype(cp, tlen, h)) != 0) {
- *epp = ep;
- return (tidx);
- }
-
- /* No, we must create a new type. */
- tp = xalloc(sizeof (type_t));
-
- tidx = storetyp(tp, cp, tlen, h);
-
- c = *cp++;
-
- while (c == 'c' || c == 'v') {
- if (c == 'c') {
- tp->t_const = 1;
- } else {
- tp->t_volatile = 1;
- }
- c = *cp++;
- }
-
- if (c == 's' || c == 'u' || c == 'l' || c == 'e') {
- s = c;
- c = *cp++;
- } else {
- s = '\0';
- }
-
- switch (c) {
- case 'B':
- tp->t_tspec = BOOL;
- break;
- case 'C':
- tp->t_tspec = s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR);
- break;
- case 'S':
- tp->t_tspec = s == 'u' ? USHORT : SHORT;
- break;
- case 'I':
- tp->t_tspec = s == 'u' ? UINT : INT;
- break;
- case 'L':
- tp->t_tspec = s == 'u' ? ULONG : LONG;
- break;
- case 'Q':
- tp->t_tspec = s == 'u' ? UQUAD : QUAD;
- break;
- case 'D':
- tp->t_tspec = s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE);
- break;
- case 'X':
- tp->t_tspec = s == 's' ? COMPLEX : (s == 'l' ?
- LDCOMPLEX : DCOMPLEX);
- break;
- case 'J':
- tp->t_tspec = s == 's' ? IMAGINARY : (s == 'l' ?
- LDIMAGINARY : DIMAGINARY);
- break;
- case 'V':
- tp->t_tspec = VOID;
- break;
- case 'P':
- tp->t_tspec = PTR;
- break;
- case 'A':
- tp->t_tspec = ARRAY;
- break;
- case 'F':
- case 'f':
- osdef = c == 'f';
- tp->t_tspec = FUNC;
- break;
- case 'T':
- tp->t_tspec = s == 'e' ? ENUM : (s == 's' ? STRUCT : UNION);
- break;
- }
-
- switch (tp->t_tspec) {
- case ARRAY:
- tp->t_dim = (int)strtol(cp, &eptr, 10);
- cp = eptr;
- tp->t_subt = TP(inptype(cp, &cp));
- break;
- case PTR:
- tp->t_subt = TP(inptype(cp, &cp));
- break;
- case FUNC:
- c = *cp;
- if (isdigit((u_char)c)) {
- if (!osdef)
- tp->t_proto = 1;
- narg = (int)strtol(cp, &eptr, 10);
- cp = eptr;
- tp->t_args = xcalloc((size_t)(narg + 1),
- sizeof (type_t *));
- for (i = 0; i < narg; i++) {
- if (i == narg - 1 && *cp == 'E') {
- tp->t_vararg = 1;
- cp++;
- } else {
- tp->t_args[i] = TP(inptype(cp, &cp));
- }
- }
- }
- tp->t_subt = TP(inptype(cp, &cp));
- break;
- case ENUM:
- tp->t_tspec = INT;
- tp->t_isenum = 1;
- /* FALLTHROUGH */
- case STRUCT:
- case UNION:
- switch (*cp++) {
- case '0':
- break;
- case '1':
- tp->t_istag = 1;
- tp->t_tag = hsearch(inpname(cp, &cp), 1);
- break;
- case '2':
- tp->t_istynam = 1;
- tp->t_tynam = hsearch(inpname(cp, &cp), 1);
- break;
- }
- break;
- /* LINTED (enumeration value(s) not handled in switch) */
- }
-
- *epp = cp;
- return (tidx);
-}
-
-/*
- * Get the length of a type string.
- */
-static int
-gettlen(const char *cp, const char **epp)
-{
- const char *cp1;
- char c, s, *eptr;
- tspec_t t;
- int narg, i, cm, vm;
-
- cp1 = cp;
-
- c = *cp++;
-
- cm = vm = 0;
-
- while (c == 'c' || c == 'v') {
- if (c == 'c') {
- if (cm)
- inperr();
- cm = 1;
- } else {
- if (vm)
- inperr();
- vm = 1;
- }
- c = *cp++;
- }
-
- if (c == 's' || c == 'u' || c == 'l' || c == 'e') {
- s = c;
- c = *cp++;
- } else {
- s = '\0';
- }
-
- t = NOTSPEC;
-
- switch (c) {
- case 'B':
- t = BOOL;
- break;
- case 'C':
- if (s == 's') {
- t = SCHAR;
- } else if (s == 'u') {
- t = UCHAR;
- } else if (s == '\0') {
- t = CHAR;
- }
- break;
- case 'S':
- if (s == 'u') {
- t = USHORT;
- } else if (s == '\0') {
- t = SHORT;
- }
- break;
- case 'I':
- if (s == 'u') {
- t = UINT;
- } else if (s == '\0') {
- t = INT;
- }
- break;
- case 'L':
- if (s == 'u') {
- t = ULONG;
- } else if (s == '\0') {
- t = LONG;
- }
- break;
- case 'Q':
- if (s == 'u') {
- t = UQUAD;
- } else if (s == '\0') {
- t = QUAD;
- }
- break;
- case 'D':
- if (s == 's') {
- t = FLOAT;
- } else if (s == 'l') {
- t = LDOUBLE;
- } else if (s == '\0') {
- t = DOUBLE;
- }
- break;
- case 'X':
- if (s == 's') {
- t = COMPLEX;
- } else if (s == 'l') {
- t = LDCOMPLEX;
- } else if (s == '\0') {
- t = DCOMPLEX;
- }
- break;
- case 'J':
- if (s == 's') {
- t = IMAGINARY;
- } else if (s == 'l') {
- t = LDIMAGINARY;
- } else if (s == '\0') {
- t = DIMAGINARY;
- }
- break;
- case 'V':
- if (s == '\0')
- t = VOID;
- break;
- case 'P':
- if (s == '\0')
- t = PTR;
- break;
- case 'A':
- if (s == '\0')
- t = ARRAY;
- break;
- case 'F':
- case 'f':
- if (s == '\0')
- t = FUNC;
- break;
- case 'T':
- if (s == 'e') {
- t = ENUM;
- } else if (s == 's') {
- t = STRUCT;
- } else if (s == 'u') {
- t = UNION;
- }
- break;
- default:
- inperr();
- }
-
- if (t == NOTSPEC)
- inperr();
-
- switch (t) {
- case ARRAY:
- (void)strtol(cp, &eptr, 10);
- if (cp == eptr)
- inperr();
- cp = eptr;
- (void)gettlen(cp, &cp);
- break;
- case PTR:
- (void)gettlen(cp, &cp);
- break;
- case FUNC:
- c = *cp;
- if (isdigit((u_char)c)) {
- narg = (int)strtol(cp, &eptr, 10);
- cp = eptr;
- for (i = 0; i < narg; i++) {
- if (i == narg - 1 && *cp == 'E') {
- cp++;
- } else {
- (void)gettlen(cp, &cp);
- }
- }
- }
- (void)gettlen(cp, &cp);
- break;
- case ENUM:
- case STRUCT:
- case UNION:
- switch (*cp++) {
- case '0':
- break;
- case '1':
- (void)inpname(cp, &cp);
- break;
- case '2':
- (void)inpname(cp, &cp);
- break;
- default:
- inperr();
- }
- break;
- /* LINTED (enumeration value(s) not handled in switch) */
- }
-
- *epp = cp;
- return (cp - cp1);
-}
-
-/*
- * Search a type by it's type string.
- */
-static u_short
-findtype(const char *cp, size_t len, int h)
-{
- thtab_t *thte;
-
- for (thte = thtab[h]; thte != NULL; thte = thte->th_nxt) {
- if (strncmp(thte->th_name, cp, len) != 0)
- continue;
- if (thte->th_name[len] == '\0')
- return (thte->th_idx);
- }
-
- return (0);
-}
-
-/*
- * Store a type and it's type string so we can later share this type
- * if we read the same type string from the input file.
- */
-static u_short
-storetyp(type_t *tp, const char *cp, size_t len, int h)
-{
- /* 0 ist reserved */
- static u_int tidx = 1;
- thtab_t *thte;
- char *name;
-
- if (tidx >= USHRT_MAX)
- errx(1, "sorry, too many types");
-
- if (tidx == tlstlen - 1) {
- tlst = xrealloc(tlst, (tlstlen * 2) * sizeof (type_t *));
- (void)memset(tlst + tlstlen, 0, tlstlen * sizeof (type_t *));
- tlstlen *= 2;
- }
-
- tlst[tidx] = tp;
-
- /* create a hash table entry */
- name = xalloc(len + 1);
- (void)memcpy(name, cp, len);
- name[len] = '\0';
-
- thte = xalloc(sizeof (thtab_t));
- thte->th_name = name;
- thte->th_idx = tidx;
- thte->th_nxt = thtab[h];
- thtab[h] = thte;
-
- return ((u_short)tidx++);
-}
-
-/*
- * Hash function for types
- */
-static int
-thash(const char *s, size_t len)
-{
- u_int v;
-
- v = 0;
- while (len-- != 0) {
- v = (v << sizeof (v)) + (u_char)*s++;
- v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
- }
- return (v % THSHSIZ2);
-}
-
-/*
- * Read a string enclosed by "". This string may contain quoted chars.
- */
-static char *
-inpqstrg(const char *src, const char **epp)
-{
- char *strg, *dst;
- size_t slen;
- int c;
- int v;
-
- dst = strg = xmalloc(slen = 32);
-
- if ((c = *src++) != '"')
- inperr();
- if ((c = *src++) == '\0')
- inperr();
-
- while (c != '"') {
- if (c == '\\') {
- if ((c = *src++) == '\0')
- inperr();
- switch (c) {
- case 'n':
- c = '\n';
- break;
- case 't':
- c = '\t';
- break;
- case 'v':
- c = '\v';
- break;
- case 'b':
- c = '\b';
- break;
- case 'r':
- c = '\r';
- break;
- case 'f':
- c = '\f';
- break;
- case 'a':
- c = '\a';
- break;
- case '\\':
- c = '\\';
- break;
- case '"':
- c = '"';
- break;
- case '\'':
- c = '\'';
- break;
- case '0': case '1': case '2': case '3':
- v = (c - '0') << 6;
- if ((c = *src++) < '0' || c > '7')
- inperr();
- v |= (c - '0') << 3;
- if ((c = *src++) < '0' || c > '7')
- inperr();
- v |= c - '0';
- c = (u_char)v;
- break;
- default:
- inperr();
- }
- }
- /* keep space for trailing '\0' */
- if (dst - strg == slen - 1) {
- strg = xrealloc(strg, slen * 2);
- dst = strg + (slen - 1);
- slen *= 2;
- }
- *dst++ = (char)c;
- if ((c = *src++) == '\0')
- inperr();
- }
- *dst = '\0';
-
- *epp = src;
- return (strg);
-}
-
-/*
- * Read the name of a symbol in static memory.
- */
-static const char *
-inpname(const char *cp, const char **epp)
-{
- static char *buf;
- static size_t blen = 0;
- size_t len, i;
- char *eptr, c;
-
- len = (int)strtol(cp, &eptr, 10);
- if (cp == eptr)
- inperr();
- cp = eptr;
- if (len + 1 > blen)
- buf = xrealloc(buf, blen = len + 1);
- for (i = 0; i < len; i++) {
- c = *cp++;
- if (!isalnum(c) && c != '_')
- inperr();
- buf[i] = c;
- }
- buf[i] = '\0';
-
- *epp = cp;
- return (buf);
-}
-
-/*
- * Return the index of a file name. If the name cannot be found, create
- * a new entry and return the index of the newly created entry.
- */
-static int
-getfnidx(const char *fn)
-{
- int i;
-
- /* 0 ist reserved */
- for (i = 1; fnames[i] != NULL; i++) {
- if (strcmp(fnames[i], fn) == 0)
- break;
- }
- if (fnames[i] != NULL)
- return (i);
-
- if (i == nfnames - 1) {
- fnames = xrealloc(fnames, (nfnames * 2) * sizeof (char *));
- (void)memset(fnames + nfnames, 0, nfnames * sizeof (char *));
- nfnames *= 2;
- }
-
- fnames[i] = xstrdup(fn);
- return (i);
-}
-
-/*
- * Separate symbols with static and external linkage.
- */
-void
-mkstatic(hte_t *hte)
-{
- sym_t *sym1, **symp, *sym;
- fcall_t **callp, *call;
- usym_t **usymp, *usym;
- hte_t *nhte;
- int ofnd;
-
- /* Look for first static definition */
- for (sym1 = hte->h_syms; sym1 != NULL; sym1 = sym1->s_nxt) {
- if (sym1->s_static)
- break;
- }
- if (sym1 == NULL)
- return;
-
- /* Do nothing if this name is used only in one translation unit. */
- ofnd = 0;
- for (sym = hte->h_syms; sym != NULL && !ofnd; sym = sym->s_nxt) {
- if (sym->s_pos.p_src != sym1->s_pos.p_src)
- ofnd = 1;
- }
- for (call = hte->h_calls; call != NULL && !ofnd; call = call->f_nxt) {
- if (call->f_pos.p_src != sym1->s_pos.p_src)
- ofnd = 1;
- }
- for (usym = hte->h_usyms; usym != NULL && !ofnd; usym = usym->u_nxt) {
- if (usym->u_pos.p_src != sym1->s_pos.p_src)
- ofnd = 1;
- }
- if (!ofnd) {
- hte->h_used = 1;
- /* errors about undef. static symbols are printed in lint1 */
- hte->h_def = 1;
- hte->h_static = 1;
- return;
- }
-
- /*
- * Create a new hash table entry
- *
- * XXX this entry should be put at the beginning of the list to
- * avoid to process the same symbol twice.
- */
- for (nhte = hte; nhte->h_link != NULL; nhte = nhte->h_link) ;
- nhte->h_link = xalloc(sizeof (hte_t));
- memset(nhte->h_link, 0, sizeof (hte_t));
- nhte = nhte->h_link;
- nhte->h_name = hte->h_name;
- nhte->h_static = 1;
- nhte->h_used = 1;
- nhte->h_def = 1; /* error in lint1 */
- nhte->h_lsym = &nhte->h_syms;
- nhte->h_lcall = &nhte->h_calls;
- nhte->h_lusym = &nhte->h_usyms;
-
- /*
- * move all symbols used in this translation unit into the new
- * hash table entry.
- */
- for (symp = &hte->h_syms; (sym = *symp) != NULL; ) {
- if (sym->s_pos.p_src == sym1->s_pos.p_src) {
- sym->s_static = 1;
- (*symp) = sym->s_nxt;
- if (hte->h_lsym == &sym->s_nxt)
- hte->h_lsym = symp;
- sym->s_nxt = NULL;
- *nhte->h_lsym = sym;
- nhte->h_lsym = &sym->s_nxt;
- } else {
- symp = &sym->s_nxt;
- }
- }
- for (callp = &hte->h_calls; (call = *callp) != NULL; ) {
- if (call->f_pos.p_src == sym1->s_pos.p_src) {
- (*callp) = call->f_nxt;
- if (hte->h_lcall == &call->f_nxt)
- hte->h_lcall = callp;
- call->f_nxt = NULL;
- *nhte->h_lcall = call;
- nhte->h_lcall = &call->f_nxt;
- } else {
- callp = &call->f_nxt;
- }
- }
- for (usymp = &hte->h_usyms; (usym = *usymp) != NULL; ) {
- if (usym->u_pos.p_src == sym1->s_pos.p_src) {
- (*usymp) = usym->u_nxt;
- if (hte->h_lusym == &usym->u_nxt)
- hte->h_lusym = usymp;
- usym->u_nxt = NULL;
- *nhte->h_lusym = usym;
- nhte->h_lusym = &usym->u_nxt;
- } else {
- usymp = &usym->u_nxt;
- }
- }
-
- /* h_def must be recalculated for old hte */
- hte->h_def = nhte->h_def = 0;
- for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) {
- if (sym->s_def == DEF || sym->s_def == TDEF) {
- hte->h_def = 1;
- break;
- }
- }
-
- mkstatic(hte);
-}
diff --git a/usr.bin/xlint/llib/Makefile b/usr.bin/xlint/llib/Makefile
deleted file mode 100644
index 59f1b431107..00000000000
--- a/usr.bin/xlint/llib/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-# $OpenBSD: Makefile,v 1.4 1997/04/27 20:56:59 millert Exp $
-# $NetBSD: Makefile,v 1.2 1995/07/03 21:25:05 cgd Exp $
-
-LIBS= llib-lposix.ln llib-lstdc.ln
-
-all: ${LIBS}
-
-install:
- ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${NONBINMODE} \
- ${LIBS} ${DESTDIR}${LINTLIBDIR}
-
-clean cleanall:
- rm -f ${LIBS}
-
-llib-lposix.ln: llib-lposix
- lint -Cposix ${.ALLSRC}
-
-llib-lstdc.ln: llib-lstdc
- lint -Cstdc ${.ALLSRC}
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/xlint/llib/llib-lposix b/usr.bin/xlint/llib/llib-lposix
deleted file mode 100644
index 31bde403454..00000000000
--- a/usr.bin/xlint/llib/llib-lposix
+++ /dev/null
@@ -1,410 +0,0 @@
-/* $OpenBSD: llib-lposix,v 1.4 2010/12/30 21:45:31 guenther Exp $ */
-/* $NetBSD: llib-lposix,v 1.2 1995/07/03 21:25:09 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* LINTLIBRARY */
-
-#define _POSIX_SOURCE
-#define _ANSI_LIBRARY
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/times.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <math.h>
-#include <time.h>
-#include <assert.h>
-#include <termios.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <signal.h>
-#include <locale.h>
-#include <setjmp.h>
-#include <string.h>
-#include <syslog.h>
-#include <utime.h>
-#include <wchar.h>
-#include <wctype.h>
-
-
-/* PROTOLIB1 */
-
-
-void (abort)(void);
-int (abs)(int j);
-int (access)(const char *path, int amode);
-double (acos)(double x);
-unsigned (alarm)(unsigned seconds);
-char *(asctime)(const struct tm *timeptr);
-double (asin)(double x);
-void (__assert)(const char *expression, int line, const char *file);
-double (atan)(double x);
-double (atan2)(double y, double x);
-int (atexit)(void (*func)(void));
-double (atof)(const char *nptr);
-int (atoi)(const char *nptr);
-long (atol)(const char *nptr);
-void *(bsearch)(const void *key, const void *base, size_t nmemb,
- size_t size, int (*compar)(const void *, const void *));
-wint_t (btowc)(int);
-void *(calloc)(size_t nmemb, size_t size);
-double (ceil)(double x);
-speed_t (cfgetispeed)(const struct termios *p);
-speed_t (cfgetospeed)(const struct termios *p);
-int (cfsetispeed)(struct termios *p, speed_t speed);
-int (cfsetospeed)(struct termios *p, speed_t speed);
-int (chdir)(const char *path);
-int (chmod)(const char *path, mode_t mode);
-int (chown)(const char *path, uid_t owner, gid_t group);
-void (clearerr)(FILE *stream);
-clock_t (clock)(void);
-int (close)(int fildes);
-int (closedir)(DIR *dirp);
-void (closelog)(void);
-double (cos)(double x);
-double (cosh)(double x);
-int (creat)(const char *path, mode_t mode);
-char *(ctermid)(char *s);
-char *(ctime)(const time_t *timer);
-char *(cuserid)(char *s);
-double (difftime)(time_t time1, time_t time0);
-div_t (div)(int numer, int denom);
-int (dup)(int fildes);
-int (dup2)(int fildes, int fildes2);
-int (errno);
-int (execl)(const char *path, const char *arg, ...);
-int (execle)(const char *path, const char *arg, ...);
-int (execlp)(const char *file, const char *arg, ...);
-int (execv)(const char *path, char *const argv[]);
-int (execve)(const char *path, char *const argv[], char *const *envp);
-int (execvp)(const char *file, char *const argv[]);
-void (exit)(int status);
-void (_exit)(int status);
-double (exp)(double x);
-double (fabs)(double x);
-int (fclose)(FILE *stream);
-int (fcntl)(int fildes, int cmd, ...);
-FILE *(fdopen)(int fildes, const char *type);
-int (feof)(FILE *stream);
-int (ferror)(FILE *stream);
-int (fflush)(FILE *stream);
-int (fgetc)(FILE *stream);
-int (fgetpos)(FILE *stream, fpos_t *pos);
-char *(fgets)(char *s, int n, FILE *stream);
-wint_t (fgetwc)(FILE *);
-wchar_t *(fgetws)(wchar_t *, int, FILE *);
-int (fileno)(FILE *stream);
-double (floor)(double x);
-double (fmod)(double x, double y);
-FILE *(fopen)(const char *filename, const char *mode);
-pid_t (fork)(void);
-long (fpathconf)(int fildes, int name);
-/* PRINTFLIKE2 */
-int (fprintf)(FILE *stream, const char *format, ...);
-int (fputc)(int c, FILE *stream);
-int (fputs)(const char *s, FILE *stream);
-wint_t (fputwc)(wchar_t, FILE *);
-int (fputws)(const wchar_t *, FILE *);
-size_t (fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
-void (free)(void *ptr);
-FILE *(freopen)(const char *filename, const char *mode, FILE *stream);
-double (frepx)(double value, int *exp);
-/* SCANFLIKE2 */
-int (fscanf)(FILE *stream, const char *format, ...);
-int (fseek)(FILE *stream, long int offset, int whence);
-int (fsetpos)(FILE *stream, const fpos_t *pos);
-int (fstat)(int fildes, struct stat *buf);
-long (ftell)(FILE *stream);
-int (fwide)(FILE *, int);
-size_t (fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
-int (getc)(FILE *stream);
-int (getchar)(void);
-char *(getcwd)(char *buf, size_t size);
-gid_t (getegid)(void);
-char *(getenv)(const char *name);
-uid_t (geteuid)(void);
-gid_t (getgid)(void);
-struct group *(getgrgid)(gid_t gid);
-struct group *(getgrnam)(const char *name);
-int (getgroups)(int gidsetsize, gid_t grouplist[]);
-char *(getlogin)(void);
-pid_t (getpgrp)(void);
-pid_t (getpid)(void);
-pid_t (getppid)(void);
-struct passwd *(getpwnam)(const char *name);
-struct passwd *(getpwuid)(uid_t uid);
-char *(gets)(char *s);
-uid_t (getuid)(void);
-wint_t (getwc)(FILE *);
-wint_t (getwchar)(void);
-struct tm *(gmtime)(const time_t *timer);
-int (isalnum)(int c);
-int (isalpha)(int c);
-int (isatty)(int fildes);
-int (iscntrl)(int c);
-int (isdigit)(int c);
-int (isgraph)(int c);
-int (islower)(int c);
-int (isprint)(int c);
-int (ispunct)(int c);
-int (isspace)(int c);
-int (isupper)(int c);
-int (iswalnum)(wint_t wc);
-int (iswalpha)(wint_t wc);
-int (iswcntrl)(wint_t wc);
-int (iswctype)(wint_t wc, wctype_t charclass);
-int (iswdigit)(wint_t wc);
-int (iswgraph)(wint_t wc);
-int (iswlower)(wint_t wc);
-int (iswprint)(wint_t wc);
-int (iswpunct)(wint_t wc);
-int (iswspace)(wint_t wc);
-int (iswupper)(wint_t wc);
-int (iswxdigit)(wint_t wc);
-int (isxdigit)(int c);
-int (kill)(pid_t pid, int sig);
-long (labs)(long j);
-double (ldexp)(double x, int exp);
-ldiv_t (ldiv)(long numer, long denom);
-int (link)(const char *existing, const char *new);
-struct lconv *(localeconv)(void);
-struct tm *(localtime)(const time_t *timer);
-double (log)(double x);
-double (log10)(double x);
-void (longjmp)(jmp_buf env, int val);
-off_t (lseek)(int fildes, off_t offset, int whence);
-int (lstat)(const char *path, struct stat *buf);
-void *(malloc)(size_t size);
-int (mblen)(const char *s, size_t n);
-size_t (mbrlen)(const char *, size_t, mbstate_t *);
-size_t (mbrtowc)(wchar_t *, const char *, size_t, mbstate_t *);
-int (mbsinit)(const mbstate_t *);
-size_t (mbsrtowcs)(wchar_t *, const char **, size_t, mbstate_t *);
-size_t (mbstowcs)(wchar_t *pwcs, const char *s, size_t n);
-int (mbtowc)(wchar_t *pwc, const char *s, size_t n);
-void *(memchr)(const void *s, int c, size_t n);
-int (memcmp)(const void *s1, const void *s2, size_t n);
-void *(memcpy)(void *s1, const void *s2, size_t n);
-void *(memmove)(void *s1, const void *s2, size_t n);
-void *(memset)(void *s, int c, size_t n);
-int (mkdir)(const char *path, mode_t mode);
-int (mkfifo)(const char *path, mode_t mode);
-time_t (mktime)(struct tm *timeptr);
-double (modf)(double value, double *iptr);
-int (open)(const char *path, int oflag, ...);
-void (openlog)(const char *, int, int);
-DIR *(opendir)(const char *dirname);
-long (pathconf)(const char *path, int name);
-int (pause)(void);
-void (perror)(const char *s);
-int (pipe)(int fildes[2]);
-double (pow)(double x, double y);
-/* PRINTFLIKE1 */
-int (printf)(const char *format, ...);
-int (putc)(int c, FILE *stream);
-int (putchar)(int c);
-int (puts)(const char *s);
-wint_t (putwc)(wchar_t, FILE *);
-wint_t (putwchar)(wchar_t);
-void (qsort)(void *base, size_t nmemb, size_t size,
- int (*compar)(const void *, const void *));
-int (raise)(int sig);
-int (rand)(void);
-ssize_t (read)(int fildes, void *buf, size_t nbyte);
-struct dirent *(readdir)(DIR *dirp);
-void *(realloc)(void *ptr, size_t size);
-int (remove)(const char *filename);
-int (rename)(const char *old, const char *new);
-void (rewind)(FILE *stream);
-void (rewinddir)(DIR *dirp);
-int (rmdir)(const char *path);
-/* SCANFLIKE1 */
-int (scanf)(const char *format, ...);
-void (setbuf)(FILE *stream, char *buf);
-int (setgid)(gid_t gid);
-int (setjmp)(jmp_buf env);
-char *(setlocale)(int category, const char *locale);
-int (setlogmask)(int);
-int (setpgid)(pid_t pid, pid_t pgid);
-pid_t (setsid)(void);
-int (setuid)(uid_t uid);
-int (setvbuf)(FILE *stream, char *buf, int mode, size_t size);
-int (sigaction)(int sig, const struct sigaction *act,
- struct sigaction *oact);
-int (sigaddset)(sigset_t *set, int signo);
-int (sigdelset)(sigset_t *set, int signo);
-int (sigemptyset)(sigset_t *set);
-int (sigfillset)(sigset_t *set);
-int (sigismember)(const sigset_t *set, int signo);
-void (siglongjmp)(sigjmp_buf env, int val);
-void (*(signal)(int sig, void (*func)(int)))(int);
-int (sigpending)(sigset_t *set);
-int (sigprocmask)(int how, const sigset_t *set, sigset_t *oset);
-int (sigsetjmp)(sigjmp_buf env, int savemask);
-int (sigsuspend)(const sigset_t *sigmask);
-double (sin)(double x);
-double (sinh)(double x);
-unsigned (sleep)(unsigned seconds);
-/* PRINTFLIKE2 */
-int (sprintf)(char *s, const char *format, ...);
-double (sqrt)(double x);
-void (srand)(unsigned seed);
-/* SCANFLIKE2 */
-int (sscanf)(const char *s, const char *format, ...);
-int (stat)(const char *path, struct stat *buf);
-char *(strcat)(char *s1, const char *s2);
-char *(strchr)(const char *s, int c);
-int (strcmp)(const char *s1, const char *s2);
-int (strcoll)(const char *s1, const char *s2);
-char *(strcpy)(char *s1, const char *s2);
-size_t (strcspn)(const char *s1, const char *s2);
-char *(strerror)(int errnum);
-size_t (strftime)(char *s, size_t maxsize, const char *format,
- const struct tm *timeptr);
-size_t (strlen)(const char *s);
-char *(strncat)(char *s1, const char *s2, size_t n);
-int (strncmp)(const char *s1, const char *s2, size_t n);
-char *(strncpy)(char *s1, const char *s2, size_t n);
-char *(strpbrk)(const char *s1, const char *s2);
-char *(strrchr)(const char *s, int c);
-size_t (strspn)(const char *s1, const char *s2);
-char *(strstr)(const char *s1, const char *s2);
-double (strtod)(const char *nptr, char **endptr);
-char *(strtok)(char *s1, const char *s2);
-long (strtol)(const char *nptr, char **endptr, int base);
-unsigned long (strtoul)(const char *nptr, char **endptr, int base);
-size_t (strxfrm)(char *s1, const char *s2, size_t n);
-long (sysconf)(int name);
-/* PRINTFLIKE2 */
-void (syslog)(int, const char *, ...);
-int (system)(const char *string);
-double (tan)(double x);
-double (tanh)(double x);
-int (tcdrain)(int fildes);
-int (tcflow)(int fildes, int action);
-int (tcflush)(int fildes, int queue_selector);
-int (tcgetattr)(int fildes, struct termios *tp);
-pid_t (tcgetpgrp)(int fildes);
-int (tcsendbreak)(int fildes, int duration);
-int (tcsetattr)(int fildes, int options, const struct termios *tp);
-int (tcsetpgrp)(int fildes, pid_t pgrpid);
-time_t (time)(time_t *timer);
-clock_t (times)(struct tms *buffer);
-FILE *(tmpfile)(void);
-char *(tmpnam)(char *s);
-int (tolower)(int c);
-int (toupper)(int c);
-wint_t (towctrans)(wint_t wc, wctrans_t charmap);
-wint_t (towlower)(wint_t wc);
-wint_t (towupper)(wint_t wc);
-char *(ttyname)(int filedes);
-void (tzset)(void);
-mode_t (umask)(mode_t cmask);
-int (uname)(struct utsname *name);
-int (ungetc)(int c, FILE *stream);
-wint_t (ungetwc)(wint_t, FILE *);
-int (unlink)(const char *path);
-int (utime)(const char *path, const struct utimbuf *times);
-int (vfprintf)(FILE *stream, const char *format, va_list arg);
-int (vprintf)(const char *format, va_list arg);
-int (vsprintf)(char *s, const char *format, va_list arg);
-pid_t (wait)(int *statloc);
-pid_t (waitpid)(pid_t pid, int *stat_loc, int options);
-size_t (wcrtomb)(char *, wchar_t, mbstate_t *);
-wchar_t *(wcscat)(wchar_t *, const wchar_t *);
-wchar_t *(wcschr)(const wchar_t *, wchar_t);
-int (wcscmp)(const wchar_t *, const wchar_t *);
-wchar_t *(wcscpy)(wchar_t *, const wchar_t *);
-size_t (wcscspn)(const wchar_t *, const wchar_t *);
-size_t (wcslen)(const wchar_t *);
-wchar_t *(wcsncat)(wchar_t *, const wchar_t *, size_t);
-int (wcsncmp)(const wchar_t *, const wchar_t *, size_t);
-wchar_t *(wcsncpy)(wchar_t *, const wchar_t *, size_t);
-wchar_t *(wcspbrk)(const wchar_t *, const wchar_t *);
-wchar_t *(wcsrchr)(const wchar_t *, wchar_t);
-size_t (wcsrtombs)(char *, const wchar_t **, size_t, mbstate_t *);
-size_t (wcsspn)(const wchar_t *, const wchar_t *);
-wchar_t *(wcsstr)(const wchar_t *, const wchar_t *);
-double (wcstod)(const wchar_t *, wchar_t **);
-wchar_t *(wcstok)(wchar_t *, const wchar_t *, wchar_t **);
-long (wcstol)(const wchar_t *, wchar_t **, int);
-size_t (wcstombs)(char *s, const wchar_t *pwcs, size_t n);
-unsigned long (wcstoul)(const wchar_t *, wchar_t **, int);
-int (wctob)(wint_t);
-wchar_t *(wmemchr)(const wchar_t *, wchar_t, size_t);
-int (wmemcmp)(const wchar_t *, const wchar_t *, size_t);
-wchar_t *(wmemcpy)(wchar_t *, const wchar_t *, size_t);
-wchar_t *(wmemmove)(wchar_t *, const wchar_t *, size_t);
-wchar_t *(wmemset)(wchar_t *, wchar_t, size_t);
-float (wcstof)(const wchar_t *, wchar_t **);
-long double (wcstold)(const wchar_t *, wchar_t **);
-long long (wcstoll)(const wchar_t *, wchar_t **, int);
-unsigned long long (wcstoull)(const wchar_t *, wchar_t **, int);
-int (wctomb)(char *s, wchar_t wchar);
-wctrans_t (wctrans)(const char *charmap);
-wctype_t (wctype)(const char *charclass);
-ssize_t (write)(int fildes, const void *buf, size_t nbyte);
-
-#if 0 /* not yet implemented */
-/* PRINTFLIKE2 */
-int (fwprintf)(FILE *, const wchar_t *, ...);
-/* SCANFLIKE2 */
-int (fwscanf)(FILE *, const wchar_t *, ...);
-/* PRINTFLIKE3 */
-int (swprintf)(wchar_t *, size_t, const wchar_t *, ...);
-/* SCANFLIKE3 */
-int (swscanf)(const wchar_t *, const wchar_t *, ...);
-int (vfwprintf)(FILE *, const wchar_t *, va_list);
-int (vfwscanf)(FILE *, const wchar_t *, va_list);
-int (vswprintf)(wchar_t *, size_t, const wchar_t *, va_list);
-int (vswscanf)(const wchar_t *, const wchar_t *, va_list);
-int (vwprintf)(const wchar_t *, va_list);
-int (vwscanf)(const wchar_t *, va_list);
-int (wcscoll)(const wchar_t *, const wchar_t *);
-size_t (wcsftime)(wchar_t *, size_t, const wchar_t *, const struct tm *);
-int (wcswidth)(const wchar_t *, size_t);
-size_t (wcsxfrm)(wchar_t *, const wchar_t *, size_t);
-int (wcwidth)(wchar_t);
-/* PRINTFLIKE1 */
-int (wprintf)(const wchar_t *, ...);
-/* SCANFLIKE1 */
-int (wscanf)(const wchar_t *, ...);
-#endif
-
diff --git a/usr.bin/xlint/llib/llib-lstdc b/usr.bin/xlint/llib/llib-lstdc
deleted file mode 100644
index c1f19e8daeb..00000000000
--- a/usr.bin/xlint/llib/llib-lstdc
+++ /dev/null
@@ -1,254 +0,0 @@
-/* $OpenBSD: llib-lstdc,v 1.4 2002/12/11 23:01:40 millert Exp $ */
-/* $NetBSD: llib-lstdc,v 1.3 1995/07/03 21:39:28 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* LINTLIBRARY */
-
-#define _ANSI_SOURCE
-#define _ANSI_LIBRARY
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <locale.h>
-#include <math.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* PROTOLIB1 */
-
-/*
- * assert.h
- */
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-void (__assert)(const char *expression, int line, const char *file);
-#else
-void (assert)(int expression);
-#endif
-
-/*
- * ctype.h
- */
-int (isalnum)(int c);
-int (isalpha)(int c);
-int (iscntrl)(int c);
-int (isdigit)(int c);
-int (isgraph)(int c);
-int (islower)(int c);
-int (isprint)(int c);
-int (ispunct)(int c);
-int (isspace)(int c);
-int (isupper)(int c);
-int (isxdigit)(int c);
-int (tolower)(int c);
-int (toupper)(int c);
-
-/*
- * errno.h
- */
-int (errno);
-
-/*
- * locale.h
- */
-char *(setlocale)(int category, const char *locale);
-struct lconv *(localeconv)(void);
-
-/*
- * math.h
- */
-double (acos)(double x);
-double (asin)(double x);
-double (atan)(double x);
-double (atan2)(double y, double x);
-double (cos)(double x);
-double (sin)(double x);
-double (tan)(double x);
-double (cosh)(double x);
-double (sinh)(double x);
-double (tanh)(double x);
-double (exp)(double x);
-double (frexp)(double value, int *exp);
-double (ldexp)(double x, int exp);
-double (log)(double x);
-double (log10)(double x);
-double (modf)(double value, double *iptr);
-double (pow)(double x, double y);
-double (sqrt)(double x);
-double (ceil)(double x);
-double (fabs)(double x);
-double (floor)(double x);
-double (fmod)(double x, double y);
-
-/*
- * setjmp.h
- */
-int (setjmp)(jmp_buf env);
-void (longjmp)(jmp_buf env, int val);
-
-/*
- * signal.h
- */
-void (*(signal)(int sig, void (*func)(int)))(int);
-int (raise)(int sig);
-
-/*
- * stdio.h
- */
-int (remove)(const char *filename);
-int (rename)(const char *old, const char *new);
-FILE *(tmpfile)(void);
-char *(tmpnam)(char *s);
-int (fclose)(FILE *stream);
-int (fflush)(FILE *stream);
-FILE *(fopen)(const char *filename, const char *mode);
-FILE *(freopen)(const char *filename, const char *mode, FILE *stream);
-void (setbuf)(FILE *stream, char *buf);
-int (setvbuf)(FILE *stream, char *buf, int mode, size_t size);
-/* PRINTFLIKE2 */
-int (fprintf)(FILE *stream, const char *format, ...);
-/* SCANFLIKE2 */
-int (fscanf)(FILE *stream, const char *format, ...);
-/* PRINTFLIKE1 */
-int (printf)(const char *format, ...);
-/* SCANFLIKE1 */
-int (scanf)(const char *format, ...);
-/* PRINTFLIKE2 */
-int (sprintf)(char *s, const char *format, ...);
-/* SCANFLIKE2 */
-int (sscanf)(const char *s, const char *format, ...);
-int (vfprintf)(FILE *stream, const char *format, va_list arg);
-int (vprintf)(const char *format, va_list arg);
-int (vsprintf)(char *s, const char *format, va_list arg);
-int (fgetc)(FILE *stream);
-char *(fgets)(char *s, int n, FILE *stream);
-int (fputc)(int c, FILE *stream);
-int (fputs)(const char *s, FILE *stream);
-int (getc)(FILE *stream);
-int (getchar)(void);
-char *(gets)(char *s);
-int (putc)(int c, FILE *stream);
-int (putchar)(int c);
-int (puts)(const char *s);
-int (ungetc)(int c, FILE *stream);
-size_t (fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
-size_t (fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
-int (fgetpos)(FILE *stream, fpos_t *pos);
-int (fseek)(FILE *stream, long offset, int whence);
-int (fsetpos)(FILE *stream, const fpos_t *pos);
-long (ftell)(FILE *stream);
-void (rewind)(FILE *stream);
-void (clearerr)(FILE *stream);
-int (feof)(FILE *stream);
-int (ferror)(FILE *stream);
-void (perror)(const char *s);
-
-/*
- * stdlib.h
- */
-double (atof)(const char *nptr);
-int (atoi)(const char *nptr);
-long (atol)(const char *nptr);
-double (strtod)(const char *nptr, char **endptr);
-long (strtol)(const char *nptr, char **endptr, int base);
-unsigned long (strtoul)(const char *nptr, char **endptr, int base);
-int (rand)(void);
-void (srand)(unsigned seed);
-void *(calloc)(size_t nmemb, size_t size);
-void (free)(void *ptr);
-void *(malloc)(size_t size);
-void *(realloc)(void *ptr, size_t size);
-void (abort)(void);
-int (atexit)(void (*func)(void));
-void (exit)(int status);
-char *(getenv)(const char *name);
-int (system)(const char *string);
-void *(bsearch)(const void *key, const void *base, size_t nmemb,
- size_t size, int (*compar)(const void *, const void *));
-void (qsort)(void *base, size_t nmemb, size_t size,
- int (*compar)(const void *, const void *));
-int (abs)(int j);
-div_t (div)(int numer, int denom);
-long (labs)(long j);
-ldiv_t (ldiv)(long numer, long denom);
-int (mblen)(const char *s, size_t n);
-int (mbtowc)(wchar_t *PWC, const char *s, size_t n);
-int (wctomb)(char *s, wchar_t wchar);
-size_t (mbstowcs)(wchar_t *pwcs, const char *s, size_t n);
-size_t (wcstombs)(char *s, const wchar_t *pwcs, size_t n);
-
-/*
- * string.h
- */
-void *(memcpy)(void *s1, const void *s2, size_t n);
-void *(memmove)(void *s1, const void *s2, size_t n);
-char *(strcpy)(char *s1, const char *s2);
-char *(strncpy)(char *s1, const char *s2, size_t n);
-char *(strcat)(char *s1, const char *s2);
-char *(strncat)(char *s1, const char *s2, size_t n);
-int (memcmp)(const void *s1, const void *s2, size_t n);
-int (strcmp)(const char *s1, const char *s2);
-int (strcoll)(const char *s1, const char *s2);
-int (strncmp)(const char *s1, const char *s2, size_t n);
-size_t (strxfrm)(char *s1, const char *s2, size_t n);
-void *(memchr)(const void *s, int c, size_t n);
-char *(strchr)(const char *s, int c);
-size_t (strcspn)(const char *s1, const char *s2);
-char *(strpbrk)(const char *s1, const char *s2);
-char *(strrchr)(const char *s1, int c);
-size_t (strspn)(const char *s1, const char *s2);
-char *(strstr)(const char *s1, const char *s2);
-char *(strtok)(char *s1, const char *s2);
-void *(memset)(void *s, int c, size_t n);
-char *(strerror)(int errnom);
-size_t (strlen)(const char *s);
-
-/*
- * time.h
- */
-clock_t (clock)(void);
-double (difftime)(time_t time1, time_t time2);
-time_t (mktime)(struct tm *timeptr);
-time_t (time)(time_t *timer);
-char *(asctime)(const struct tm *timeptr);
-char *(ctime)(const time_t *timer);
-struct tm *(gmtime)(const time_t *timer);
-struct tm *(localtime)(const time_t *timer);
-size_t (strftime)(char *s, size_t maxsize, const char *format,
- const struct tm *timeptr);
diff --git a/usr.bin/xlint/xlint/Makefile b/usr.bin/xlint/xlint/Makefile
deleted file mode 100644
index ce5334a8842..00000000000
--- a/usr.bin/xlint/xlint/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# $OpenBSD: Makefile,v 1.5 2011/11/08 10:37:10 guenther Exp $
-# $NetBSD: Makefile,v 1.2 1995/07/03 21:25:14 cgd Exp $
-
-.PATH: ${.CURDIR}/../lint1
-
-PROG= xlint
-SRCS= xlint.c mem.c
-MAN= lint.1
-
-CFLAGS+=-I${.CURDIR}/../lint1
-
-realinstall:
- ${INSTALL} ${INSTALL_COPY} -S ${INSTALL_STRIP} \
- -o ${BINOWN} -g ${BINGRP} \
- -m ${BINMODE} ${PROG} ${DESTDIR}${BINDIR}/lint
-
-
-.include "${.CURDIR}/../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/usr.bin/xlint/xlint/lint.1 b/usr.bin/xlint/xlint/lint.1
deleted file mode 100644
index 8e9fd24a008..00000000000
--- a/usr.bin/xlint/xlint/lint.1
+++ /dev/null
@@ -1,513 +0,0 @@
-.\" $OpenBSD: lint.1,v 1.27 2011/06/09 15:19:03 jsg Exp $
-.\" $NetBSD: lint.1,v 1.3 1995/10/23 13:45:31 jpo Exp $
-.\"
-.\" Copyright (c) 1994, 1995 Jochen Pohl
-.\" All Rights Reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by Jochen Pohl for
-.\" The NetBSD Project.
-.\" 4. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.Dd $Mdocdate: June 9 2011 $
-.Dt LINT 1
-.Os
-.Sh NAME
-.Nm lint
-.Nd a C program verifier
-.Sh SYNOPSIS
-.Nm lint
-.Op Fl ceFfgHhprsVvxz
-.Op Fl i | nu
-.Op Fl D Ns Ar name Ns Op =def
-.Op Fl I Ns Ar directory
-.Op Fl L Ns Ar directory
-.Op Fl l Ns Ar library
-.Op Fl MD
-.Op Fl o Ns Ar outputfile
-.Op Fl U Ns Ar name
-.Ar
-.Nm lint
-.Op Fl ceFfgHhprsVvz
-.Fl C Ns Ar library
-.Op Fl D Ns Ar name Ns Op =def
-.Op Fl I Ns Ar directory
-.Op Fl MD
-.Op Fl U Ns Ar name
-.Ar
-.Sh DESCRIPTION
-.Nm
-attempts to detect features of the named C program files
-that are likely to be bugs, non-portable, or wasteful.
-It also performs stricter type checking than the C compiler.
-.Nm
-runs the C preprocessor as its first phase, with the
-preprocessor symbol
-.Sy lint
-defined to allow certain questionable code to be altered
-or skipped by
-.Nm lint .
-Therefore, this symbol should be thought of as a reserved
-word for all code that is to be checked by
-.Nm lint .
-.Pp
-Among the possible problems that are currently noted are
-unreachable statements, loops not entered at the top,
-variables declared and not used, and logical expressions
-with constant values.
-Function calls are checked for inconsistencies, such as
-calls to functions that return values in some places and
-not in others, functions called with varying numbers of
-arguments, function calls that pass arguments of a type
-other than the type the function expects to receive,
-functions whose values are not used, and calls to functions
-not returning values that use the non-existent return value
-of the function.
-.Pp
-Filename arguments ending with
-.Pa \&.c
-are taken to be C source files.
-Filename arguments with names ending with
-.Pa \&.ln
-are taken to be the result of an earlier invocation of
-.Nm lint ,
-with either the
-.Fl i ,
-.Fl o ,
-or
-.Fl C
-option in effect.
-The
-.Pa \&.ln
-files are analogous to the
-.Pa \&.o
-(object) files produced by
-.Xr cc 1
-from
-.Pa \&.c
-files.
-.Nm
-also accepts special libraries specified with the
-.Fl l
-option, which contain definitions of library routines and
-variables.
-.Pp
-.Nm
-takes all the
-.Pa \&.c , \&.ln ,
-and
-.Pa llib-l Ns Ar library Ns Pa \&.ln
-(lint library) files and processes them in command-line order.
-By default,
-.Nm
-appends the standard C lint library
-.Pq Pa llib-lc.ln ,
-if it exists,
-to the end of the list of files.
-When the
-.Fl i
-option is used, the
-.Pa \&.ln
-files are ignored.
-Also, when the
-.Fl o
-or
-.Fl i
-options are used, the
-.Pa llib-l Ns Ar library Ns Pa \&.ln
-files are ignored.
-When the
-.Fl i
-option is
-.Em omitted
-the second pass of
-.Nm
-checks this list of files for mutual compatibility.
-At this point, if a complaint stems not from a given source
-file, but from one of its included files, the source filename
-will be printed followed by a question mark.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl C Ns Ar library
-Create a
-.Nm
-library with the name
-.Pa llib-l Ns Ar library Ns Pa .ln .
-This library is built from all
-.Pa \&.c
-and
-.Pa \&.ln
-input files.
-After all global definitions of functions and
-variables in these files are written to the newly created library,
-.Nm
-checks all input files, including libraries specified with the
-.Fl l
-option, for mutual compatibility.
-.It Fl c
-Complain about casts which have questionable portability.
-.It Fl D Ns Ar name Ns Op =def
-Define
-.Ar name
-for
-.Xr cpp 1 ,
-as if by a
-.Li #define
-directive.
-If no definition is given,
-.Ar name
-is defined as 1.
-.It Fl e
-Complain about unusual operations on
-.Sy enum Ns -Types
-and combinations of
-.Sy enum Ns -
-and
-.Sy integer Ns -Types.
-.It Fl F
-Print pathnames of files.
-.Nm
-normally prints the filename without the path.
-.It Fl f
-For each warning or error, print the offending line of the
-corresponding source code file.
-.It Fl g
-Don't print warnings for some extensions of
-.Xr gcc 1
-to the C language.
-Currently these are nonconstant initializers in
-automatic aggregate initializations, arithmetic on pointer to void,
-zero sized structures, subscripting of non-lvalue arrays, prototypes
-overriding old style function declarations and long long
-integer types.
-The
-.Fl g
-flag also turns on the keywords
-.Sy asm
-and
-.Sy inline
-(alternate keywords with leading underscores for both
-.Sy asm
-and
-.Sy inline
-are always available).
-.It Fl H
-If a complaint stems from an included file
-.Nm
-prints the name of the included file instead of the source file name
-followed by a question mark.
-.It Fl h
-Apply a number of heuristic tests to attempt to intuit
-bugs, improve style, and reduce waste.
-.It Fl I Ns Ar directory
-Add
-.Ar directory
-to the list of directories in which to search for include files.
-.It Fl i
-Produce a
-.Pa \&.ln
-file for every
-.Pa \&.c
-file on the command line.
-These
-.Pa \&.ln
-files are the product of
-.Nm lint Ns 's
-first pass only, and are not checked for compatibility
-between functions.
-.It Fl L Ns Ar directory
-Search for lint libraries in
-.Ar directory
-and
-.Ar directory Ns Pa /lint
-before searching the standard place.
-.It Fl l Ns Ar library
-Include the lint library
-.Pa llib-l Ns Ar library Ns Pa \&.ln .
-.It Fl MD
-Ignored, so the same flags can be passed to
-.Nm lint
-and
-.Xr cpp 1 .
-.It Fl n
-Do not check compatibility against the standard library.
-.It Fl o Ns Ar outputfile
-Name the output file
-.Ar outputfile .
-The output file produced is the input that is given to
-.Nm lint Ns 's
-second pass.
-The
-.Fl o
-option simply saves this file in the named output file.
-If the
-.Fl i
-option is also used the files are not checked for compatibility.
-To produce a
-.Pa llib-l Ns Ar library Ns Pa \&.ln
-without extraneous messages, use of the
-.Fl u
-option is suggested.
-The
-.Fl v
-option is useful if the source file(s) for the lint library
-are just external interfaces.
-.It Fl p
-Attempt to check portability of code to other dialects of C.
-.It Fl r
-In case of redeclarations report the position of the
-previous declaration.
-.It Fl s
-Strict ANSI C mode.
-Issue warnings and errors required by ANSI C.
-Also do not produce warnings for constructs which behave
-differently in traditional C and ANSI C.
-With the
-.Fl s
-flag,
-.Li __STRICT_ANSI__
-is a predefined preprocessor macro.
-.It Fl U Ns Ar name
-Remove any initial definition of
-.Ar name
-for the preprocessor.
-.It Fl u
-Do not complain about functions and external variables used
-and not defined, or defined and not used (this is suitable
-for running
-.Nm
-on a subset of files comprising part of a larger program).
-.It Fl V
-Print the command lines constructed by the controller program to
-run the C preprocessor and
-.Nm lint Ns 's
-first and second pass.
-.It Fl v
-Suppress complaints about unused arguments in functions.
-.It Fl x
-Report variables referred to by
-.Sy extern
-declarations, but never used.
-.It Fl z
-Do not complain about structures that are never defined
-(for example, using a structure pointer without knowing
-its contents).
-.El
-.Pp
-.Sy Input Grammar
-.Pp
-.Nm lint Ns 's
-first pass reads standard C source files.
-.Nm
-recognizes the following C comments as commands.
-.Bl -tag -width Fl
-.It Li /* ARGSUSED Ns Ar n Li */
-Make
-.Nm
-check only the first
-.Ar n
-arguments for usage; a missing
-.Ar n
-is taken to be 0 (this option acts like the
-.Fl v
-option for the next function).
-.It Li /* CONSTCOND */ No or Xo
-.Li /* CONSTANTCOND */ No or
-.Li /* CONSTANTCONDITION */
-.Xc
-Suppress complaints about constant operands for the next expression.
-.It Li /*\ FALLTHRU\ */ No or Xo
-.Li /* FALLTHROUGH */
-.Xc
-Suppress complaints about fall through to a
-.Sy case
-or
-.Sy default
-labelled statement.
-This directive should be placed immediately preceding the label.
-.It Li /* LINTLIBRARY */
-At the beginning of a file, mark all functions and variables defined
-in this file as
-.Em used .
-Also shut off complaints about unused function arguments.
-.It Li /* LINTED Xo
-.Op Ar comment
-.Li */ No or
-.Li /* NOSTRICT
-.Op Ar comment
-.Li */
-.Xc
-Suppress any intra-file warning except those dealing with
-unused variables or functions.
-This directive should be placed on the line immediately
-preceding where the
-.Nm
-warning occurred.
-.It Li /* LONGLONG */
-Suppress complaints about use of long long integer types.
-.It Li /* NORETURN */
-Tell
-.Nm
-that the function will never return, which means any code
-following a call to this function is unreachable.
-This directive should be placed immediately preceding the function.
-.It Li /* NOTREACHED */
-At appropriate points, inhibit complaints about unreachable code.
-This comment is typically placed just after calls to functions
-like
-.Xr exit 3 .
-.It Li /* PRINTFLIKE Ns Ar n Li */
-Make
-.Nm
-check the first
-.Pq Ar n Ns -1
-arguments as usual.
-The
-.Ar n Ns -th
-argument is interpreted as a
-.Sy printf
-format string that is used to check the remaining arguments.
-.It Li /* PROTOLIB Ns Ar n Li */
-Cause
-.Nm
-to treat function declaration prototypes as function definitions
-if
-.Ar n
-is non-zero.
-This directive can only be used in conjunction with the
-.Li /* LINTLIBRARY */
-directive.
-If
-.Ar n
-is zero, function prototypes will be treated normally.
-.It Li /* SCANFLIKE Ns Ar n Li */
-Make
-.Nm
-check the first
-.Pq Ar n Ns -1
-arguments as usual.
-The
-.Ar n Ns -th
-argument is interpreted as a
-.Sy scanf
-format string that is used to check the remaining arguments.
-.It Li /* VARARGS Ns Ar n Li */
-Suppress the usual checking for variable numbers of arguments in
-the following function declaration.
-The data types of the first
-.Ar n
-arguments are checked; a missing
-.Ar n
-is taken to be 0.
-.El
-.Pp
-The behavior of the
-.Fl i
-and the
-.Fl o
-options allows for incremental use of
-.Nm
-on a set of C source files.
-Generally, one invokes
-.Nm
-once for each source file with the
-.Fl i
-option.
-Each of these invocations produces a
-.Pa \&.ln
-file that corresponds to the
-.Pa \&.c
-file, and prints all messages that are about just that
-source file.
-After all the source files have been separately run through
-.Nm lint ,
-it is invoked once more (without the
-.Fl i
-option), listing all the
-.Pa \&.ln
-files with the needed
-.Fl l Ns Ar library
-options.
-This will print all the inter-file inconsistencies.
-This scheme works well with
-.Xr make 1 ;
-it allows
-.Xr make 1
-to be used to
-.Nm
-only the source files that have been modified since the last
-time the set of source files were
-.Nm lint Ns ed .
-.Sh ENVIRONMENT
-.Bl -tag -width Fl
-.It Ev LIBDIR
-the directory where the lint libraries specified by the
-.Fl l Ns Ar library
-option must exist.
-If this environment variable is undefined, then the default path
-.Pa /usr/libdata/lint
-will be used to search for the libraries.
-.It Ev TMPDIR
-usually the path for temporary files can be redefined by setting
-this environment variable.
-.El
-.Sh FILES
-.Bl -tag -width /usr/libdata/lint/llib-lposix.ln -compact
-.It Pa /usr/libexec/lint Ns Bq 12
-programs
-.It Pa /usr/libdata/lint/llib-lposix.ln
-prebuilt POSIX C lint library
-.It Pa /usr/libdata/lint/llib-lstdc.ln
-prebuilt ANSI/ISO C lint library
-.It Pa /tmp/lint*
-temporaries
-.El
-.Sh SEE ALSO
-.Xr cc 1 ,
-.Xr cpp 1 ,
-.Xr make 1
-.Sh AUTHORS
-Jochen Pohl
-.Sh BUGS
-The routines
-.Xr exit 3 ,
-.Xr longjmp 3
-and other functions that do not return are not understood; this
-causes various incorrect diagnostics.
-.Pp
-Static functions which are used only before their first
-extern declaration are reported as unused.
-.Pp
-Libraries created by the
-.Fl o
-option will, when used in later
-.Nm
-runs, cause certain errors that were reported when the libraries
-were created to be reported again, and cause line numbers and file
-names from the original source used to create those libraries
-to be reported in error messages.
-For these reasons, it is recommended to use the
-.Fl C
-option to create lint libraries.
diff --git a/usr.bin/xlint/xlint/pathnames.h b/usr.bin/xlint/xlint/pathnames.h
deleted file mode 100644
index fdb64a50345..00000000000
--- a/usr.bin/xlint/xlint/pathnames.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $OpenBSD: pathnames.h,v 1.2 1996/06/26 05:44:31 deraadt Exp $ */
-/* $NetBSD: pathnames.h,v 1.2 1995/07/03 21:25:20 cgd Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* directory where lint1 and lint2 reside */
-#define PATH_LIBEXEC "/usr/libexec"
-
-/* default library search path */
-#define PATH_LINTLIB "/usr/libdata/lint"
diff --git a/usr.bin/xlint/xlint/xlint.c b/usr.bin/xlint/xlint/xlint.c
deleted file mode 100644
index 2b6d588f72e..00000000000
--- a/usr.bin/xlint/xlint/xlint.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/* $OpenBSD: xlint.c,v 1.36 2011/09/21 18:08:07 jsg Exp $ */
-/* $NetBSD: xlint.c,v 1.3 1995/10/23 14:29:30 jpo Exp $ */
-
-/*
- * Copyright (c) 1994, 1995 Jochen Pohl
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jochen Pohl for
- * The NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <err.h>
-#include <errno.h>
-#include <paths.h>
-
-#include "lint.h"
-#include "pathnames.h"
-
-/* directory for temporary files */
-static const char *tmpdir;
-
-/* path name for cpp output */
-static char *cppout;
-
-/* files created by 1st pass */
-static char **p1out;
-
-/* input files for 2nd pass (without libraries) */
-static char **p2in;
-
-/* library which will be created by 2nd pass */
-static char *p2out;
-
-/* flags always passed to cpp */
-static char **cppflags;
-
-/* flags for cpp, controled by sflag/tflag */
-static char **lcppflgs;
-
-/* flags for lint1 */
-static char **l1flags;
-
-/* flags for lint2 */
-static char **l2flags;
-
-/* libraries for lint2 */
-static char **l2libs;
-
-/* default libraries */
-static char **deflibs;
-
-/* additional libraries */
-static char **libs;
-
-/* search path for libraries */
-static char **libsrchpath;
-
-/* flags */
-static int iflag, oflag, Cflag, sflag, tflag, Fflag = 1;
-
-/* print the commands executed to run the stages of compilation */
-static int Vflag;
-
-/* filename for oflag */
-static char *outputfn;
-
-/* reset after first .c source has been processed */
-static int first = 1;
-
-/*
- * name of a file which is currently written by a child and should
- * be removed after abnormal termination of the child
- */
-static const char *currfn;
-
-static void appstrg(char ***, char *);
-static void appcstrg(char ***, const char *);
-static void applst(char ***, char *const *);
-static void freelst(char ***);
-static char *concat2(const char *, const char *);
-static char *concat3(const char *, const char *, const char *);
-static void terminate(int);
-static const char *lbasename(const char *, int);
-static void appdef(char ***, const char *);
-static void usage(void);
-static void fname(const char *);
-static int runchild(const char *, char *const *, const char *);
-static void findlibs(char *const *);
-static int rdok(const char *);
-static void lint2(void);
-static void cat(char *const *, const char *);
-
-/*
- * Some functions to deal with lists of strings.
- * Take care that we get no surprises in case of asynchronous signals.
- */
-static void
-appstrg(char ***lstp, char *s)
-{
- char **lst, **olst;
- int i;
-
- olst = *lstp;
- for (i = 0; olst[i] != NULL; i++) ;
- lst = xmalloc((i + 2) * sizeof (char *));
- (void)memcpy(lst, olst, i * sizeof (char *));
- lst[i] = s;
- lst[i + 1] = NULL;
- *lstp = lst;
-}
-
-static void
-appcstrg(char ***lstp, const char *s)
-{
- appstrg(lstp, xstrdup(s));
-}
-
-static void
-applst(char ***destp, char *const *src)
-{
- int i, k;
- char **dest, **odest;
-
- odest = *destp;
- for (i = 0; odest[i] != NULL; i++) ;
- for (k = 0; src[k] != NULL; k++) ;
- dest = xmalloc((i + k + 1) * sizeof (char *));
- (void)memcpy(dest, odest, i * sizeof (char *));
- for (k = 0; src[k] != NULL; k++)
- dest[i + k] = xstrdup(src[k]);
- dest[i + k] = NULL;
- *destp = dest;
- free(odest);
-}
-
-static void
-freelst(char ***lstp)
-{
- char *s;
- int i;
-
- for (i = 0; (*lstp)[i] != NULL; i++) ;
- while (i-- > 0) {
- s = (*lstp)[i];
- (*lstp)[i] = NULL;
- free(s);
- }
-}
-
-static char *
-concat2(const char *s1, const char *s2)
-{
- char *s;
- size_t len = strlen(s1) + strlen(s2) + 1;
-
- s = xmalloc(len);
- (void)strlcpy(s, s1, len);
- (void)strlcat(s, s2, len);
-
- return (s);
-}
-
-static char *
-concat3(const char *s1, const char *s2, const char *s3)
-{
- char *s;
- size_t len = strlen(s1) + strlen(s2) + strlen(s3) + 1;
-
- s = xmalloc(len);
- (void)strlcpy(s, s1, len);
- (void)strlcat(s, s2, len);
- (void)strlcat(s, s3, len);
-
- return (s);
-}
-
-/*
- * Clean up after a signal.
- */
-static void
-terminate(int signo)
-{
- int i;
-
- if (cppout != NULL)
- (void)remove(cppout);
-
- if (p1out != NULL) {
- for (i = 0; p1out[i] != NULL; i++)
- (void)remove(p1out[i]);
- }
-
- if (p2out != NULL)
- (void)remove(p2out);
-
- if (currfn != NULL)
- (void)remove(currfn);
-
- _exit(signo != 0 ? 1 : 0);
-}
-
-/*
- * Returns a pointer to the last component of strg after delim.
- * Returns strg if the string does not contain delim.
- */
-static const char *
-lbasename(const char *strg, int delim)
-{
- const char *cp, *cp1, *cp2;
-
- cp = cp1 = cp2 = strg;
- while (*cp != '\0') {
- if (*cp++ == delim) {
- cp2 = cp1;
- cp1 = cp;
- }
- }
- return (*cp1 == '\0' ? cp2 : cp1);
-}
-
-static void
-appdef(char ***lstp, const char *def)
-{
- appstrg(lstp, concat2("-D__", def));
- appstrg(lstp, concat3("-D__", def, "__"));
-}
-
-static void
-usage()
-{
- (void)printf("usage: lint [-ceFfgHhprsVvxz] [-i | -nu] [-Dname[=def]] [-Idirectory]\n");
- (void)printf("\t[-Ldirectory] [-llibrary] [-ooutputfile] [-MD] [-Uname] file ...\n");
- (void)printf(" lint [-ceFfgHhprsVvz] -Clibrary [-Dname[=def]]\n");
- (void)printf("\t[-Idirectory] [-MD] [-Uname] file ...\n");
- terminate(-1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int c;
- int fd;
- char flgbuf[3], *tmp, *s;
- size_t len;
- struct utsname un;
-
- if ((tmp = getenv("TMPDIR")) == NULL || (len = strlen(tmp)) == 0) {
- tmpdir = xstrdup(_PATH_TMP);
- } else {
- s = xmalloc(len + 2);
- (void)snprintf(s, len + 2, "%s%s",
- tmp, tmp[len - 1] == '/' ? "" : "/");
- tmpdir = s;
- }
-
- if (asprintf(&cppout, "%slint0.XXXXXXXXXX", tmpdir) == -1)
- err(1, NULL);
- if ((fd = mkstemp(cppout)) == -1) {
- warn("can't make temp");
- terminate(-1);
- }
- close(fd);
-
- p1out = xcalloc(1, sizeof (char *));
- p2in = xcalloc(1, sizeof (char *));
- cppflags = xcalloc(1, sizeof (char *));
- lcppflgs = xcalloc(1, sizeof (char *));
- l1flags = xcalloc(1, sizeof (char *));
- l2flags = xcalloc(1, sizeof (char *));
- l2libs = xcalloc(1, sizeof (char *));
- deflibs = xcalloc(1, sizeof (char *));
- libs = xcalloc(1, sizeof (char *));
- libsrchpath = xcalloc(1, sizeof (char *));
-
- appcstrg(&cppflags, "-x");
- appcstrg(&cppflags, "c");
- appcstrg(&cppflags, "-undef");
- /* even with -undef cpp still identifies as GNUC */
- appcstrg(&cppflags, "-U__GNUC__");
-#if defined(__GNUC__)
-#if __GNUC__ < 3
- appcstrg(&cppflags, "-$");
- appcstrg(&cppflags, "-C");
-#else
- appcstrg(&cppflags, "-CC");
-#endif
-#endif
- appcstrg(&cppflags, "-Wcomment");
- appcstrg(&cppflags, "-D__OpenBSD__");
- appcstrg(&cppflags, "-Dlint"); /* XXX don't def. with -s */
- appdef(&cppflags, "lint");
- appdef(&cppflags, "unix");
-
- if (uname(&un) == -1)
- err(1, "uname");
- appdef(&cppflags, un.machine);
- appstrg(&lcppflgs, concat2("-D", un.machine));
-
-#ifdef MACHINE_ARCH
-#ifdef MACHINE_CPU
- if (strcmp(MACHINE_ARCH, MACHINE_CPU) != 0) {
- appdef(&cppflags, MACHINE_CPU);
- appstrg(&lcppflgs, concat2("-D", MACHINE_CPU));
- }
-#endif
- if (strcmp(un.machine, MACHINE_ARCH) != 0) {
- appdef(&cppflags, MACHINE_ARCH);
- appstrg(&lcppflgs, concat2("-D", MACHINE_ARCH));
- }
-#endif
-
- appcstrg(&deflibs, "c");
-
- if (signal(SIGHUP, terminate) == SIG_IGN)
- (void)signal(SIGHUP, SIG_IGN);
- (void)signal(SIGINT, terminate);
- (void)signal(SIGQUIT, terminate);
- (void)signal(SIGTERM, terminate);
-
- while (argc > optind) {
- c = getopt(argc, argv, "abcefghil:no:prstuvxyzC:D:FHI:L:M:U:V");
-
- switch (c) {
-
- case 'a':
- case 'b':
- case 'c':
- case 'e':
- case 'f':
- case 'g':
- case 'r':
- case 'v':
- case 'y':
- case 'z':
- (void)snprintf(flgbuf, sizeof flgbuf, "-%c", c);
- appcstrg(&l1flags, flgbuf);
- break;
-
- case 'F':
- Fflag = 1;
- /* FALLTHROUGH */
- case 'u':
- case 'h':
- (void)snprintf(flgbuf, sizeof flgbuf, "-%c", c);
- appcstrg(&l1flags, flgbuf);
- appcstrg(&l2flags, flgbuf);
- break;
-
- case 'i':
- if (Cflag)
- usage();
- iflag = 1;
- break;
-
- case 'n':
- freelst(&deflibs);
- break;
-
- case 'p':
- appcstrg(&l1flags, "-p");
- appcstrg(&l2flags, "-p");
- if (*deflibs != NULL) {
- freelst(&deflibs);
- appcstrg(&deflibs, "c");
- }
- break;
-
- case 's':
- if (tflag)
- usage();
- freelst(&lcppflgs);
- appcstrg(&lcppflgs, "-trigraphs");
- appcstrg(&lcppflgs, "-Wtrigraphs");
- appcstrg(&lcppflgs, "-pedantic");
- appcstrg(&lcppflgs, "-D__STRICT_ANSI__");
- appcstrg(&l1flags, "-s");
- appcstrg(&l2flags, "-s");
- sflag = 1;
- break;
-
- case 't':
- if (sflag)
- usage();
- freelst(&lcppflgs);
- appcstrg(&lcppflgs, "-traditional");
- appstrg(&lcppflgs, concat2("-D", MACHINE));
- appstrg(&lcppflgs, concat2("-D", MACHINE_ARCH));
- appcstrg(&l1flags, "-t");
- appcstrg(&l2flags, "-t");
- tflag = 1;
- break;
-
- case 'x':
- appcstrg(&l2flags, "-x");
- break;
-
- case 'C':
- if (Cflag || oflag || iflag)
- usage();
- Cflag = 1;
- appstrg(&l2flags, concat2("-C", optarg));
- if (asprintf(&p2out, "llib-l%s.ln", optarg) == -1)
- err(1, NULL);
- freelst(&deflibs);
- break;
-
- case 'D':
- case 'I':
- case 'U':
- (void)snprintf(flgbuf, sizeof flgbuf, "-%c", c);
- appstrg(&cppflags, concat2(flgbuf, optarg));
- break;
-
- case 'l':
- appcstrg(&libs, optarg);
- break;
-
- case 'o':
- if (Cflag || oflag)
- usage();
- oflag = 1;
- outputfn = xstrdup(optarg);
- break;
-
- case 'L':
- appcstrg(&libsrchpath, optarg);
- break;
-
- case 'M':
- break;
-
- case 'H':
- appcstrg(&l2flags, "-H");
- break;
-
- case 'V':
- Vflag = 1;
- break;
-
- case '?':
- usage();
- /* NOTREACHED */
-
- case -1:
- /* filename */
- if (argv[optind] == NULL)
- break;
- fname(argv[optind++]);
- first = 0;
- }
-
- }
- argc -= optind;
- argv += optind;
-
- if (first)
- usage();
-
- if (iflag)
- terminate(0);
-
- if (!oflag) {
- if ((s = getenv("LIBDIR")) == NULL || strlen(s) == 0)
- s = PATH_LINTLIB;
- appcstrg(&libsrchpath, s);
- findlibs(libs);
- findlibs(deflibs);
- }
-
- (void)printf("Lint pass2:\n");
- lint2();
-
- if (oflag)
- cat(p2in, outputfn);
-
- if (Cflag)
- p2out = NULL;
-
- terminate(0);
- /* NOTREACHED */
-}
-
-/*
- * Read a file name from the command line
- * and pass it through lint1 if it is a C source.
- */
-static void
-fname(const char *name)
-{
- const char *bn, *suff;
- char **args, *ofn, *path;
- size_t len;
- int error;
- int fd;
-
- bn = lbasename(name, '/');
- suff = lbasename(bn, '.');
-
- if (strcmp(suff, "ln") == 0) {
- /* only for lint2 */
- if (!iflag)
- appcstrg(&p2in, name);
- return;
- }
-
- if (strcmp(suff, "c") != 0 &&
- (strncmp(bn, "llib-l", 6) != 0 || bn != suff)) {
- warnx("unknown file type: %s", name);
- return;
- }
-
- /* build the name of the output file of lint1 */
- if (oflag) {
- ofn = outputfn;
- outputfn = NULL;
- oflag = 0;
- } else if (iflag) {
- len = strlen(bn) + (bn == suff ? 4 : 2);
- ofn = xmalloc(len);
- (void)snprintf(ofn, len, "%.*s",
- bn == suff ? strlen(bn) : (suff - 1) - bn, bn);
- (void)strlcat(ofn, ".ln", len);
- } else {
- if (asprintf(&ofn, "%slint1.XXXXXXXXXX", tmpdir) == -1)
- err(1, NULL);
- if ((fd = mkstemp(ofn)) == -1) {
- warn("can't make temp");
- terminate(-1);
- }
- close(fd);
- }
- if (!iflag)
- appcstrg(&p1out, ofn);
-
- args = xcalloc(1, sizeof (char *));
-
- /* run cpp */
-
- if (asprintf(&path, "%s/cpp", PATH_LIBEXEC) == -1)
- err(1, NULL);
-
- appcstrg(&args, path);
- applst(&args, cppflags);
- applst(&args, lcppflgs);
- appcstrg(&args, name);
- appcstrg(&args, cppout);
-
- error = runchild(path, args, cppout);
- free(path);
- freelst(&args);
- if (error)
- return;
-
- /* run lint1 */
-
- if (asprintf(&path, "%s/lint1", PATH_LIBEXEC) == -1)
- err(1, NULL);
-
- appcstrg(&args, path);
- applst(&args, l1flags);
- appcstrg(&args, cppout);
- appcstrg(&args, ofn);
-
- error = runchild(path, args, ofn);
- free(path);
- freelst(&args);
- if (error)
- return;
-
- appcstrg(&p2in, ofn);
- free(ofn);
-
- free(args);
-}
-
-static int
-runchild(const char *path, char *const *args, const char *crfn)
-{
- int status, signo, i;
- pid_t rv;
-
- if (Vflag) {
- for (i = 0; args[i] != NULL; i++)
- (void)printf("%s ", args[i]);
- (void)printf("\n");
- }
-
- currfn = crfn;
-
- (void)fflush(stdout);
-
- switch (fork()) {
- case -1:
- warn("cannot fork");
- terminate(-1);
- /* NOTREACHED */
- default:
- /* parent */
- break;
- case 0:
- /* child */
- (void)execv(path, args);
- warn("cannot exec %s", path);
- exit(1);
- /* NOTREACHED */
- }
- currfn = NULL;
-
- while ((rv = wait(&status)) == -1 && errno == EINTR) ;
- if (rv == -1) {
- warn("wait");
- return(-1);
- }
- if (WIFSIGNALED(status)) {
- signo = WTERMSIG(status);
- warnx("%s got SIG%s", path, sys_signame[signo]);
- return(-1);
- }
- if (WEXITSTATUS(status) != 0)
- return(-1);
- return(0);
-}
-
-static void
-findlibs(char *const *liblst)
-{
- int i, k;
- const char *lib, *path;
- char *lfn;
- size_t len, l;
-
- lfn = NULL;
-
- for (i = 0; (lib = liblst[i]) != NULL; i++) {
- for (k = 0; (path = libsrchpath[k]) != NULL; k++) {
- len = strlen(path) + strlen(lib);
- l = len + sizeof ("/llib-l.ln");
- lfn = xrealloc(lfn, l);
- (void)snprintf(lfn, l, "%s/llib-l%s.ln", path, lib);
- if (rdok(lfn))
- break;
- l = len + sizeof ("/lint/llib-l.ln");
- lfn = xrealloc(lfn, l);
- (void)snprintf(lfn, l, "%s/lint/llib-l%s.ln", path, lib);
- if (rdok(lfn))
- break;
- }
- if (path != NULL) {
- appstrg(&l2libs, concat2("-l", lfn));
- } else {
- warnx("cannot find llib-l%s.ln", lib);
- }
- }
-
- free(lfn);
-}
-
-static int
-rdok(const char *path)
-{
- struct stat sbuf;
-
- if (stat(path, &sbuf) == -1)
- return (0);
- if ((sbuf.st_mode & S_IFMT) != S_IFREG)
- return (0);
- if (access(path, R_OK) == -1)
- return (0);
- return (1);
-}
-
-static void
-lint2()
-{
- char *path, **args;
-
- args = xcalloc(1, sizeof (char *));
-
- if (asprintf(&path, "%s/lint2", PATH_LIBEXEC) == -1)
- err(1, NULL);
-
- appcstrg(&args, path);
- applst(&args, l2flags);
- applst(&args, l2libs);
- applst(&args, p2in);
-
- (void)runchild(path, args, p2out);
- free(path);
- freelst(&args);
- free(args);
-}
-
-static void
-cat(char *const *srcs, const char *dest)
-{
- int ifd, ofd, i;
- char *src, *buf;
- ssize_t rlen;
-
- if ((ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
- warn("cannot open %s", dest);
- terminate(-1);
- }
-
- buf = xmalloc(MBLKSIZ);
-
- for (i = 0; (src = srcs[i]) != NULL; i++) {
- if ((ifd = open(src, O_RDONLY)) == -1) {
- free(buf);
- warn("cannot open %s", src);
- terminate(-1);
- }
- do {
- if ((rlen = read(ifd, buf, MBLKSIZ)) == -1) {
- free(buf);
- warn("read error on %s", src);
- terminate(-1);
- }
- if (write(ofd, buf, (size_t)rlen) == -1) {
- free(buf);
- warn("write error on %s", dest);
- terminate(-1);
- }
- } while (rlen == MBLKSIZ);
- (void)close(ifd);
- }
- (void)close(ofd);
- free(buf);
-}
-