CA2175711A1 - Incremental compilation of c++ programs - Google Patents

Incremental compilation of c++ programs

Info

Publication number
CA2175711A1
CA2175711A1 CA002175711A CA2175711A CA2175711A1 CA 2175711 A1 CA2175711 A1 CA 2175711A1 CA 002175711 A CA002175711 A CA 002175711A CA 2175711 A CA2175711 A CA 2175711A CA 2175711 A1 CA2175711 A1 CA 2175711A1
Authority
CA
Canada
Prior art keywords
program
source code
declarations
parsing
representation
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Abandoned
Application number
CA002175711A
Other languages
French (fr)
Inventor
Lee Richard Nackman
Michael Karasick
John Joseph Barton
Derek Lieber
David Joseph Streeter
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
IBM Canada Ltd
Original Assignee
IBM Canada Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by IBM Canada Ltd filed Critical IBM Canada Ltd
Priority to CA002175711A priority Critical patent/CA2175711A1/en
Priority to TW085110652A priority patent/TW308676B/en
Priority to US08/838,205 priority patent/US6182281B1/en
Priority to EP97302677A priority patent/EP0805391A3/en
Priority to JP9105811A priority patent/JPH1040114A/en
Publication of CA2175711A1 publication Critical patent/CA2175711A1/en
Abandoned legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/48Incremental compilation

Abstract

An enhanced compiler for compiling C+ + programs without the use of forward declarations normally included in program header files. Through multiple parsingpasses, the compiler extracts definitions for the declarations directly from the bodies of the C+ + files. By saving the definitions to a persistent program representation, for example a program database, on subsequent sweeps, only definitions for new or changed declarations need be updated. In this way, C+ + programs can be incrementally compiled on a declaration by declaration basis.

Description

INCREMENTAL COMPILATION OF C++ PROGRAMS

Field of the Invention The present invention is directed to a technique permitting incremental compilation of C++ programs.

Bacl<ground of the Invention C++ is an object-oriented programming language in which programs are created using a set of language tools, abstraction and constructs that support aparticular form of user-defined types7 called "classes". Each such type associates a collection of declared data with a set of operations on that data. Variables, orinstances7 of such types in the running programs are called objects.
Classes can be related to one another by inheritance. The properties7 behaviors7data, and operations of a parent7 or "base", class may be inherited without modification by some child7 or "derived" class7 or the behaviors7 properties7 and operations may be selectively refined under control of the programmer. When defining a derived class7 one may start by building on an existing base class which is similar to the one to be created. The derived class inherits the implementation and behavior of the base class7 except as modified by amendments detailed in the derived class definition. Several classes can inherit the behaviors of a common parent7 and a derived class may inherit from more than one base class. A member function is a function or operation defined as a behaviour of some user-defined type where that type participates in a hierarchy of other types.
A feature of C+ + programming is that it is text-based7 and its classes are stored in separate files. Class declarations are usually split up into 2 files: a header file with 217~711 extension ".h" or ".hpp" that contains the class declaration with the member fields and the member function headers, and a body file with extension ".C" or ".cpp" that contains the bodies of the member functions.
In conventional C + + programming, the header files contain important preprocessor directives and forward declarations, the latter providing the declaration ordering to ensure that every name is declared before it is used. Header files are inserted into the source file through the use of the preprocessor directive #include.
However, forward declarations must be manually prepared by the programmer;
writing, organizing and maintaining header files (through program revisions) talces considerable programmer time and thought. ~s a result, mistakes in header files are a frequent source of compile errors.
Header files are also a major source of long program build times in C++
programming. As programmers increasingly exploit C+ + classes, the cost of repeatedly reprocessing header files often dominates total compilation time. Oneresult has been the introduction of pre-compiled header files, now supported by most commercial C+ + compilers, to counter this problem.
The idea of providing for selective compilation has been addressed at varying levels of granularity. For example, UIC Patent No. 2 130 406 B of Reiffen, titled Computer System with Real-time Compilation, discusses a system that partially compiles while the user is editing the source program. The compiler compiles up to a "pause location" in the source defined by the editor and then waits. When the user has made changes up to a point where the editor thinlcs the compiler can processmore, it updates the "pause location" and the compiler does a bit more work.
However, this compiler still compiles the source code from start to finish in order. If the user changes the source before the "pause location", the editor tells the compiler to re-initialize and start compiling from the start of source down to the new "pause location".
In C+ + compilers, techniques for implementing a form of incremental compilation have been developed, in which a tool called "mal<e" determines which files need to be recompiled by locating those files with time stamps after the last compilation, and then directing the compiler to compile the necessary files. However, conventional C++ compilers that effect file-based batch processing must read thedeclarations in order, and often read through thousands of lines of unchanged code in a file, or in the header files that the file includes, before processing a changed declaration. (Any file that includes a modified header file must be recompiled, whether or not the modification affects any definition in that file.) Also, the programmer needs to tell "make" about file-level dependencies, and this dependency information must be maintained as the system being developed evolves. While there are tools to maintain the dependencies automatically, they are very slow and, consequently, are not consistently used, leading to errors in the dependency information, and ultimately, problems during recompilation.
Therefore, a system which provided for incremental compilation of changes to C+ + programs, effected at top-level declaration incrementality, would greatly reduce compilation time during program development and maintenance.
Also, entirely eliminating the need for forward declarations in C+ +
programming would provide a major improvement in programmer productivity by eliminating the work involved in preparing the header files initially and correcting errors identified during compilation. An enhancement to the compiler is necessary to dispense with the requirement for the ordering provided in the forward declarations.

Summary of the Invention It is an object of the present invention to provide a means for parsing a C+ +
program during compilation that dispenses with the requirement for forward declarations Ol- other ordering of the defining declarations, and dispenses with the 5requirement on the programmer to maintain file-level dependency information during program editing.
It is also an object of the present invention to provide a system that can compile and link small changes in C+ + programs rather than complete source files, that is, a system for incremental programming.
10A further object of the present invention is to provide a means for creating awllole-program representation that will persist through multiple parsing passes of the compller.
Accordingly, the present invention provides a method for compiling a C+ +
program in source code that consists of making an initial sweep of the source code, 15one declaration at a time, to obtain the declarations. Any declaration for which not all identifiers are Icnown in said initial sweep are set aside, and at least one subsequent sweep of the source code is made to obtain definitions for the declarations set aside from the initial sweep.
Preferably, the declarations are saved to a program representation following 20each sweep of the source code, and the program representation persists between compilations.
The invention also provides a method for parsing a program in C+ + source code without ordering or forward declarations, or without header files. In this method, the parsing is done directly of top level declarations.
25In a further embodiment, the present invention provides a method for compiling a C++ source code program in an enhanced compiler effecting lexical analysis to tokenize the source code program, parsing and semantic analysis to produce an intermediate representation of the source code program. The improvement of the invention consists of parsing the tolcenized source code program through multiple parsing passes, each pass accumulating information to parse declarations in the source code program from program definitions. Preferably, in the initial pass, only type declarations for the tokenized source code program are parsed, and in subsequent passes, information about type names, variables and functions in the source code program is accumulated.
The present invention is also directed to a compiler adpated to compile programs written in C++ source code. The compiler includes a parser adapted to extract definitions for declarations used in the programs directly from the source code by effecting multiple parsing sweeps of the source code. Preferably, the compiler also includes means for stoling objects from said parsing sweeps of the source code, such as as a program representation that persists between compilations.
Preferably, the means for storing objects includes means for storing a prioritized queue of token sequences from the source code program, each tolcen sequence containing at least one declaration for parsing.
The present invention is also directed to a mechanism for compiling programs written in C+ + source code without ordering, forward declarations or header files that consists of means for directly parsing top-level declarations from the C++ source code.
Finally, the present invention is directed to a computer program product having new, useful and nonobvious combination of computer readable program code means embodying thereon program code means for implementing the above-described method and compiler mechanism.

