BSD 4_3_Tahoe release
[unix-history] / usr / doc / smm / 19.porttour / porttour1.ms
CommitLineData
95f51977
C
1.\" @(#)porttour1.ms 6.3 (Berkeley) 5/30/86
2.\"
3.ds f \fIf77\fP
4.ds U \s-2UNIX\s0
5.ds V \s-2VAX\s0
6.de Bl
7.na
8.fi
9.ll 3i
10..
11.de Sp
12.sp 0.25v
13..
c9528a00
C
14.TL
15A Tour Through the Portable C Compiler
16.AU
17S. C. Johnson
18.AI
95f51977
C
19AT&T Bell Laboratories
20.sp
21.AU
22Donn Seeley
23.AI
24Department of Computer Science
25University of Utah
26.AB
27.OH 'A Tour Through the Portable C Compiler''SMM:19-%'
28.EH 'SMM:19-%''A Tour Through the Portable C Compiler'
29.PP
30Since its introduction,
31the Portable C Compiler has become the standard
32\*U C compiler for many machines.
33Three quarters or more of the code
34in the compiler is machine independent
35and much of the rest can be generated easily
36using knowledge of the target architecture.
37This paper describes the structure
38and organization of the compiler
39and tries to further simplify the job
40of the compiler porter.
41.PP
42This document originally appeared with the Seventh Edition of \*U,
43and has been revised and extended for publication
44with the Fourth Berkeley Software Distribution.
45The new material covers changes which
46have been made in the compiler since the Seventh Edition,
47and includes some discussion of secondary topics
48which were thought to be of interest
49in future ports of the compiler.
50.sp
51.LP
52Revised April, 1986
53.AE
c9528a00
C
54.SH
55Introduction
56.PP
57A C compiler has been implemented that has proved to be quite portable,
58serving as the basis for C compilers on roughly a dozen machines, including
95f51977 59the DEC \*V, Honeywell 6000, IBM 370, and Interdata 8/32.
c9528a00
C
60The compiler is highly compatible with the C language standard.
61.[
62Kernighan Ritchie Prentice 1978
63.]
64.PP
65Among the goals of this compiler are portability, high reliability,
66and the use of state-of-the-art techniques and tools wherever practical.
67Although the efficiency of the compiling process is not
68a primary goal, the compiler is efficient enough, and produces
69good enough code, to serve as a production compiler.
70.PP
71The language implemented is highly compatible with the current PDP-11 version of C.
72Moreover, roughly 75% of the compiler, including
73nearly all the syntactic and semantic routines, is machine independent.
74The compiler also serves as the major portion of the program
75.I lint ,
76described elsewhere.
77.[
78Johnson Lint Program Checker
79.]
80.PP
81A number of earlier attempts to make portable compilers are worth noting.
82While on CO-OP assignment to Bell Labs in 1973, Alan Snyder wrote a portable C
83compiler which was the basis of his Master's Thesis at M.I.T.
84.[
85Snyder Portable C Compiler
86.]
87This compiler was very slow and complicated, and contained a number of rather
88serious implementation difficulties;
89nevertheless, a number of Snyder's ideas appear in this work.
90.PP
91Most earlier portable compilers, including Snyder's, have proceeded by
92defining an intermediate language, perhaps based
93on three-address code or code for a stack machine,
94and writing a machine independent program to
95translate from the source code to this
96intermediate code.
97The intermediate code is then read by a second pass, and interpreted or compiled.
98This approach is elegant, and has a number of advantages, especially if the
99target machine is far removed from the host.
100It suffers from some disadvantages as well.
101Some constructions, like initialization and subroutine prologs,
102are difficult or expensive to express in a
103machine independent way that still allows them
104to be easily adapted to the target assemblers.
105Most of these approaches require a symbol table to be constructed
106in the second (machine dependent) pass, and/or
107require powerful target assemblers.
108Also, many conversion operators may be generated
109that have no effect on a given machine,
110but may be needed on others (for example, pointer to pointer
111conversions usually do nothing in C, but must be generated because
112there are some machines where they are significant).
113.PP
114For these reasons, the first pass of the portable compiler
115is not entirely machine independent.
116It contains some machine dependent features, such as initialization, subroutine
117prolog and epilog, certain storage allocation functions,
118code for the
119.I switch
120statement, and code to throw out unneeded conversion operators.
121.PP
122As a crude measure of the degree of
123portability actually achieved,
124the Interdata 8/32 C compiler has
125roughly 600 machine dependent lines of source out of 4600 in Pass 1, and 1000
126out of 3400 in Pass 2.
127In total, 1600 out of 8000, or 20%,
128of the total source is machine dependent
129(12% in Pass 1, 30% in Pass 2).
130These percentages can be expected to rise slightly as the
131compiler is tuned.
132The percentage of machine-dependent code for the IBM is 22%, for
133the Honeywell 25%.
134If the assembler format and structure were the same for all
135these machines, perhaps another 5-10% of the code
136would become machine independent.
137.PP
138These figures are sufficiently misleading as to be almost
139meaningless.
140A large fraction of the machine dependent code can be converted
141in a straightforward, almost mechanical way.
95f51977 142On the other hand, a certain amount of the code requires hard
c9528a00
C
143intellectual effort to convert, since the algorithms
144embodied in this part of the code are typically complicated
145and machine dependent.
146.PP
147To summarize, however, if you need a C compiler written for a machine with
148a reasonable architecture, the compiler is already three quarters finished!
149.SH
150Overview
151.PP
152This paper discusses the structure and organization of the portable compiler.
153The intent is to give the big picture, rather than discussing the details of a particular machine
154implementation.
155After a brief overview and a discussion of the source file structure,
156the paper describes the major data structures, and then delves more
157closely into the two passes.
158Some of the theoretical work on which the compiler is based, and
159its application to the compiler, is discussed elsewhere.
160.[
161johnson portable theory practice
162.]
163One of the major design issues in any C compiler, the design of
164the calling sequence and stack frame, is the subject of a separate
165memorandum.
166.[
167johnson lesk ritchie calling sequence
168.]
169.PP
170The compiler consists of two passes,
171.I pass1
172and
173.I pass2 ,
174that together turn C source code into assembler code for the target
175machine.
176The two passes are preceded by a preprocessor, that
177handles the
178.B "#define"
179and
180.B "#include"
181statements, and related features (e.g.,
182.B #ifdef ,
183etc.).
95f51977
C
184The two passes may optionally be followed by
185a machine dependent code improver.
c9528a00
C
186.PP
187The output of the preprocessor is a text file that is read as the standard
188input of the first pass.
189This
190produces as standard output another text file that becomes the standard
191input of the second pass.
192The second pass produces, as standard output, the desired assembler language source code.
95f51977
C
193The code improver, if used, converts the assembler code
194to more effective code,
195and the result is passed to the assembler.
c9528a00
C
196The preprocessor and the two passes
197all write error messages on the standard error file.
198Thus the compiler itself makes few demands on the I/O
199library support, aiding in the bootstrapping process.
200.PP
95f51977
C
201The division of the compiler into two passes is somewhat artificial.
202The compiler can optionally be loaded
c9528a00
C
203so that both passes operate in the same program.
204This ``one pass'' operation eliminates the overhead of
205reading and writing the intermediate file, so the compiler
206operates about 30% faster in this mode.
207It also occupies about 30% more space than the larger
208of the two component passes.
95f51977
C
209This ``one pass'' compiler is the standard version
210on machines with large address spaces, such as the \*V.
c9528a00
C
211.PP
212Because the compiler is fundamentally structured as two
213passes, even when loaded as one, this document primarily
214describes the two pass version.
215.PP
216The first pass does the lexical analysis, parsing, and
217symbol table maintenance.
218It also constructs parse trees for expressions,
219and keeps track of the types of the nodes in these trees.
220Additional code is devoted to initialization.
221Machine dependent portions of the first pass serve to
222generate subroutine prologs and epilogs,
223code for switches, and code for branches, label definitions,
224alignment operations,
225changes of location counter, etc.
226.PP
227The intermediate file is a text file organized into lines.
228Lines beginning with a right parenthesis are copied by the second
229pass directly to its output file, with the
230parenthesis stripped off.
231Thus, when the first pass produces assembly code, such as subroutine prologs,
232etc., each line is prefaced with a right parenthesis;
233the second pass passes these lines to through to the assembler.
234.PP
235The major job done by the second pass is generation of code
236for expressions.
237The expression parse trees produced in the first pass are
238written onto the
239intermediate file in Polish Prefix form:
240first, there is a line beginning with a period, followed by the source
241file line number and name on which the expression appeared (for debugging purposes).
242The successive lines represent the nodes of the parse tree,
243one node per line.
244Each line contains the node number, type, and
245any values (e.g., values of constants)
246that may appear in the node.
247Lines representing nodes with descendants are immediately
248followed by the left subtree of descendants, then the
249right.
250Since the number of descendants of any node is completely
251determined by the node number, there is no need to mark the end
252of the tree.
253.PP
254There are only two other line types in the intermediate file.
255Lines beginning with a left square bracket (`[') represent the beginning of
256blocks (delimited by { ... } in the C source);
257lines beginning with right square brackets (`]') represent the end of blocks.
258The remainder of these lines tell how much
259stack space, and how many register variables,
260are currently in use.
261.PP
262Thus, the second pass reads the intermediate files, copies the `)' lines,
263makes note of the information in the `[' and `]' lines,
264and devotes most of its effort to the
265`.' lines and their associated expression trees, turning them
266turns into assembly code to evaluate the expressions.
267.PP
268In the one pass version of the compiler, the expression
95f51977 269trees contain information useful to both logical passes.
c9528a00
C
270Instead of writing the trees onto an intermediate file,
271each tree is transformed in place into an acceptable
272form for the code generator.
273The code generator then writes the result of compiling
274this tree onto the standard output.
275Instead of `[' and `]' lines in the intermediate file, the information is passed
276directly to the second pass routines.
277Assembly code produced by the first pass is simply written out,
95f51977 278without the need for `)' at the head of each line.
c9528a00
C
279.SH
280The Source Files
281.PP
95f51977
C
282The compiler source consists of 25 source files.
283Several header files contain information
284which is needed across various source modules.
285.I Manifest.h
286has declarations for node types, type manipulation
287macros and other macros, and some global data definitions.
288.I Macdefs.h
c9528a00
C
289has machine-dependent definitions, such as the size and alignment of the
290various data representations.
95f51977
C
291.I Config.h
292defines symbols which control the configuration of the compiler,
293including such things as the sizes of various tables
294and whether the compiler is ``one pass''.
295The compiler conditionally includes another file,
296.I onepass.h ,
297which contains definitions which are particular to
298a ``one pass'' compiler.
299.I Ndu.h
300defines the basic tree building structure
301which is used throughout the compiler
302to construct expression trees.
303.I Manifest.h
304includes a file of opcode and type definitions named
305.I pcclocal.h ;
306this file is automatically generated from
307a header file specific to the C compiler named
308.I localdefs.h
309and a public header file
310.I /usr/include/pcc.h .
311Another file,
312.I pcctokens ,
313is generated in a similar way
314and contains token definitions for the compiler's Yacc
315.[
316Johnson Yacc Compiler cstr
317.]
318grammar.
c9528a00 319Two machine independent header files,
95f51977 320.I pass1.h
c9528a00 321and
95f51977 322.I pass2.h ,
c9528a00
C
323contain the data structure and manifest definitions
324for the first and second passes, respectively.
325In the second pass, a machine dependent header file,
95f51977 326.I mac2defs.h ,
c9528a00
C
327contains declarations of register names, etc.
328.PP
95f51977
C
329.I Common.c
330contains machine independent routines used in both passes.
c9528a00
C
331These include routines for allocating and freeing trees, walking over trees,
332printing debugging information, and printing error messages.
95f51977
C
333This file can be compiled in two flavors,
334one for pass 1 and one for pass 2,
335depending on what conditional compilation symbol is used.
c9528a00
C
336.PP
337Entire sections of this document are devoted to the detailed structure of the
338passes.
339For the moment, we just give a brief description of the files.
340The first pass
341is obtained by compiling and loading
95f51977 342.I cgram.y ,
c9528a00 343.I code.c ,
95f51977
C
344.I common.c ,
345.I local.c ,
346.I optim.c ,
347.I pftn.c ,
348.I scan.c ,
349.I stab.c ,
350.I trees.c
c9528a00 351and
95f51977 352.I xdefs.c .
c9528a00 353.I Scan.c
95f51977
C
354is the lexical analyzer, which provides tokens to the
355bottom-up parser which is defined by the Yacc grammar
c9528a00
C
356.I cgram.y .
357.I Xdefs.c
358is a short file of external definitions.
359.I Pftn.c
360maintains the symbol table, and does initialization.
361.I Trees.c
362builds the expression trees, and computes the node types.
363.I Optim.c
364does some machine independent optimizations on the expression trees.
95f51977
C
365.I Common.c
366contains service routines common to the two passes of the compiler.
c9528a00
C
367All the above files are machine independent.
368The files
369.I local.c
370and
371.I code.c
372contain machine dependent code for generating subroutine
373prologs, switch code, and the like.
95f51977
C
374.I Stab.c
375contains machine dependent code for
376producing external symbol table information
377which can drive a symbolic debugger.
c9528a00
C
378.PP
379The second pass
380is produced by compiling and loading
c9528a00 381.I allo.c ,
95f51977
C
382.I common.c ,
383.I local2.c ,
c9528a00 384.I match.c ,
c9528a00 385.I order.c ,
95f51977 386.I reader.c
c9528a00
C
387and
388.I table.c .
389.I Reader.c
390reads the intermediate file, and controls the major logic of the
391code generation.
392.I Allo.c
393keeps track of busy and free registers.
394.I Match.c
395controls the matching
396of code templates to subtrees of the expression tree to be compiled.
95f51977
C
397.I Common.c
398defines certain service routines,
c9528a00
C
399as in the first pass.
400The above files are machine independent.
401.I Order.c
402controls the machine dependent details of the code generation strategy.
403.I Local2.c
404has many small machine dependent routines,
405and tables of opcodes, register types, etc.
406.I Table.c
407has the code template tables,
408which are also clearly machine dependent.
409.SH
95f51977 410Data Structure Considerations
c9528a00
C
411.PP
412This section discusses the node numbers, type words, and expression trees, used
413throughout both passes of the compiler.
414.PP
415The file
95f51977 416.I manifest.h
c9528a00
C
417defines those symbols used throughout both passes.
418The intent is to use the same symbol name (e.g., MINUS)
419for the given operator throughout the lexical analysis, parsing, tree building,
95f51977
C
420and code generation phases.
421.I Manifest.h
422obtains some of its definitions from
423two other header files,
424.I localdefs.h
425and
426.I pcc.h .
427.I Localdefs.h
428contains definitions for operator symbols
429which are specific to the C compiler.
430.I Pcc.h
431contains definitions for operators and types
432which may be used by other compilers
433to communicate with a portable code generator
434based on pass 2;
435this code generator will be described later.
c9528a00
C
436.PP
437A token
438like MINUS may be seen in the lexical analyzer before it is known
439whether it is a unary or binary operator;
440clearly, it is necessary to know this by the time the parse tree
441is constructed.
442Thus, an operator (really a macro) called
443UNARY is provided, so that MINUS
444and UNARY MINUS are both distinct node numbers.
445Similarly, many binary operators exist in an assignment form (for example, \-=),
446and the operator ASG may be applied to such node names to generate new ones, e.g. ASG MINUS.
447.PP
448It is frequently desirable to know if a node represents a leaf (no descendants), a unary operator (one
449descendant) or a binary operator (two descendants).
450The macro
451.I optype(o)
452returns one of the manifest constants LTYPE, UTYPE, or BITYPE, respectively, depending
453on the node number
454.I o .
455Similarly,
456.I asgop(o)
457returns true if
458.I o
459is an assignment operator number (=, +=, etc. ), and
460.I logop(o)
461returns true if
462.I o
463is a relational or logical (&&, \(or\(or, or !) operator.
464.PP
465C has a rich typing structure, with a potentially infinite number of types.
466To begin with, there are the basic types: CHAR, SHORT, INT, LONG, the unsigned versions
467known as
468UCHAR, USHORT, UNSIGNED, ULONG, and FLOAT, DOUBLE,
469and finally
470STRTY (a structure), UNIONTY, and ENUMTY.
471Then, there are three operators that can be applied to types to make others:
472if
473.I t
474is a type, we may potentially have types
475.I "pointer to t" ,
476.I "function returning t" ,
477and
478.I "array of t's"
479generated from
480.I t .
481Thus, an arbitrary type in C consists of a basic type, and zero or more of these operators.
482.PP
483In the compiler, a type is represented by an unsigned integer; the rightmost four bits hold the basic
484type, and the remaining bits are divided into two-bit fields, containing
4850 (no operator), or one of the three operators
486described above.
487The modifiers are read right to left in the word, starting with the two-bit
488field adjacent to the basic type, until a field with 0 in it is reached.
489The macros PTR, FTN, and ARY represent the
490.I "pointer to" ,
491.I "function returning" ,
492and
493.I "array of"
494operators.
495The macro values are shifted so that they align with the first two-bit
496field; thus PTR+INT
497represents the type for an integer pointer, and
498.DS
499ARY + (PTR<<2) + (FTN<<4) + DOUBLE
500.DE
95f51977 501represents the type of an array of pointers to functions returning \fBdouble\fPs.
c9528a00
C
502.PP
503The type words are ordinarily manipulated by macros.
504If
505.I t
506is a type word,
507.I BTYPE(t)
508gives the basic type.
509.I ISPTR(t) ,
510.I ISARY(t) ,
511and
512.I ISFTN(t)
513ask if an object of this type is a pointer, array, or a function,
514respectively.
515.I MODTYPE(t,b)
516sets the basic type of
517.I t
518to
519.I b .
520.I DECREF(t)
521gives the type resulting from removing the first operator from
522.I t .
523Thus, if
524.I t
525is a pointer to
95f51977 526.I t\(fm ,
c9528a00 527a function returning
95f51977 528.I t\(fm ,
c9528a00 529or an array of
95f51977 530.I t\(fm ,
c9528a00
C
531then
532.I DECREF(t)
533would equal
95f51977 534.I t\(fm .
c9528a00
C
535.I INCREF(t)
536gives the type representing a pointer to
537.I t .
538Finally, there are operators for dealing with the unsigned types.
539.I ISUNSIGNED(t)
540returns true if
541.I t
542is one of the four basic unsigned types;
543in this case,
544.I DEUNSIGN(t)
545gives the associated `signed' type.
546Similarly,
547.I UNSIGNABLE(t)
548returns true if
549.I t
550is one of the four basic types that could become unsigned, and
551.I ENUNSIGN(t)
552returns the unsigned analogue of
553.I t
554in this case.
555.PP
556The other important global data structure is that of expression trees.
557The actual shapes of the nodes are given in
95f51977
C
558.I ndu.h .
559The information stored for each pass is not quite the same;
560in the first pass, nodes contain
561dimension and size information, while in the second pass
c9528a00
C
562nodes contain register allocation information.
563Nevertheless, all nodes contain fields called
564.I op ,
565containing the node number,
566and
567.I type ,
568containing the type word.
569A function called
570.I talloc()
571returns a pointer to a new tree node.
572To free a node, its
573.I op
574field need merely be set to FREE.
575The other fields in the node will remain intact at least until the next allocation.
576.PP
577Nodes representing binary operators contain fields,
578.I left
579and
580.I right ,
581that contain pointers to the left and right descendants.
582Unary operator nodes have the
583.I left
584field, and a value field called
585.I rval .
586Leaf nodes, with no descendants, have two value fields:
587.I lval
588and
589.I rval .
590.PP
591At appropriate times, the function
592.I tcheck()
593can be called, to check that there are no busy nodes remaining.
594This is used as a compiler consistency check.
595The function
596.I tcopy(p)
597takes a pointer
598.I p
599that points to an expression tree, and returns a pointer
600to a disjoint copy of the tree.
601The function
602.I walkf(p,f)
603performs a postorder walk of the tree pointed to by
604.I p ,
605and applies the function
606.I f
607to each node.
608The function
609.I fwalk(p,f,d)
610does a preorder walk of the tree pointed to by
611.I p .
612At each node, it calls a function
613.I f ,
614passing to it the node pointer, a value passed down
615from its ancestor, and two pointers to values to be passed
616down to the left and right descendants (if any).
617The value
618.I d
619is the value passed down to the root.
c9528a00
C
620.I Fwalk
621is used for a number of tree labeling and debugging activities.
622.PP
623The other major data structure, the symbol table, exists only in pass one,
624and will be discussed later.
625.SH
626Pass One
627.PP
628The first pass does lexical analysis, parsing, symbol table maintenance,
629tree building, optimization, and a number of machine dependent things.
630This pass is largely machine independent, and the machine independent
631sections can be pretty successfully ignored.
632Thus, they will be only sketched here.
633.SH
634Lexical Analysis
635.PP
636The lexical analyzer is a conceptually simple routine that reads the input
637and returns the tokens of the C language as it encounters them:
638names, constants, operators, and keywords.
639The conceptual simplicity of this job is confounded a bit by several
640other simple jobs that unfortunately must go on simultaneously.
641These include
642.IP \(bu
643Keeping track of the current filename and line number, and occasionally
644setting this information as the result of preprocessor control lines.
645.IP \(bu
646Skipping comments.
647.IP \(bu
648Properly dealing with octal, decimal, hex, floating
649point, and character constants, as well as character strings.
650.PP
651To achieve speed, the program maintains several tables
652that are indexed into by character value, to tell
653the lexical analyzer what to do next.
654To achieve portability, these tables must be initialized
655each time the compiler is run, in order that the
656table entries reflect the local character set values.
657.SH
658Parsing
659.PP
95f51977 660As mentioned above, the parser is generated by Yacc from the grammar
c9528a00
C
661.I cgram.y.
662The grammar is relatively readable, but contains some unusual features
663that are worth comment.
664.PP
665Perhaps the strangest feature of the grammar is the treatment of
666declarations.
667The problem is to keep track of the basic type
668and the storage class while interpreting the various
669stars, brackets, and parentheses that may surround a given name.
670The entire declaration mechanism must be recursive,
671since declarations may appear within declarations of
672structures and unions, or even within a
673.B sizeof
674construction
675inside a dimension in another declaration!
676.PP
677There are some difficulties in using a bottom-up parser,
678such as produced by Yacc, to handle constructions where a lot
679of left context information must be kept around.
680The problem is that the original PDP-11 compiler is top-down in
681implementation, and some of the semantics of C reflect this.
682In a top-down parser, the input rules are restricted
683somewhat, but one can naturally associate temporary
684storage with a rule at a very early stage in the recognition
685of that rule.
686In a bottom-up parser, there is more freedom in the
687specification of rules, but it is more difficult to know what
688rule is being matched until the entire rule is seen.
689The parser described by
95f51977 690.I cgram.y
c9528a00
C
691makes effective use of
692the bottom-up parsing mechanism in some places (notably the treatment
693of expressions), but struggles against the
694restrictions in others.
695The usual result is that it is necessary to run a stack of values
696``on the side'', independent of the Yacc value stack,
697in order to be able to store and access information
698deep within inner constructions, where the relationship of the
699rules being recognized to the total picture is not yet clear.
700.PP
701In the case of declarations, the attribute information
702(type, etc.) for a declaration is carefully
703kept immediately to the left of the declarator
704(that part of the declaration involving the name).
705In this way, when it is time to declare the name, the
706name and the type information can be quickly brought together.
707The ``$0'' mechanism of Yacc is used to accomplish this.
708The result is not pretty, but it works.
709The storage class information changes more slowly,
710so it is kept in an external variable, and stacked if
711necessary.
712Some of the grammar could be considerably cleaned up by using
713some more recent features of Yacc, notably actions within
714rules and the ability to return multiple values for actions.
715.PP
716A stack is also used to keep track of the current location
717to be branched to when a
718.B break
719or
720.B continue
721statement is processed.
722.PP
723This use of external stacks dates from the time when Yacc did not permit
724values to be structures.
725Some, or most, of this use of external stacks
726could be eliminated by redoing the grammar to use the mechanisms now provided.
727There are some areas, however, particularly the processing of structure, union,
95f51977 728and enumeration declarations, function
c9528a00
C
729prologs, and switch statement processing, when having
730all the affected data together in an array speeds later
731processing; in this case, use of external storage seems essential.
732.PP
733The
734.I cgram.y
735file also contains some small functions used as
736utility functions in the parser.
737These include routines for saving case values and labels in processing switches,
738and stacking and popping
739values on the external stack described above.
740.SH
741Storage Classes
742.PP
743C has a finite, but fairly extensive, number of storage classes
744available.
745One of the compiler design decisions was to
746process the storage class information totally in the first pass;
747by the second pass, this information must have
748been totally dealt with.
749This means that all of the storage allocation must take place in the first
750pass, so that references to automatics and
751parameters can be turned into references to cells lying a certain
752number of bytes offset from certain machine registers.
753Much of this transformation is machine dependent, and strongly
754depends on the storage class.
755.PP
756The classes include EXTERN (for externally declared, but not defined variables),
757EXTDEF (for external definitions), and similar distinctions for
758USTATIC and STATIC, UFORTRAN and FORTRAN (for fortran functions) and
759ULABEL and LABEL.
760The storage classes REGISTER and AUTO are obvious, as
761are STNAME, UNAME, and ENAME (for structure, union, and enumeration
762tags), and the associated MOS, MOU, and MOE (for the members).
763TYPEDEF is treated as a storage class as well.
764There are two special storage classes: PARAM and SNULL.
765SNULL is used to distinguish the case where no explicit
766storage class has been given; before an entry is made
767in the symbol table the true storage class is discovered.
768Similarly, PARAM is used for the temporary entry in the symbol
769table made before the declaration of function parameters is completed.
770.PP
771The most complexity in the storage class process comes from
772bit fields.
773A separate storage class is kept for each width bit field;
774a
775.I k
776bit bit field has storage class
777.I k
778plus FIELD.
779This enables the size to be quickly recovered from the storage class.
780.SH
95f51977 781Symbol Table Maintenance
c9528a00
C
782.PP
783The symbol table routines do far more than simply enter
784names into the symbol table;
785considerable semantic processing and checking is done as well.
786For example, if a new declaration comes in, it must be checked
787to see if there is a previous declaration of the same symbol.
788If there is, there are many cases.
789The declarations may agree and be compatible (for example,
95f51977 790an \fBextern\fP declaration can appear twice) in which case the
c9528a00
C
791new declaration is ignored.
792The new declaration may add information (such as an explicit array
793dimension) to an already present declaration.
794The new declaration may be different, but still correct (for example,
95f51977 795an \fBextern\fP declaration of something may be entered,
c9528a00
C
796and then later the definition may be seen).
797The new declaration may be incompatible, but appear in an inner block;
798in this case, the old declaration is carefully hidden away, and
799the new one comes into force until the block is left.
800Finally, the declarations may be incompatible, and an error
801message must be produced.
802.PP
803A number of other factors make for additional complexity.
804The type declared by the user is not always the type
95f51977 805entered into the symbol table (for example, if a formal parameter to a function
c9528a00
C
806is declared to be an array, C requires that this be changed into
807a pointer before entry in the symbol table).
808Moreover, there are various kinds of illegal types that
809may be declared which are difficult to
810check for syntactically (for example,
811a function returning an array).
812Finally, there is a strange feature in C that requires
813structure tag names and member names for structures and unions
814to be taken from a different logical symbol table than ordinary identifiers.
815Keeping track of which kind of name is involved is a bit of struggle
816(consider typedef names used within structure declarations, for example).
817.PP
818The symbol table handling routines have been rewritten a number of times to
819extend features, improve performance, and fix bugs.
820They address the above problems with reasonable effectiveness
821but a singular lack of grace.
822.PP
823When a name is read in the input, it is hashed, and the
824routine
825.I lookup
826is called, together with a flag which tells which symbol table
827should be searched (actually, both symbol tables are stored in one, and a flag
828is used to distinguish individual entries).
829If the name is found,
830.I lookup
831returns the index to the entry found; otherwise, it makes
832a new entry, marks it UNDEF (undefined), and returns the
833index of the new entry.
834This index is stored in the
835.I rval
836field of a NAME node.
837.PP
838When a declaration is being parsed, this NAME node is
95f51977 839made part of a tree with UNARY MUL nodes for each \fB*\fP,
c9528a00
C
840LB nodes for each array descriptor (the right descendant
841has the dimension), and UNARY CALL nodes for each function
842descriptor.
843This tree is passed to the routine
844.I tymerge ,
845along with the attribute type of the whole declaration;
846this routine collapses the tree to a single node, by calling
847.I tyreduce ,
848and then modifies the type to reflect the overall
849type of the declaration.
850.PP
851Dimension and size information is stored in a table called
852.I dimtab .
853To properly describe a type in C, one needs not just the
854type information but also size information (for structures and
95f51977 855enumerations) and dimension information (for arrays).
c9528a00
C
856Sizes and offsets are dealt with in the compiler by
857giving the associated indices into
858.I dimtab .
859.I Tymerge
860and
861.I tyreduce
862call
863.I dstash
864to put the discovered dimensions away into the
865.I dimtab
866array.
867.I Tymerge
868returns a pointer to a single node that contains
869the symbol table index in its
870.I rval
871field, and the size and dimension indices in
872fields
873.I csiz
874and
875.I cdim ,
876respectively.
877This information is properly considered part of the type in the first pass,
878and is carried around at all times.
879.PP
880To enter an element into the symbol table, the routine
881.I defid
882is called; it is handed a storage class, and a pointer
883to the node produced by
884.I tymerge .
885.I Defid
886calls
887.I fixtype ,
888which adjusts and checks the given type depending on the storage
889class, and converts null types appropriately.
890It then calls
891.I fixclass ,
892which does a similar job for the storage class;
893it is here, for example, that
95f51977
C
894\fBregister\fP declarations are either allowed or changed
895to \fBauto\fP.
c9528a00
C
896.PP
897The new declaration is now compared against an older one,
898if present, and several pages of validity checks performed.
899If the definitions are compatible, with possibly some added information,
900the processing is straightforward.
901If the definitions differ, the block levels of the
902current and the old declaration are compared.
903The current block level is kept in
904.I blevel ,
905an external variable; the old declaration level is kept in the symbol table.
906Block level 0 is for external declarations, 1 is for arguments to functions,
907and 2 and above are blocks within a function.
908If the current block level is the same as the old declaration, an error
909results.
910If the current block level is higher, the new declaration overrides the old.
911This is done by marking the old symbol table entry ``hidden'', and making
912a new entry, marked ``hiding''.
913.I Lookup
914will skip over hidden entries.
915When a block is left, the symbol table is searched,
916and any entries defined in that block are destroyed; if
917they hid other entries, the old entries are ``unhidden''.
918.PP
919This nice block structure is warped a bit because labels
920do not follow the block structure rules (one can do a
921.B goto
922into
923a block, for example);
924default definitions of functions in inner blocks also persist clear out to the outermost scope.
925This implies that cleaning up the symbol table after block exit is more
926subtle than it might first seem.
927.PP
928For successful new definitions,
929.I defid
930also initializes a ``general purpose'' field,
931.I offset ,
932in the symbol table.
933It contains the stack offset for automatics and parameters, the register number
934for register variables, the bit offset into the structure for
935structure members, and
936the internal label number for static variables and labels.
937The offset field is set by
938.I falloc
939for bit fields, and
940.I dclstruct
941for structures and unions.
942.PP
943The symbol table entry itself thus contains
944the name, type word, size and dimension offsets,
945offset value, and declaration block level.
946It also has a field of flags, describing what symbol table the
947name is in, and whether the entry is hidden, or hides another.
948Finally, a field gives the line number of the last use,
949or of the definition, of the name.
950This is used mainly for diagnostics, but is useful to
951.I lint
952as well.
953.PP
954In some special cases, there is more than the above amount of information kept
955for the use of the compiler.
956This is especially true with structures; for use in initialization,
957structure declarations must have access to a list of the members of the
958structure.
959This list is also kept in
960.I dimtab .
961Because a structure can be mentioned long before the
962members are known, it is necessary to have another
963level of indirection in the table.
964The two words following the
965.I csiz
966entry in
967.I dimtab
968are used to hold the alignment of the structure, and
969the index in dimtab of the list of members.
970This list contains the symbol table indices for the structure members, terminated by a
971\-1.
972.SH
973Tree Building
974.PP
975The portable compiler transforms expressions
976into expression trees.
977As the parser recognizes each rule making up an
978expression,
979it calls
980.I buildtree
981which is given an operator number, and pointers to the
982left and right descendants.
983.I Buildtree
984first examines the left and right descendants,
985and, if they are both constants, and the operator
986is appropriate, simply does the constant
987computation at compile time, and returns
988the result as a constant.
989Otherwise,
990.I buildtree
991allocates a node for the head of the tree,
992attaches the descendants to it, and ensures that
993conversion operators are generated if needed, and that
994the type of the new node is consistent with the types
995of the operands.
996There is also a considerable amount of semantic complexity here;
997many combinations of types are illegal, and the portable
998compiler makes a strong effort to check
999the legality of expression types completely.
1000This is done both for
1001.I lint
1002purposes, and to prevent such semantic errors
1003from being passed through to the code generator.
1004.PP
1005The heart of
1006.I buildtree
1007is a large table, accessed by the routine
1008.I opact .
1009This routine maps the types of the left and right
1010operands into a rather smaller set of descriptors, and then
1011accesses a table (actually encoded in a switch statement) which
1012for each operator and pair of types causes
1013an action to be returned.
1014The actions are logical or's of a number of
1015separate actions, which may be
1016carried out by
1017.I buildtree .
1018These component actions may include
1019checking the left side to ensure that it
1020is an lvalue (can be stored into),
1021applying a type conversion to the left or right operand,
1022setting the type of the new node to
1023the type of the left or right operand, calling various
1024routines to balance the types of the left and right operands,
1025and suppressing the ordinary conversion
1026of arrays and function operands to pointers.
1027An important operation is OTHER, which causes
1028some special code to be invoked
1029in
1030.I buildtree ,
1031to handle issues which are unique to a particular operator.
1032Examples of this are
1033structure and union reference
1034(actually handled by
1035the routine
1036.I stref ),
1037the building of NAME, ICON, STRING and FCON (floating point constant) nodes,
95f51977
C
1038unary \fB*\fP and \fB&\fP, structure assignment, and calls.
1039In the case of unary \fB*\fP and \fB&\fP,
c9528a00 1040.I buildtree
95f51977
C
1041will cancel a \fB*\fP applied to a tree, the top node of which
1042is \fB&\fP, and conversely.
c9528a00
C
1043.PP
1044Another special operation is
1045PUN; this
1046causes the compiler to check for type mismatches,
1047such as intermixing pointers and integers.
1048.PP
95f51977 1049The treatment of conversion operators is a rather
c9528a00 1050strange area of the compiler (and of C!).
95f51977 1051The introduction of type casts only confounded this
c9528a00
C
1052situation.
1053Most of the conversion operators are generated by
1054calls to
1055.I tymatch
1056and
1057.I ptmatch ,
1058both of which are given a tree, and asked to make the
1059operands agree in type.
1060.I Ptmatch
1061treats the case where one of the operands is a pointer;
1062.I tymatch
1063treats all other cases.
1064Where these routines have decided on the
1065proper type for an operand, they call
1066.I makety ,
1067which is handed a tree, and a type word, dimension offset, and size offset.
1068If necessary, it inserts a conversion operation to make the
1069types correct.
1070Conversion operations are never inserted on the left side of
1071assignment operators, however.
1072There are two conversion operators used;
1073PCONV, if the conversion is to a non-basic type (usually a pointer),
1074and
1075SCONV, if the conversion is to a basic type (scalar).
1076.PP
1077To allow for maximum flexibility, every node produced by
1078.I buildtree
1079is given to a machine dependent routine,
1080.I clocal ,
1081immediately after it is produced.
1082This is to allow more or less immediate rewriting of those
1083nodes which must be adapted for the local machine.
1084The conversion operations are given to
1085.I clocal
1086as well; on most machines, many of these
1087conversions do nothing, and should be thrown away
1088(being careful to retain the type).
1089If this operation is done too early,
1090however,
1091later calls to
1092.I buildtree
1093may get confused about correct type of the
1094subtrees;
1095thus
1096.I clocal
95f51977 1097is given the conversion operations only after the entire tree is built.
c9528a00
C
1098This topic will be dealt with in more detail later.
1099.SH
1100Initialization
1101.PP
1102Initialization is one of the messier areas in the portable compiler.
1103The only consolation is that most of the mess takes place
1104in the machine independent part, where it
1105is may be safely ignored by the implementor of the
1106compiler for a particular machine.
1107.PP
1108The basic problem is that the semantics of initialization
1109really calls for a co-routine structure; one collection
1110of programs reading constants from the input stream, while another,
1111independent set of programs places these constants into the
1112appropriate spots in memory.
1113The dramatic differences in the local assemblers also
1114come to the fore here.
1115The parsing problems are dealt with by keeping a rather
1116extensive stack containing the current
1117state of the initialization; the assembler
1118problems are dealt with by having a fair number of machine dependent routines.
1119.PP
1120The stack contains the symbol table number,
1121type, dimension index, and size index for the current identifier
1122being initialized.
1123Another entry has the offset, in bits, of the beginning
1124of the current identifier.
1125Another entry keeps track of how many elements have been seen,
1126if the current identifier is an array.
1127Still another entry keeps track of the current
1128member of a structure being initialized.
1129Finally, there is an entry containing flags
1130which keep track of the current state of the initialization process
95f51977 1131(e.g., tell if a `}' has been seen for the current identifier).
c9528a00
C
1132.PP
1133When an initialization begins, the routine
1134.I beginit
1135is called; it handles the alignment restrictions, if
1136any, and calls
1137.I instk
1138to create the stack entry.
1139This is done by first making an entry on the top of the stack for the item
1140being initialized.
1141If the top entry is an array, another entry is made on the stack
1142for the first element.
1143If the top entry is a structure, another entry is made on the
1144stack for the first member of the structure.
1145This continues until the top element of the stack is a scalar.
1146.I Instk
1147then returns, and the parser begins collecting initializers.
1148.PP
1149When a constant is obtained, the routine
1150.I doinit
1151is called; it examines the stack, and does whatever
1152is necessary to assign the current constant to the
1153scalar on the top of the stack.
1154.I gotscal
1155is then called, which rearranges the stack so that the
1156next scalar to be initialized gets placed on top of the stack.
1157This process continues until the end of the initializers;
1158.I endinit
1159cleans up.
95f51977 1160If a `{' or `}' is encountered in the
c9528a00
C
1161string of initializers, it is handled by calling
1162.I ilbrace
1163or
1164.I irbrace ,
1165respectively.
1166.PP
1167A central issue is the treatment of the ``holes'' that
1168arise as a result of alignment restrictions or explicit
1169requests for holes in bit fields.
1170There is a global variable,
1171.I inoff ,
1172which contains the current offset in the initialization
1173(all offsets in the first pass of the compiler are in bits).
1174.I Doinit
1175figures out from the top entry on the stack the expected
1176bit offset of the next identifier; it calls the
1177machine dependent
1178routine
1179.I inforce
1180which, in a machine dependent way, forces
1181the assembler to
1182set aside space if need be so that the
1183next scalar seen will go into the appropriate
1184bit offset position.
1185The scalar itself is passed to one of the machine dependent
1186routines
1187.I fincode
1188(for floating point initialization),
1189.I incode
1190(for fields, and other initializations less than an int in
1191size),
1192and
1193.I cinit
1194(for all other initializations).
1195The size is passed to all these routines, and it is up to
1196the machine dependent routines to ensure that the
1197initializer occupies exactly the right size.
1198.PP
1199Character strings represent a bit of an exception.
1200If a character string is seen as the initializer for
1201a pointer, the characters making up the string must
1202be put out under a different location counter.
1203When the lexical analyzer sees the quote at the head
1204of a character string, it returns the token STRING,
1205but does not do anything with the contents.
1206The parser calls
1207.I getstr ,
1208which sets up the appropriate location counters
1209and flags, and calls
1210.I lxstr
1211to read and process the contents of the string.
1212.PP
1213If the string is being used to initialize a character array,
1214.I lxstr
1215calls
1216.I putbyte ,
1217which in effect simulates
1218.I doinit
1219for each character read.
1220If the string is used to initialize a character pointer,
1221.I lxstr
1222calls a machine dependent routine,
1223.I bycode ,
1224which stashes away each character.
1225The pointer to this string is then returned,
1226and processed normally by
1227.I doinit .
1228.PP
1229The null at the end of the string is treated as if it
1230were read explicitly by
1231.I lxstr .
1232.SH
1233Statements
1234.PP
1235The first pass addresses four main areas; declarations, expressions, initialization, and statements.
1236The statement processing is relatively simple; most of it is carried out in the
1237parser directly.
1238Most of the logic is concerned with allocating
1239label numbers, defining the labels, and branching appropriately.
1240An external symbol,
1241.I reached ,
1242is 1 if a statement can be reached, 0 otherwise; this is
1243used to do a bit of simple flow analysis as the program is being parsed,
1244and also to avoid generating the subroutine return sequence if the subroutine
1245cannot ``fall through'' the last statement.
1246.PP
1247Conditional branches are handled by generating an expression
1248node, CBRANCH,
1249whose left descendant is the conditional expression and the
1250right descendant is an ICON node containing the internal label
1251number to be branched to.
1252For efficiency, the semantics are that
1253the label is gone to if the condition is
1254.I false .
1255.PP
1256The switch statement is
1257compiled by collecting the case entries, and an indication as to whether
1258there is a default case;
1259an internal label number is generated for each of these,
1260and remembered in a big array.
1261The expression comprising the value to be switched on is
1262compiled when the switch keyword is encountered,
1263but the expression tree is headed by
1264a special node, FORCE, which tells the code generator to
1265put the expression value into a special distinguished
1266register (this same mechanism is used for processing the
1267return statement).
1268When the end of the switch block is reached, the array
1269containing the case values is sorted, and checked for
1270duplicate entries (an error); if all is
1271correct, the machine dependent routine
1272.I genswitch
1273is called, with this array of labels and values in increasing order.
1274.I Genswitch
1275can assume that the value to be tested is already in the
1276register which is the usual integer return value register.
1277.SH
1278Optimization
1279.PP
1280There is a machine independent file,
1281.I optim.c ,
1282which contains a relatively short optimization routine,
1283.I optim .
1284Actually the word optimization is something of a misnomer;
1285the results are not optimum, only improved, and the
1286routine is in fact not optional; it must
1287be called for proper operation of the compiler.
1288.PP
1289.I Optim
1290is called after an expression tree is built, but
1291before the code generator is called.
1292The essential part of its job is to call
1293.I clocal
1294on the conversion operators.
1295On most machines, the treatment of
95f51977 1296\fB&\fP is also essential:
c9528a00 1297by this time in the processing, the only node which
95f51977
C
1298is a legal descendant of \fB&\fP is NAME.
1299(Possible descendants of \fB*\fP have been eliminated by
1300.I buildtree .)
c9528a00
C
1301The address of a static name is, almost by definition, a
1302constant, and can be represented by an ICON node on most machines
1303(provided that the loader has enough power).
1304Unfortunately, this is not universally true; on some machine, such as the IBM 370,
1305the issue of addressability rears its ugly head;
1306thus, before turning a NAME node into an ICON node,
1307the machine dependent function
1308.I andable
1309is called.
1310.PP
1311The optimization attempts of
1312.I optim
95f51977 1313are quite limited.
c9528a00
C
1314It is primarily concerned with improving the behavior of
1315the compiler with operations one of whose arguments is a constant.
1316In the simplest case, the constant is placed on the right if the
1317operation is commutative.
1318The compiler also makes a limited search for expressions
1319such as
1320.DS
95f51977 1321( \fIx\fP + \fIa\fP ) + \fIb\fP
c9528a00
C
1322.DE
1323where
1324.I a
1325and
1326.I b
1327are constants, and attempts to combine
1328.I a
1329and
1330.I b
1331at compile time.
1332A number of special cases are also examined;
1333additions of 0 and multiplications by 1 are removed,
1334although the correct processing of these cases to get
1335the type of the resulting tree correct is
1336decidedly nontrivial.
1337In some cases, the addition or multiplication must be replaced by
95f51977 1338a conversion operator to keep the types from becoming
c9528a00 1339fouled up.
95f51977
C
1340In cases where a relational operation is being done
1341and one operand is a constant, the operands are permuted and the operator altered, if necessary,
c9528a00
C
1342to put the constant on the right.
1343Finally, multiplications by a power of 2 are changed to shifts.
c9528a00
C
1344.SH
1345Machine Dependent Stuff
1346.PP
1347A number of the first pass machine dependent routines have been discussed above.
1348In general, the routines are short, and easy to adapt from
1349machine to machine.
1350The two exceptions to this general rule are
1351.I clocal
1352and
1353the function prolog and epilog generation routines,
1354.I bfcode
1355and
1356.I efcode .
1357.PP
1358.I Clocal
1359has the job of rewriting, if appropriate and desirable,
1360the nodes constructed by
1361.I buildtree .
1362There are two major areas where this
95f51977 1363is important:
c9528a00
C
1364NAME nodes and conversion operations.
1365In the case of NAME nodes,
1366.I clocal
1367must rewrite the NAME node to reflect the
1368actual physical location of the name in the machine.
1369In effect, the NAME node must be examined, the symbol table
1370entry found (through the
1371.I rval
1372field of the node),
1373and, based on the storage class of the node,
1374the tree must be rewritten.
1375Automatic variables and parameters are typically
1376rewritten by treating the reference to the variable as
1377a structure reference, off the register which
1378holds the stack or argument pointer;
1379the
1380.I stref
1381routine is set up to be called in this way, and to
1382build the appropriate tree.
1383In the most general case, the tree consists
95f51977
C
1384of a unary \fB*\fP node, whose descendant is
1385a \fB+\fP node, with the stack or argument register as left operand,
c9528a00
C
1386and a constant offset as right operand.
1387In the case of LABEL and internal static nodes, the
1388.I rval
1389field is rewritten to be the negative of the internal
1390label number; a negative
1391.I rval
1392field is taken to be an internal label number.
1393Finally, a name of class REGISTER must be converted into a REG node,
1394and the
1395.I rval
1396field replaced by the register number.
1397In fact, this part of the
1398.I clocal
1399routine is nearly machine independent; only for machines
1400with addressability problems (IBM 370 again!) does it
95f51977 1401have to be noticeably different.
c9528a00
C
1402.PP
1403The conversion operator treatment is rather tricky.
1404It is necessary to handle the application of conversion operators
1405to constants in
1406.I clocal ,
1407in order that all constant expressions can have their values known
1408at compile time.
1409In extreme cases, this may mean that some simulation of the
1410arithmetic of the target machine might have to be done in a
1411cross-compiler.
1412In the most common case,
1413conversions from pointer to pointer do nothing.
1414For some machines, however, conversion from byte pointer to short or long
1415pointer might require a shift or rotate operation, which would
1416have to be generated here.
1417.PP
1418The extension of the portable compiler to machines where the size of a pointer
1419depends on its type would be straightforward, but has not yet been done.
1420.PP
95f51977
C
1421Another machine dependent issue in the first pass
1422is the generation of external ``symbol table'' information.
1423This sort of symbol table is used by programs such as symbolic debuggers
1424to relate object code back to source code.
1425Symbol table routines are provided in
1426the file \fIstab.c\fP,
1427which is included in the machine dependent sources
1428for the first pass.
1429The symbol table routines insert assembly code
1430containing assembly pseudo-ops directly into
1431the instruction stream generated by the compiler.
1432.PP
1433There are two basic kinds of symbol table operations.
1434The simplest operation is the generation of a source line number;
1435this serves to map an address in an executable image
1436into a line in a source file so that a debugger
1437can find the source code
1438corresponding to the instructions being executed.
1439The routine \fIpsline\fP is called by the scanner
1440to emit source line numbers when
1441a nonempty source line is seen.
1442The other variety of symbol table operation
1443is the generation of type and address information
1444about C symbols.
1445This is done through the \fIoutstab\fP routine,
1446which is normally called using the FIXDEF macro
1447in the monster \fIdefid\fP routine in \fIpftn.c\fP
1448that enters symbols into the compiler's internal symbol table.
1449.PP
1450Yet another major machine dependent issue involves function prolog and epilog
c9528a00
C
1451generation.
1452The hard part here is the design of the stack frame
1453and calling sequence; this design issue is discussed elsewhere.
1454.[
1455Johnson Lesk Ritchie calling sequence
1456.]
1457The routine
1458.I bfcode
1459is called with the number of arguments
1460the function is defined with, and
1461an array containing the symbol table indices of the
1462declared parameters.
1463.I Bfcode
1464must generate the code to establish the new stack frame,
1465save the return address and previous stack pointer
1466value on the stack, and save whatever
1467registers are to be used for register variables.
1468The stack size and the number of register variables is not
1469known when
1470.I bfcode
1471is called, so these numbers must be
1472referred to by assembler constants, which are
1473defined when they are known (usually in the second pass,
1474after all register variables, automatics, and temporaries have been seen).
1475The final job is to find those parameters which may have been declared
1476register, and generate the code to initialize
1477the register with the value passed on the stack.
1478Once again, for most machines, the general logic of
1479.I bfcode
1480remains the same, but the contents of the
1481.I printf
1482calls in it will change from machine to machine.
1483.I efcode
1484is rather simpler, having just to generate the default
1485return at the end of a function.
1486This may be nontrivial in the case of a function returning a structure or union, however.
1487.PP
1488There seems to be no really good place to discuss structures and unions, but
1489this is as good a place as any.
1490The C language now supports structure assignment,
1491and the passing of structures as arguments to functions,
1492and the receiving of structures back from functions.
1493This was added rather late to C, and thus to the portable compiler.
1494Consequently, it fits in less well than the older features.
1495Moreover, most of the burden of making these features work is
1496placed on the machine dependent code.
1497.PP
1498There are both conceptual and practical problems.
1499Conceptually, the compiler is structured around
1500the idea that to compute something, you put it into
1501a register and work on it.
1502This notion causes a bit of trouble on some machines (e.g., machines with 3-address opcodes), but
1503matches many machines quite well.
1504Unfortunately, this notion breaks down with structures.
1505The closest that one can come is to keep the addresses of the
1506structures in registers.
1507The actual code sequences used to move structures vary from the
1508trivial (a multiple byte move) to the horrible (a
1509function call), and are very machine dependent.
1510.PP
1511The practical problem is more painful.
1512When a function returning a structure is called, this function
1513has to have some place to put the structure value.
1514If it places it on the stack, it has difficulty popping its stack frame.
1515If it places the value in a static temporary, the routine fails to be
1516reentrant.
1517The most logically consistent way of implementing this is for the
1518caller to pass in a pointer to a spot where the called function
1519should put the value before returning.
1520This is relatively straightforward, although a bit tedious, to implement,
1521but means that the caller must have properly declared
1522the function type, even if the value is never used.
1523On some machines, such as the Interdata 8/32, the return value
1524simply overlays the argument region (which on the 8/32 is part
1525of the caller's stack frame).
1526The caller takes care of leaving enough room if the returned value is larger
1527than the arguments.
95f51977 1528This also assumes that the caller declares the
c9528a00
C
1529function properly.
1530.PP
95f51977 1531The PDP-11 and the \*V have stack hardware which is used in function calls and returns;
c9528a00
C
1532this makes it very inconvenient to
1533use either of the above mechanisms.
95f51977
C
1534In these machines, a static area within the called function
1535is allocated, and
c9528a00
C
1536the function return value is copied into it on return; the function
1537returns the address of that region.
1538This is simple to implement, but is non-reentrant.
1539However, the function can now be called as a subroutine
1540without being properly declared, without the disaster which would otherwise ensue.
1541No matter what choice is taken, the convention is that the function
1542actually returns the address of the return structure value.
1543.PP
1544In building expression trees, the portable compiler takes a bit for granted about
1545structures.
1546It assumes that functions returning structures
1547actually return a pointer to the structure, and it assumes that
1548a reference to a structure is actually a reference to its address.
1549The structure assignment operator is rebuilt so that the left
1550operand is the structure being assigned to, but the
1551right operand is the address of the structure being assigned;
1552this makes it easier to deal with
1553.DS
1554.I "a = b = c"
1555.DE
1556and similar constructions.
1557.PP
1558There are four special tree nodes associated with these
1559operations:
1560STASG (structure assignment), STARG (structure argument
1561to a function call), and STCALL and UNARY STCALL
1562(calls of a function with nonzero and zero arguments, respectively).
1563These four nodes are unique in that the size and alignment information, which can be determined by
1564the type for all other objects in C,
1565must be known to carry out these operations; special
1566fields are set aside in these nodes to contain
1567this information, and special
1568intermediate code is used to transmit this information.
1569.SH
1570First Pass Summary
1571.PP
1572There are may other issues which have been ignored here,
1573partly to justify the title ``tour'', and partially
1574because they have seemed to cause little trouble.
1575There are some debugging flags
1576which may be turned on, by giving the compiler's first pass
1577the argument
1578.DS
95f51977 1579.B \-X [flags]
c9528a00
C
1580.DE
1581Some of the more interesting flags are
95f51977
C
1582\fB\-Xd\fP for the defining and freeing of symbols,
1583\fB\-Xi\fP for initialization comments, and
1584\fB\-Xb\fP for various comments about the building of trees.
c9528a00
C
1585In many cases, repeating the flag more than once gives more information;
1586thus,
95f51977 1587\fB\-Xddd\fP gives more information than \fB\-Xd\fP.
c9528a00
C
1588In the two pass version of the compiler, the
1589flags should not be set when the output is sent to the second
1590pass, since the debugging output and the intermediate code both go onto the standard
1591output.
1592.PP
1593We turn now to consideration of the second pass.