Brief Description of the Drawings Embodiments of the invention will now be described in detail in association with the accompanying drawings, in which:
Figure I is a schematic diagram showing conventional compilation in a simple one-pass compiler;
Figure 2 is a flow diagram showing the main loop of the multi-pass parsing technique of the present invention for a program compilation or recompilation;
Figure 3 is a flow diagram showing source file change detection, according to one aspect of the invention;
Figure 4 is a flow diagram showing source file updating during recompilation, according to another aspect of the invention;
Figure 5 is a data control flow representation of the steps illustrated in Figure 4;
Figure 6 is a flow diagram showing updating of a persistent object called the SourceRegion, according to a further aspect of the invention;
Figure 7 is a data control flow representation of the steps illustrated in Figure 6;
Figure 8 is a flow diagram showing processing of a persistent object called a Marlcer Node, according to another aspect of the invention; and Figure 9 is a flow diagram showing processing of a persistent object called an Implementation, according to another aspect of the invention.

Detailed Description of the Preferred Embodiments An overview of the operation of a conventional one-pass compiler is illustrated in Figure 1. The compiler can be divided into a front end 1 which analyses the stmcture and meaning of the source text. From the source code input as a character stream 3, the front end I produces an intermediate representation 5 of the program that is passed to the back end 2. The back end 2 of the compiler generates the equivalent program in the target language (usually modules in object code - called object modules - capable of being combined by a linker or linlcing loader to form a machine executable program), and may also provide some reorganization of the code for optimal runtime performance.
The front end 1 may be further subdivided into 3 operations or phases; lexical analysis, syntatic analysis and semantic analysis. The lexical analyzer or scanner 6 carries out a simple structural analysis, grouping the individual symbols of the source program text into their logical entities as tokens, and passing a stream of tokens 4 to the next phase. The syntax analyzer or parser 7 analyses the overall structure of the whole program and groups the tolcens into the larger constructs (statements, loops and routines) that make up the whole program. Once the structure of the program has been determined, the semantic analyzer 8 checlcs that the components of the program fit together meaningfully (i.e., determines which variables are to hold floating points and which are to hold integers, checlcs for definitions of array size, etc.).
Conventional C+ + compilers require forward declarations and order to support one-pass parsing. Parsing C+ + requires Icnowing whether or not an identifier is the name of a type, as in the following example:
void f() ~

217~71~

T~ p; // T is type = > Declaration of a pointer variable p.
// T is variable = > operator~(T, p) Forward declarations of type-names allow mutually referential types to be constructed in one-pass. For example, str~lct l; // l orward declaration struct S { T* t; }; // ok, T is a typename struct T { S~ s; ~;
Finally, forward declarations allow separate compilation with type checlcing.
FoIward declarations are placed in header files, which are then induded in both source files that use the declarations and those that provide definitions for the declarations.
For example, a header file foo.h with forward declarations typcdef float T;
cxtcrn T a_t; // a_t is a variable, its type is T
cxtern int foo(T); // foo is a function, it takes a T argument // and returns an int allows definitions to be written that use a_t and foo(). With this header file included7 the following code will compile:
#include "foo.h"
int main() {
rcturn foo(a_t);

The same header file is included again when compiling a_t and foo()'s definitions to ensure consistency between the forward declarations and the definitions.

Thus, for a conventional C+ + compiler that perforrns only a single parsing pass, the programmer is required to create, order and maintain header files that use forward declarations in the manner described above.
Through use of the enhanced compiler of the present invention, forward declarations and ordering can be eliminated in C+ + programming, as can header files and the development-environment problems they bring.
Forward declarations and order are needed for one-pass parsing and for separate compilation. By contrast, the present invention utilizes multi-pass parsing.
Information about the meaning of C+ + identifiers is extracted from the programmer's definitions, not from forward declarations for type names, variables, or functions or programmer-defined ordering of top-level declarations. This requires that all of the definitions must be available simultaneously during compilation, and may be parsed multiple times. In the example above, both the file containing main() and the file containing the definitions of foo() and a_t would have to be available at the same time and each of these declarations might be parsed more than once. When all of the definitions are not available in source form, for example, in class libraries supplied in compiled form, the forward dedarations supplied in the corresponding header files can be used instead.
According to the invention, the top-level declarations are defined to be top-level declaration statements (e.g., global f~mctions and global variables), member functions are defined outside of a class definition7 and static members that have variabledefinitions. Top-level declarations are unordered, but declarations within a top-level declaration must be ordered with respect to each other. Therefore, the followingdeclarations are invalid:
class C {

- 217~71l T x; // T used before declared typedcf int T;
};
int I = j, j; // j used before declared The source code is parsed one declaration at a time. Any declaration that fails to parse is set aside for a later pass. Each pass accumulates information about the type names, variables and functions in the program. This information includes dependencies, that is the uses in one declaration of names declared in other 10declarations. (Dependencies are essential for orderless processing of overloaded names.) If the program is correct, the multiple passes will uncover all of the information necessary for parsing; if the programmer has failed to define all of the type names, variables, or functions used in the program, the multiple passes will halt with an error similar to the errors from conventional compilers.
15The following simple example consists of two functions and a global variable:
int main() {
rcturn foo(a t);
}

Ta_t = 4;
int foo(T t) ~ return t.val(); }
class T
publ ic:
I (int 1) { _val = 1; }
int val() ~ rcturn _val; }
privatc:
int _val;
};

~17S711 Omitting some important details for the moment, in the first pass through this program, only the class T will parse. On the second pass, the types of the functions and variables will be parsed. On the third pass, the variable initializers and function bodies will be parsed. Thus by multiple passes, the program can be parsed without the programmer manually-typed forward declarations and without order.
In the preferred embodiment, each pass of the multi-pass parse is called a parsesweep. The processing of each C+ + statement containing top-level declarations is called a parse. The data structure that is produced or updated by a parse svveep is called a CodeStore. An execution of a complete parse (through multiple sweeps), whether it ends by successfully parsing all source code or by determining that the input is not legal C+ +, is called an incorporation, referring to the use of multi-pass parsing to incorporate changes in C++ source files into an existing (but possibly empty) CodeStore. Thus an incorporation consists of multiple parse sweeps, each sweep consisting of parses operating on top-level declarations.
The results of parsing the whole program are stored as a persistent whole-program representation, and only the source code that has changed since the lastincorporation or is affected by the changes is processed during subsequent recompilations. In the preferred embodiment a program database (called the Codestore), is used to hold the persistent program le~reselltation through the multiple parsing passes. However, it should be recognized that a persistent database is not an essential feature for operation of the multi-pass parsing compiler of the present invention. The requirements for multi-pass parsing are similar to the requirements for single-pass parsing: text input, internal data structures to fill, boolclceeping structures.
However, some of the data structures would be persistent (as described below) if the multiple sweeps of the parsing technique were used to update a persistent program database.
While persistent program representations or program databases have been integral to development systems for other languages, they are not generally used in C+ + because the benefits from conventional compilation have not been great enough to overcome the performance costs. Areas in which forms of limited program database associated with C++ compilers have been introduced include pre-compiled header files (discussed above) and template repositories. The problem addressed by the latter is that extensive use of C++ templates increases compilation time (and adds codebloat) unless there is some place to store template instantiations. The templaterepositories many commercial compilers use are intended to counter this problem.However, these solutions are not whole-program databases since, until the present invention, the ability to store more and more information in a program database has been circumscribed by the performance implications of large database size balanced against the benefits attained.
In the preferred embodiment of the present invention, a multi-pass parsing technique has been combined with a whole program representation, such as a program database. It has been found that a program database can implement a dependency analysis more fine-grained than files, reducing unnecessary compilation.
The objects used in the invention are either persistent, meaning that they survive across incorporations, or transient, meaning they are discarded at the end of an incorporation. The persistent objects are stored in the program database, in the preferred embodiment. The transient objects are created for the purpose of incorporation; any state they contain is not needed to begin a new cycle of mcorporation.
The CodeStore program representation contains the following types of persistent objects:

Source: A source object supplies source code to the compiler. Most source objects are SourceFile objects, that is, files which contain source code. Although forward declarations are not required and declarations need not be ordered, both fo~warddeclarations and order are allowed for compatibility with existing source files. Other kinds of source objects specify programmatic generation of declarations, e.g., source-code builders, wizards, etc.

ProjectControlSource: A project control source lists the names of files that contain source code and/or commands that are run to generate source code. A project control source also contains options used during incorporation, analogous to compiler options.
There is a single project control source for each CodeStore in the preferred embodiment.
SourceStore: A source store is a list of the Source objects that comprise the input to the process of the invention. The ProjectControlSource is on this list and is processed to populate the remainder of the list.

Macro: Macro objects represent C+ + preprocessor (#define) macros.

MacroStore: A macro store object is a dictionary that maps an identifier to a macro of that name.

SourceRegion: A source region represents a sequence of source code lexical tokens for a single top-level declaration.

Declaration: A declaration object is an internal representation of a C+ + declaration.
Each SourceRegion parses to one or more Declarations and each Declaration can bespecified in multiple SourceRegions.

DeclarationStore: A declaration store object represents a C+ + scope. It contains the Declaration objects for all names in the scope that have been successfully processed. These objects are dictionaries; a definition can be retrieved by giving a name to the DeclarationStore. These dictionaries respond to lookup requests using the C+ + rules for identifier lookup. Generally speal<ing, declaration stores and the declarations they contain correspond to the data structures one finds in the symbol table of a conventional compiler.

Implementation: An implementation object represents the result of parsing a function body or variable initializer. For example, an implementation object maycontain an abstract syntax tree.

DependencyNode: A dependency node object represents a node in a directed graph that relates object references to object definitions. All of the preceding objects are kinds of dependency nodes.

WorkQueue: A work queue represents the order in which Sources, SourceRegions, and Declarations are processed. The internal structure of the WorkQueues are described below.

217~711 MarlcerNode: A marlcer node is a special Icind of DependencyNode that is placed on a WorkQueue to change the order of queue processing.

The transient objects, such as preprocessors and parsers, operate on or create the persistent objects during incorporation. An Incorporator object contains all of the transient objects.
All of the persistent objects, except work queues, exhibit dependency node behavior. (In a C++ implementation of the present process, the classes for the persistent objects are derived from a dependency node abstract base class.) Eachdependency node includes a list of its antecedent dependency nodes and a list of its dependent dependency nodes. The antecedents of a dependency node D are all the objects that are used as inputs to the processing of D itself; the dependents of D are all the objects that have D as an antecedent, i.e., all those objects that refer to D.
Talcen together~ the dependency nodes and lists of antecedents and dependents form a dependency graph that is used to manage the effects of change.
There are two work queues of dependency nodes that cause processing to occur;
at each step, a dependency node is removed from a queue and processed and, this processing is called an update. The primary work queue is priority-based, with priorities assigned so that dependency nodes are generally processed before their dependents. The secondary work queue operates on a first-in, first-out basis (FIFO) and its entries are processed after processing all dependency nodes of certain ldnds (e.g., Sources, Source Regions, and Implementations) that are on the primary queue.
Every dependency node has associated with it one or more values, for example, its type or size. The values are typically computed by an update. When an updatedetermines that the value of the dependency node has changed, the corresponding dependent nodes, which use those values, are added to the primary work queue. Inthis way, changes to Sources cause reparsing of SourceRegions, changes to Declarations cause regenerating Implementations, and so on.
Each object on the primary work queue is assigned a priority; the highest-priority object is processed next. The initial priorities are assigned to approximate a topological ordering to the dependency graph nodes. Coarse relative priorities are assigned based on the Icind of object, ranlcing those lcinds of objects usually need to be processed first with highest priority. Thus the SourceStore has higllest priority, the sources are given high priority, followed by SourceRegions that l 0 lilcely declare types, followed then by SourceRegions that lilcely declare non-types, and followed then by Implementations. These coarse relative priorities are spaced numerically far apart to allow fine-grained priorities to be assigned to individual objects based on their dependency relations. These fine priorities interpolate the coarse priorities and, ideally, higher priority objects rarely depend on lower priority objects.
When an object is updated, the processing can succeed, fail, or fail with progress. Success means that the object's antecedents exist in the CodeStore and that the processor accepted the object as being correct; failure means either that anantecedent did not exist in the CodeStore, or that the object being processed was in error; failure with progress means that the processor failed, but that additional information was put in the CodeStore as a result of the processing. As an example, consider the possibilities when the parser processes a source region. The parse can succeed, and this means that all the names that appeared in the source region were known and that the declaration contained in the source region was correct.
Alternatively, one of the names used in the source region could be unlcnown or the - '~175711 declaration contained in the source region could be incorrect. This is failure; however, if new information was gleaned (e.g., the name of a class), the failure would be a failure with progress.
When an update on an object succeeds, the object is removed from the primary queue and its processing is finished (unless it is later placed on a queue). When an update fails (with or without progress), the object is removed from the primary queue and put on the secondary queue, which is ordered first-in, first-out. Nodes on the secondary queue are processed again, in the manner described below.
According to the invention, parsing continues until either all nodes have been updated successfully, or until the primary queue is empty and an attempt to update all nodes on the secondary queue yields failure without progress on all nodes. In the former case, the parse is complete; in the latter case, the source regions represented by the nodes remaining on the secondary queue are in error and error messages are generated.
In the first phase of the parsing, an attempt is made to parse all interfaces, which essentially comprise: all functions not including bodies contained within braces;
top-level variable declarations not including initializers; typedefs; and class, union, and struct declarations not including function bodies. Processing interfaces before processing other declarations gets the effect of forward declarations without burdening the programmer to write and maintain them. The key to efficiency is to do as much processing as possible using the Declaration objects already in the CodeStore for declarations that have not changed since the last incorporation, while using updated or new Declaration objects when the source code has changed.
Referring now to Figure 2, when an incorporation begins, the MacroStore contains Macros from Sources scanned in previous incorporations and the 2 1 7 ~ 7 1 l DeclarationStore contains Declaration objects that represent the result of the previous incorporation. As illustrated, the SourceStore is placed, with highest priority7 on the primary WorlcQueue (block 10). In addition, two MarlcerNodes are placed on the primary WorlcQueue (block 12), one for completion of type name processing and one for completion of non-type name processing. The highest priority dependency Nodeis removed from the primaly WorkQueue and the dependency processed (block 14, 16). If the Dependency Node is a SourceStore, its dependency will be processed follo-ving the steps in Figure 3; if a Source, Figure 4 steps will be followed; if a SourceRegion, Figure 6 steps will be followed; if a Marker Node, Figure 8 steps will be followed; and if an Implementation, Figure 9 steps will be followed. Incorporation ends when all Dependency Nodes have been successfully processed (block 20) or when a DependencyNode requests that incorporation end (block 18); whis happens for example when MarkerNodes fail to successfully process all nodes in the secondary(retry) queue.
Referring now to Figure 3, the top priority item on the primary WorkQueue is the SourceStore (block 21). When the SourceStore is removed from the queue (reference block 14 in Figure 2), its update function checlcs the time stamp on the corresponding project control file and, if necessary, updates the list of Sources contained in the SourceStore (block 22, Figure 3). Then, for each Source object, the time stamp on the corresponding file is checked (block 24) to determine if there has been a change since the last incorporation, and DependencyNode for each out-of-date Source is marked invalid and added to the primary WorkQueue (block 26).
Invalidating a Source causes all Macros defined in that Source to be hidden (block 28). This means that the MacroStore will respond to name loolcups on those Macros as if they do not exist. Once the SourceStore has checked all the Sources, processing conthlues following the main loop of Figure 2 (bloclcs 22, 29 of Figure 3).
In the next stage, each of the Source objects is decomposed into SourceRegions. This occurs whenever a Source object appears on the top of the primary WorkQueue. Figures 4 and 5 illustrate the preprocessing stage of incorporation. In the data control flow schematic of Figure 5, rectangles represent persistent objects in the CodeStore and ovals represent transient objects. Thin arrows represent pointers between objects; thick arrows represent data flow. Referring first to Figure 4 the Source on top of the primary WorkQueue is removed and its updatefunction is called (bloclcs 30, 32).
The Source update function uses the transient objects illustrated in Figure 5:
~ a C++ preprocessor 62 for extracting macro definitions and expanding macros defined in source code files that takes source text 68 and the MacroStore 70 and emits new macros 72 and a stream of preprocessed C+ + tolcen;
~ a MacroReconciler 64 that takes new macro definitions from the Preprocessor and updates the MacroStore 70; and ~ a DeclarationIsolator 66 that breaks the stream of tolcens from the PreProcessor 62 into SourceRegions.
First the Source's text stream is passed to the Preprocessor together with the MacroStore (block 32, Figure 4), and the Preprocessor tolcenizes the input (block 34).
Any Macros defined in the Source, recognized by #deflne commands, are passed to the MacroReconciler (block 36) for updating. If the defined Macro is identical to anexisting Macro, the hidden status is removed on the existing Macro; otherwise a new Macro is added to the MacroStore (blocks 38, 40~, and the MacroReconciler adds affected Sources to the primary WorlcQueue by enqueuing Source for re-processingthat may be altered by new or changed Macros (block 42). Next, the Preprocessor ~17~71 l looks up each token for possible macro-expansion (block 44). This is the usual expansion of macros as understood by those skilled in the art. Tokens output from the Preprocessor are then fed into the DeclarationIsolator (block 46) where SourceRegions are identified and those that are new or changed are placed on theWorkQueue by following the steps of declaration isolation then priority selection and queue placement (bloclcs 48 to 54).
Declaration isolation consists of partitioning the stream of tokens into individual declarations by matching braces, parentheses and square braclcets. Linlcage specifications and name space specifications are distributed over the declarations contained in them.
As a result of this isolation process, a list of SourceRegions for a Source is generated. All C+ + declarations will be wholly contained within one SourceRegion.
All of the tokens output from the preprocessor will be assigned to SourceRegions.
Some source code may fail to decompose into SourceRegions. For example, mismatched braces or a missing semicolon will cause the SourceRegion algorithm to hit an end of file while searching for the end of a declaration. In this case an error message can be emitted and processing of that Source will stop.
If this Source existed during the last incorporation, compare each newly extracted SourceRegion to the stored SourceRegions. If any of these comparisons yield exact matches, the new version is deleted. In this way unchanged C++
declarations need not be parsed or otherwise processed. As this comparison happens on preprocessed tokens, changes to comments and white-space do not cause recompilation.
The DeclarationIsolator also classifies each SourceRegion as probably a type-defining or probably a non-type-defining region. If the top-level tokens in the - 21~571 ~

SourceRegion contain one of the keywords class, struct, union typedef or enum, the SourceRegion is probably a type-defining region. Type-defining regions are givenhigher priority on the WorlcQueue than non-type-defining regions to reduce the number of parsing passes. Incorrect classification does not affect the correctness of the results of using the invented technique .
After classification, a SourceRegion and the stream of tokens that it representsare added to the CodeStore (block 52). The SourceRegion is then placed on the primary WorlcQueue (block 54). After all text in the Source has been processed, any SourceRegions for the Source remaining from previous incorporations, that is, those that did not match incoming SourceRegions, are hidden and processing continues in Figure 2 (blocks 56, 58 of Figure 4).
In summary7 the first stage of the process begins with Sources on the WorkQueue and ends with SourceRegions Oll the WorkQueue. In between the Source is pumped through the preprocessor, the MacroStore filled and used, and the DeclarationIsolator exercised to produce the SourceRegions enqueued for the nextstage in the algorithm. This first stage ends when there is a SourceRegion at the front of the primary queue (block 80, Figure 6).
The next stage of the process is designed to collect the "interfaces" declared in the SourceRegions on the Worl<Queues and is illustrated in Figures 6 and 7.
Interfaces are roughly like the C++ declarations in header files, but defined asfollows:
~ the type of variables: const integral variables are treated specially (see below);
~ the return type and argument list of functions, excluding default function arguments;
~ the Icind of type (class, struct7 union~ or enum); the interfaces contained in 217571 l a class, struct, or union;
~ enumerator initializers;
~ typedef definitions;
~ access declaration scopes;
~ interfaces contained in extem declarations and namespaces;
~ function template return type, argument list, and parameter declarations;
~ class template parameter declaration, lcind, and contained interfaces.
A constant integral type variable initialized with a constant expression and an enumerator with an initializer are treated as special cases since they can appear in constant expressions defining types.
In general terms, interfaces are extracted by parsing the tokens stored in SourceRegions. Parsing alone is insufficient llowever, since interfaces can be dependent upon constant expressions which can themselves depend upon the sizes of type definitions, and templates may have to be instantiated in order to parse I S non-templates.
The transient objects used in this stage of the algorithm are illustrated in Fig.
7. They are:
~ a Parser 73 that reads the tol<ens of a SourceRegion and analyzes them by looking up programmer-defined symbols in the DeclarationStore 75 to produce a Declaration 76 or an error message;
~ a DeclarationReconciler 74 that talces the new declaration 76 created by the Parser, loads it into the DeclarationStore 75, and places the SourceRegion 69 objects for any Declarations 76 whose parse may be changed by the presence of the new declaration on the WorkQueue 60;
~ a TypeAnalyzer 77 that takes a C+ + expression and gives the C+ + type 217~

that the expression evaluates to, i.e. a variable's type, a function's return type, or an expression's result type;
~ an ObjectModel 78 that takes a C++ type and returns the C++ size of val~le for that type; and ~ an ExpressionEvaluator 79 that takes an C+ + expression and returns the C++ value computation for that expression; only constant expressions will be evaluated.
Referring to Figure 6 each time the Incorporator takes a SourceRegion from the top of the WorkQueue and calls its update function (block 80), the SourceRegion's TokenStream is passed to the Parser (block 82). The parser scans for new declaration names (block 86), using the existing CodeStore to lookup names used in forming the C++ declarations. When a new declaration is recognized, the parser calls the DeclarationReconciler. The DeclarationReconciler compares the Declaration name with the DeclarationStore (block 88), and adds a new Declaration or changes an existing one in the DeclarationStore (block 90). When control returns to the Parser, newly added declarations have been recorded and are available for subsequent loolcup (block 92). Once all of the tolcens have been processed, the main loop steps continue processing (blocks 84, 94 of Figure 6).
The parsing of some declarations may result in more than one entry in the DeclarationStore. These cases include compound declarations, anonyrnous unions, and enumerations. For examples, // Compound declaration: 1 patse, 2 dcclarations entered.
int i, j;
// l~nonymous union: 1 parse, 3 declarations union ~ int u; float v; ~;
// cnumeration, I parse, 3 declarations.

~175711 cn~lm Polygon { triangle=3, rectangle=4 ~;
The latter two cases inject declarations from within matching braces to an enclosing scope.
In the DeclarationReconciler, any other Declarations used by the Parser in parsing the SourceRegion of this Declaration are recorded as "antecedent" declarations (block 92). Briefly, each SourceRegion has a list of pointers to the Declarations used to parse it (antecedents) and each Declaration has a list of pointers to SourceRegions it is referenced in (dependents). These pointers are used in overload processing as described below.
For function definitions, the DeclarationReconciler creates a new entry on the WorlcQueue for the f mction body; for variable definitions, the DeclarationReconciler creates a similar entry for the variable initializer. These entries are placed on the WorkQueue at a priority below any SourceRegion entry so that they will be considered during Implementation parsing. The successful SourceRegion is removedfronl the WorkQueue and the interface parse step ends.
An interface parse step failure can result either from erroneous source text provided by the programmer or Parser failure when loolcing up a name in the DeclarationStore. As it generally cannot be determined whether the programmer omitted a declaration or whether the declaration will appear in a later SourceRegion further down the WorkQueue, SourceRegions which fail to parse are placed on the secondary (retry) queue.
If the interface parse fails, a declaration may still have been entered in the DeclarationStore. If the Parser has determined that the declaration is a class, it will cause the DeclarationReconciler to enter a class declaration marked as "partially-defined" into the DeclarationStore as described below.

21~571:~

C~9-96-006 As an interface is parsed, the names of instances of class templates may be encountered. If the body of an instantiated template is needed in order to parse, and the template has not yet been fully instantiated, then the parse fails (as it would for any other name-loolcup failure). In addition, a DependencyNode for the template instantiation is added to the Worl<Queue. Just as the rules of the C+ + languagedictate, a template class name only creates the equivalent of a forward class declaration; neither the body of the class nor the bodies of member functions are instantiated until they are needed. In all cases, if template expansion fails, the parse of the dependent SourceRegion does not succeed.
At the end of each interface parse step, one SourceRegion has been removed from the WorlcQueue to be parsed and either one or more declarations have been added to the DeclarationStore, or the SourceRegion has been placed on a secondary FlFOQueue, or, for classes, enums, and declarations of template instances, both of these may have happened. If any declaration has entered the DeclarationStore, the Incorporator records that it has made progress.
The first pass of interface parsing continues until the MarlcerNode for completion of type name processing is encountered (block 96, Figure 8). When theMarlcerNode is dequeued the size of the secondary (retry) queue is tested (block 98).
If the retry queue is not empty, then it is repeatedly processed, by updating each of its DependencyNodes, until either the queue is emptied (by successful updates) or all DependencyNode updates fail (blocks 100, 102). Once the secondary (retry) queue is empty, processing returns to the main loop (bloclcs 98, 104).
The next DependencyNode is removed from the primary queue of the WorkQueue and its update function called (bloclcs 20, 12, l 4, Figure 2).
SourceRegions encountered during this stage are processed in the same way as ~ l 757~ ~

previously. The entire purpose of having these two stages is to reduce the number of failed parses from missing type names. By recursing over the type name SourceRegions first, all type names are extracted before any regions that do not contain type names are tried. When a second MarlcerNode, for completion of non-type names, rises to the top of the primary WorlcQueue, the retry queue is again processed until convergence.
The above description refers to special treatment for class declarations. Class declarations are treated as a special case because they "contain" member declarations, some of which might be types vital to the unambiguous parsing of other declarations.
The contained type names, the interfaces of contained member functions, and the interfaces of contained member variables are needed to compute sizeof that may appear in the definitions of other types. Failure to parse one or a few members cannot result in complete failure of the parse of a class or no progress will be made.
For example, the Parser can determine that X is a class in this code even if thenature of Y is not l<nown:
struct X {
Y~ y; // rarse fails if Y is not in the declaration store.
~;
Recording the information that X is a class is vital when other classes used in specifying members of X use the type name X in their declarations. For example, if the following source-code object appears after the one above, the compiler needs to Icnow that X is a type name:
struct Y { // seen later X~ x; // Ok, if X is a struct.
};

Thus class declarations must be entered into the DeclarationStore even when '~ 7571l the parse of their contained declarations fails. Furthermore, the class body must be parsed to look for nested types as well. Having done this, any successfully parsed member declarations can be saved, since if the class is completed, there is no need to consider it again.
The special treatment of class declarations consists of the following. If the Parser sees one of the C++ keywords class, struct, union, or enum followed by a previous undeclared identifier, it creates an class declaration named by the identifier and marlcs that class or enum as "partially-defined". The class declaration is passed to the DeclarationReconciler which enters it into the DeclarationStore, creating a DeclarationStore for the classes members. If remaining work in the class body parse succeeds and if the result is an class declaration, then the class is marlced as "defined".
Otherwise the Parser reports an error but the partially-defined class declaration remains in the DeclarationStore and the Incorporator is marlced as having made progress.
Although the partial-definition is described as a special case, this behavior is the typical one for parsing C+ + declarations. C+ + specifies that a type declaration is known as such as soon as its identifier is parsed. Thus code lilce struct Z ~
%~ 7,; // Z iS a type name ~;
is legal in a single-pass parser even though the use of Z comes before the closing brace of the class declaration.
Constant expressions can appear in array bounds and template arguments that define types, including types that appear in the interface for variables and functions.
They can also appear in initializers for const integral variables, enumerators, and ~17571 L

bit-field lengths, all of which can appear in constant expressions directly or through the sizeof operator. Consequently, constant expressions must be parsed and evaluated during the interface parse sweep in order to parse all interfaces.
Constant expressions consist of literals whose values are given directly and objects whose values can be deduced without run-time information: the value of enumerators (a constant integral object), the value of constant integer variables initialized with constant expressions, and the value of sizeof expressions. The values that must be deduced are treated in the following manner.
Enumerators values are precomputed when they are entered into the CodeStore. Enumerators must be initialized with constant expressions. Once the Parser recognizes that an enumeration is being processed, it sends the enumeration name to the DeclarationReconciler as in class processing. Then the Parser attempts to parse the contained enumerators. Initializers are parsed, type analyzed, and evaluated; if the result is not a constant integral value the parse step fails.
Integral variables declared const are precomputed as was done for enumerators.
They need not be initialized with constant expressions so a non-const value does not cause the parse step to fail.
The value of sizeof explessions are computed on demand. The operands of sizeof are parsed whenever they are encountered in the interface parse. The argument tosizcof can either be a type name or an expression. If it is a type name, it must resolve to a fully defined type; othelwise the parse fails. If it is an expression, the expression is type-analyzed~ and the size of the resulting type is calculated.
After interfaces have been successfully parsed, the WorlcQueue has one entry, called an "implementation", for each function body and variable initializer found when Declarations were added to the DeclarationStore. During the implementation parsing 2 1~7571~

that is, when the top priority item on the primary Worl<Queue is an Implementation (block I 10, Figure 9), these entries are removed one at a time (block 1 12) and parsed (block 114). C++ declarations encountered during this parse are used to create Declarations inserted into a DeclarationStore representing the function's local scope;
C+ + expressions encountered during this parse are passed to the TypeAnalyzer.
These steps cause additional dependency graph arcs to be added between the implementation and the Declarations needed to parse and type analyze it (block 1 16).
As in the parse of interfaces, class template instance name loolcup may cause class template expansion. In addition, the TypeAnalyzer may match function calls to function template names. If the corresponding template instance has not been used before, the body of the template instance is placed on the WorlcQueue below any other implementation. These implementations are processed when their WorkQueue entries are encountered during this implementation parse sweep. Once type analysis (block I 16) has completed successfully, the implementation is transformed to a simpler form suitable for generating machine code (block 118). At this stage of implementation processing, this simpler form can be optimized so that more efficient machine code is generated (block 120). Then implementation processing can continue through to produce the machine code, and link it into the program (bloclcs 122, 124), before returning to the main loop of the present invention (block 126).
Exceptions to the simple pattern are caused by overloading as discussed below.
Expansion of templates during implementation parsing may inject new Declarations into the namespaces used in interface or other implementation parses.
For example, consider inline friend functions in class templates template<class T~
class X

i~l75711 puhlic:
friend int operator==(const T& a, const T& b) { return a.equiv(b); }
};
This operator is added to the global namespace during instantiation of the template.
After injection, functions compiled without considering this interface can be invalid.
For example, struct A {
opcrator int();
~;
void fnc_a() {
A a I ;
A a2;
al = = a2; // converts A->int then calls = = for ints Up to this point there are no errors. Incorporating this function yields:
voi~l fnc_x(){
X<A~ I; // in jects operator= =(A&,A&) The injection will change the type analysis of fnc_a.
Function overloading can have a similar effect on types. For example, suppose this code has been parsed:
int foo(int 1) { return 1; ~
int barl I O*sizcof(foo( 1.0))];
The expression 1.0 is converted to an int and the return type of the sole function foo(), int, is used to in the array size expression. Then this SourceRegion is encountered:

~17 ~ 711 doublc foo(float i) ~ return f+O.5; ~
Now the type of bar must be reevaluated to correct the size of the array.
Both of these examples are handled by a general mechanism that also implements CodeStore update. As we have mentioned in several places, each time aDeclaration is referenced, a pointer is placed in the DependencyNode of the Declaration pointing back to the referring DependencyNode. This comprehensive list of uses is employed to correct Declarations in the presence of dedaration injection and overloading. For overloaded names, the correction is simple: users of declarations of the same name are removed from the CodeStore and their SourceRegions are enqueued for reprocessing. For injected and global operators, all uses of conversion operators must be enqueued on the types mentioned as arguments of the injected operator.
Since the WorkQueue entries are always processed in order of highest priority, interface parse cycles may interrupt the implementation parse sweep. Once we reach the last implementation entry in the WorlcQueue is reached, the incorporation is over.
If incorporation ends successfully, the DeclarationStore can be passed along forfurther processing, including inspection or subsequent compilations. If the incorporation fails, generally the programmer will be notified to the errors and their location. A programmer may need to inspect the DeclarationStore to correct the source code; traversal of the DeclarationStore in this case needs to be aware that some declarations may only be partially defined.

Claims (31)

The embodiments of the invention in which an exclusive property or privilege is claimed are defined as follows:
1. A method for compiling a C+ + program in source code, comprising:
making an initial sweep of the source code, one declaration at a time, to obtainthe declarations;
setting aside any declaration for which not all identifiers are known in said initial sweep; and making at least one subsequent sweep of the source code to obtain definitions for the declarations set aside from the initial sweep.
2. The method, according to claim 1, further comprising:
saving the declarations to a program representation following each sweep of the source code.
3. The method of claim 2 wherein the program representation persists between compilations.
4. The method of claim 3 wherein the program representation is saved to a program database.
5. The method of claim 2 wherein the step of saving the declarations to a program representation comprises updating an existing representation with new or changeddefinitions.
6. A method for parsing a program in C++ source code without ordering or forward declarations, wherein said parsing is done directly of top level declarations.
7. A method for parsing a program in C++ source code without header files, wherein said parsing is done directly of top level declarations.
8. A method for compiling a C+ + source code program in an enhanced compiler effecting lexical analysis to tokenize the source code program, parsing and semantic analysis to produce an intermediate representation of the source code program, the improvement comprising:
parsing the tokenized source code program through multiple parsing passes, each pass accumulating information to parse declarations in the source code program from program definitions.
9. The method, according to claim 8, wherein the multiple passes comprise at least an initial pass and a subsequent pass, and wherein in the initial pass, only type declarations for the tokenized source code program are parsed.
10. The method, according to claim 9, wherein in the said subsequent pass, information about type names, variables and functions in the source code program is accumulated.
11. The method, according to claim 9, wherein said at least an initial pass and a subsequent pass comprise three passes, and wherein types of functions and variables from the source code program are parsed in a second pass and variable initializers and function bodies from the source code program are parsed in a third pass.
12. The method, according to claim 8, further comprising:
saving a program representation of parsed declarations after each parsing pass.
13. The method, according to claim 12, wherein the program representation persists between compilations.
14. The method, according to claim 13, wherein the program representation is saved to a program database.
15. The method, according to claim 12, further comprising:
updating said program representation after a parsing pass with new or changed information on any declarations obtained during said parsing pass.
16. A compiler adpated to compile programs written in C+ + source code comprising a parser adapted to extract definitions for declarations used in the programs directly from the source code by effecting multiple parsing sweeps of the source code.
17. The compiler, according to claim 16, further comprising means for storing objects from said parsing sweeps of the source code.
18. The compiler, according to claim 17, wherein the means for storing objects includes means for storing a representation of the source code parsed from a parsing sweep as a program representation.
19. The compiler, according to claim 17, wherein the means for storing objects comprises means for storing objects in a representation that persists between compilations.
20. The compiler, according to claim 19, wherein the means for storing objects comprises a program database.
21. The compiler according to claim 20 wherein the means for storing objects comprises means for storing a whole program representation of the source code parsed from a parsing sweep in the program database, and further comprises means for updating said whole program representation following subsequent parsing sweeps.
22. The compiler, according to claim 18, wherein the means for storing objects comprises means for storing a prioritized queue of token sequences from the source code program, each token sequence containing at least one declaration for parsing.
23. The compiler, according to claim 22, wherein the prioritized queue comprisesa primary queue and a secondary queue, the primary queue being adapted to store at least one token sequence initially obtained from the source code program prior to any parsing sweeps and the secondary queue adapted to store token sequences for declarations that failed to parse after any parsing sweep.
24. The compiler, according to claim 23, further comprising a preprocessor adapted to:
extract macro definitions;
expand macros defined in the source code program;
emit new macros to the program representation; and emit a stream of preprocessed C+ + tokens to the primary queue.
25. The compiler, according to claim 24, wherein the preprocessor extracts the macro definitions from the program representation.
26. A mechanism for compiling programs written in C++ source code without ordering or forward declarations comprising:
means for directly parsing top-level declarations from the C+ + source code.
27. A mechanism for compiling programs written in C++ source code without header files comprising:
means for directly parsing top level declarations from the C+ + source code.
28. A program storage device readable by a machine, tangibly embodying a program of instructions executable by the machine for compiling a C+ + program in source code, said method steps comprising:
making an initial sweep of the source code, one declaration at a time, to obtainthe declarations;
setting aside any declaration for which not all identifiers are known in said initial sweep; and making at least one subsequent sweep of the source code to obtain definitions for the declarations set aside from the initial sweep.
29. A program storage device readable by a machine, tangibly embodying a program of instructions executable by the machine for parsing a program in C+ +
source code without ordering or forward declarations, said method steps comprising directly parsing top level declarations.
30. A program storage device readable by a machine, tangibly embodying a program of instructions for parsing a program in C++ source code without header files, said method steps comprising directly parsing top level declarations.
31. A program storage device readable by a machine, tangibly embodying a program of instructions for an enhanced compiler for compiling a C+ + source code program by effecting lexical analysis to tokenize the source code program, parsing and semantic analysis to produce an intermediate representation of the source code program, the improved method steps comprising:
parsing the tokenized source code program through multiple parsing passes, each pass accumulating information to parse declarations in the source code program from program definitions.
CA002175711A 1996-05-01 1996-05-01 Incremental compilation of c++ programs Abandoned CA2175711A1 (en)

Priority Applications (5)

Application Number Priority Date Filing Date Title
CA002175711A CA2175711A1 (en) 1996-05-01 1996-05-01 Incremental compilation of c++ programs
TW085110652A TW308676B (en) 1996-05-01 1996-08-31 Incremental compilation of C++ programs
US08/838,205 US6182281B1 (en) 1996-05-01 1997-04-16 Incremental compilation of C++ programs
EP97302677A EP0805391A3 (en) 1996-05-01 1997-04-18 Incremental compilation of c++ programs
JP9105811A JPH1040114A (en) 1996-05-01 1997-04-23 Compile method for c++ program and compiler

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CA002175711A CA2175711A1 (en) 1996-05-01 1996-05-01 Incremental compilation of c++ programs

Publications (1)

Publication Number Publication Date
CA2175711A1 true CA2175711A1 (en) 1997-11-02

Family

ID=4158128

Family Applications (1)

Application Number Title Priority Date Filing Date
CA002175711A Abandoned CA2175711A1 (en) 1996-05-01 1996-05-01 Incremental compilation of c++ programs

Country Status (5)

Country Link
US (1) US6182281B1 (en)
EP (1) EP0805391A3 (en)
JP (1) JPH1040114A (en)
CA (1) CA2175711A1 (en)
TW (1) TW308676B (en)

Families Citing this family (44)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6523171B1 (en) * 1998-12-29 2003-02-18 International Business Machines Corporation Enhanced source code translator from procedural programming language (PPL) to an object oriented programming language (OOPL)
US6457172B1 (en) * 1999-04-13 2002-09-24 International Business Machines Corporation Compiler for supporting multiple runtime data representations
JP4118456B2 (en) * 1999-06-29 2008-07-16 株式会社東芝 Program language processing system, code optimization method, and machine-readable storage medium
US6353925B1 (en) * 1999-09-22 2002-03-05 Compaq Computer Corporation System and method for lexing and parsing program annotations
US6769115B1 (en) * 2000-05-01 2004-07-27 Emc Corporation Adaptive interface for a software development environment
FR2810423A1 (en) * 2000-06-16 2001-12-21 Suntech Method for developing computer projects, comprises functional analysis, computer creation of components to fulfill the functions,declaration of components on computer system and loading into computer
FR2812479B1 (en) * 2000-07-28 2003-01-31 Airsys Atm S A UNIVERSAL COMPUTER CODE GENERATOR
JP2002116917A (en) * 2000-10-05 2002-04-19 Fujitsu Ltd Compiler for compiling source program by object-oriented programming language
CA2328566A1 (en) * 2000-12-15 2002-06-15 Ibm Canada Limited - Ibm Canada Limitee System and method for providing language-specific extensions to the compare facility in an edit system
US20020129341A1 (en) * 2000-12-30 2002-09-12 Gregory Hibdon Selective expansion of high-level design language macros for automated design modification
US7152223B1 (en) 2001-06-04 2006-12-19 Microsoft Corporation Methods and systems for compiling and interpreting one or more associations between declarations and implementations in a language neutral fashion
US7146370B1 (en) * 2001-06-27 2006-12-05 Ncr Corp. Copying a portion of a database structure associated with a query
US7343407B2 (en) * 2001-10-15 2008-03-11 Ricoh Company, Ltd. Method and system of remote monitoring and support of devices, including handling Email messages having message types specified within the Email message
US7080352B2 (en) * 2002-01-30 2006-07-18 Dloo, Incorporated Method and system for creating programs using code having coupled syntactic and semantic relationships
US7308449B2 (en) * 2002-02-01 2007-12-11 John Fairweather System and method for managing collections of data on a network
US7020870B2 (en) * 2002-05-15 2006-03-28 Sun Microsystems, Inc. Dynamic size for language variables
US7240340B2 (en) * 2002-08-12 2007-07-03 Microsoft Corporation System and method for browse information parsing without compilation
US6904591B2 (en) * 2002-11-01 2005-06-07 Oz Development, Inc. Software development system for editable executables
US7219338B2 (en) * 2003-03-25 2007-05-15 Microsoft Corporation Multi-language compilation
US7441237B2 (en) * 2003-03-25 2008-10-21 Microsoft Corporation System and method for extending a compiler through a composer
US7194733B2 (en) * 2003-06-11 2007-03-20 Microsoft Corporation Transformation of an asynchronous transactional messaging language into a web services compatible language
US20050039189A1 (en) * 2003-08-14 2005-02-17 Todd Anderson Methods and apparatus to preemptively compile an application
CA2651461A1 (en) * 2003-12-17 2005-06-17 Ibm Canada Limited - Ibm Canada Limitee Relationship management for data modeling in an integrated development environment
US8136094B2 (en) * 2004-01-07 2012-03-13 International Business Machines Corporation Relationship management for data modeling in an integrated development environment
US7506320B2 (en) * 2004-09-09 2009-03-17 International Business Machines Corporation Generating sequence diagrams using call trees
US7784039B2 (en) * 2004-09-22 2010-08-24 Panasonic Corporation Compiler, compilation method, and compilation program
US7480897B2 (en) * 2005-03-10 2009-01-20 International Business Machines Corporation Method and system for managing development objects for computer program code
US20080127128A1 (en) * 2006-10-30 2008-05-29 Daniel Mateescu Type Validation for Applications Incorporating A Weakly-Typed Language
WO2008119572A1 (en) * 2007-03-29 2008-10-09 International Business Machines Corporation An apparatus and method for identifying contextual changes in source code
US8132152B2 (en) * 2007-06-08 2012-03-06 Apple Inc. Extending a scripting language to provide an object hierarchy
US8079025B2 (en) * 2007-06-08 2011-12-13 Apple Inc. Asynchronous load of source dependencies
US20090037386A1 (en) 2007-08-03 2009-02-05 Dietmar Theobald Computer file processing
US8099721B2 (en) * 2008-06-17 2012-01-17 Microsoft Corporation Parsing of declarations in all branches of preprocessor conditionals
US20100010801A1 (en) * 2008-07-11 2010-01-14 Microsoft Corporation Conflict resolution and error recovery strategies
US8171045B2 (en) * 2008-07-31 2012-05-01 Xsevo Systems, Inc. Record based code structure
US20100153912A1 (en) * 2008-12-15 2010-06-17 Apple Inc. Variable type knowledge based call specialization
US8539457B2 (en) * 2009-11-06 2013-09-17 Microsoft Corporation Partial on-demand lazy semantic analysis
US8677314B1 (en) * 2011-08-18 2014-03-18 Google Inc. Modifying a source code file to reduce dependencies included therein
US8843907B2 (en) 2011-08-25 2014-09-23 Myezapp Inc. Compiler with error handling
US8464234B2 (en) * 2011-10-24 2013-06-11 Google Inc. Pre-parsed headers for compilation
US9442707B2 (en) 2014-06-25 2016-09-13 Microsoft Technology Licensing, Llc Incremental whole program compilation of code
US10261889B2 (en) 2014-06-25 2019-04-16 Microsoft Technology Licensing, Llc Techniques for edit-and-continue and enhanced optimized debugging on optimized code
JP6481515B2 (en) 2015-05-29 2019-03-13 富士通株式会社 Information processing apparatus, compiling method, and compiler program
US11481201B2 (en) * 2020-03-05 2022-10-25 Intuit Inc. Integrated development environment for developing and compiling query language schemas for application program interfaces

Family Cites Families (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5105353A (en) * 1987-10-30 1992-04-14 International Business Machines Corporation Compressed LR parsing table and method of compressing LR parsing tables
US5170465A (en) * 1989-06-30 1992-12-08 Digital Equipment Corporation Incremental-scanning compiler for source-code development system
US5276880A (en) * 1989-12-15 1994-01-04 Siemens Corporate Research, Inc. Method for parsing and representing multi-versioned computer programs, for simultaneous and synchronous processing of the plural parses
US5204960A (en) * 1990-01-08 1993-04-20 Microsoft Corporation Incremental compiler
US5386570A (en) * 1993-05-24 1995-01-31 Hewlett-Packard Company Method for a two pass compiler with the saving parse states from first to second pass
US5560010A (en) * 1993-10-28 1996-09-24 Symantec Corporation Method for automatically generating object declarations
US5586328A (en) * 1994-10-21 1996-12-17 Microsoft Corporation Module dependency based incremental compiler and method

Also Published As

Publication number Publication date
US6182281B1 (en) 2001-01-30
JPH1040114A (en) 1998-02-13
EP0805391A3 (en) 2004-06-30
EP0805391A2 (en) 1997-11-05
TW308676B (en) 1997-06-21

Similar Documents

Publication Publication Date Title
US6182281B1 (en) Incremental compilation of C++ programs
US5680622A (en) System and methods for quickly detecting shareability of symbol and type information in header files
US7120898B2 (en) Intermediate representation for multiple exception handling models
US5737608A (en) Per-keystroke incremental lexing using a conventional batch lexer
Pollock et al. An incremental version of iterative data flow analysis
Somogyi et al. The execution algorithm of Mercury, an efficient purely declarative logic programming language
US5854932A (en) Compiler and method for avoiding unnecessary recompilation
Binkley Semantics guided regression test cost reduction
Odersky et al. The Scala language specification
US6067641A (en) Demand-based generation of symbolic information
US6353925B1 (en) System and method for lexing and parsing program annotations
US4989132A (en) Object-oriented, logic, and database programming tool with garbage collection
US20110239188A1 (en) Type interface system and method
US20080281580A1 (en) Dynamic parser
JPH05508494A (en) Integrated hierarchical representation of computer programs for software development
Parr et al. ANTLR reference manual
US20040154009A1 (en) Structuring program code
Parr et al. Pccts reference manual: version 1.00
US5864700A (en) Sequencing and error detection of template instantiations during compilation of C++ Programs
US20030233640A1 (en) Structuring program code
Brandis et al. The Oberon system family
Koskimies et al. The design of a language processor generator
JPH0792758B2 (en) Compiler and compilation method
Cervelle et al. Tatoo: an innovative parser generator
Baker A single-pass syntax-directed front end for Ada

Legal Events

Date Code Title Description
EEER Examination request
FZDE Discontinued
FZDE Discontinued

Effective date: 20080501