summaryrefslogtreecommitdiff
path: root/TAO/TAO_IDL/docs/WRITING_A_BE
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/TAO_IDL/docs/WRITING_A_BE')
-rw-r--r--TAO/TAO_IDL/docs/WRITING_A_BE1350
1 files changed, 0 insertions, 1350 deletions
diff --git a/TAO/TAO_IDL/docs/WRITING_A_BE b/TAO/TAO_IDL/docs/WRITING_A_BE
deleted file mode 100644
index 5c3c069f7a1..00000000000
--- a/TAO/TAO_IDL/docs/WRITING_A_BE
+++ /dev/null
@@ -1,1350 +0,0 @@
-OMG INTERFACE DEFINITION LANGUAGE COMPILER FRONT END PROTOCOLS
-==============================================================
-
-INTRODUCTION
-------------
-
-Welcome to the publicly available source release of SunSoft's
-implementation of the compiler front end (CFE) for OMG Interface Definition
-Language!
-
-This document explains how to use the release to create a fully functional
-OMG Interface Definition Language to target language compiler for your
-selected target system configuration. The section OVERVIEW explains this
-document's structure.
-
-CONTEXT
--------
-
-The implementation has three parts:
-
-1. A main program driving the compilation process
-2. A parser and attendant utilities for converting the IDL input into
- an internal form
-3. One or more back ends which take as input the internal form representing
- the IDL input, and which produce output in a target language and target
- format
-
-The release contains components 1 and 2, and a demonstration implementation
-of component 3. To use this release, you
-
-- write a back end which takes the internal representation of the parsed input
- and translates it to the target language and format. You may replace or
- modify the demonstration back end provided.
-- link the back end with the provided main program and parser sources
- to produce a complete compiler.
-
-OVERVIEW
---------
-
-This document does not explain IDL nor does it introduce IDL features.
-For this information, refer to the OMG CORBA specification, available by
-anonymous FTP from omg.org.
-
-This document does not explain C++, except to demonstrate how it is
-used to construct the CFE. The ARM by Stroustrup and Ellis provides a
-thorough explanation of C++.
-
-This document consists of two independent parts. The first part
-s all CFE supported protocols and the required
-application programmer's interface entry points that a conformant
-BE must provide. The second part steps through the process of
-constructing a working BE.
-
-The first part describes:
-
-- The compilation process
-- The Abstract Syntax Tree (AST) internal representation of parsed IDL
- input
-- How access to member data fields is managed
-- How the AST is generated from the IDL input (Generator protocol)
-- How definition scopes are nested and how name lookup works
-- The narrowing mechanism
-- How definition scopes are managed and how nodes are added to scopes
-- How BEs get control during the AST construction process (Add protocol)
-- The inheritance scheme used by the AST and how it affects BEs
-- How errors are handled and reported
-- How the CFE is initialized
-- How the command line arguments are parsed
-- What global variables and functions are provided
-- What API is required to be supported by a BE in order to link
- with the CFE
-- What files must be included in each BE file
-
-The second part describes
-
-- The API to be supplied by each BE
-- How to subclass from the AST to add BE specific functionality
-- How to subclass from the Generator protocol to create BE specific
- extended AST nodes
-- How to write constructors for the derived BE classes
-- How to use the Add protocol to store BE specific information
-- How to maintain BE specific information which applies to the entire
- AST generated from the IDL input
-- How to use data members in your BE
-- How to build a complete compiler
-
-PART I. FEATURES OF THE CFE
--=========================-
-
-THE COMPILATION PROCESS
------------------------
-
-The OMG IDL compiler operates as follows:
-
-- Parses command line arguments. If an option is directed at a
- BE, an appropriate operation provided by the BE is invoked to process
- the option.
-- Performs global initialization.
-- Forks a copy of the compiler for each file specified as input.
-- An ANSI-compatible preprocessor preprocesses the IDL input.
-- Parses the file using the CFE parser, and constructs an AST describing the
- IDL input.
-- Prints the AST for verification, if requested.
-- Invokes the BE to process the AST and produce the output
- characteristic of that BE.
-
-ABSTRACT SYNTAX TREE
---------------------
-
-The AST (Abstract Syntax Tree) is the primary mechanism for communication
-between a BE and the CFE. It consists of a tree of instances of classes
-defined in the CFE or refinements of those classes as defined in a BE.
-The class hierarchy of the AST closely resembles the structure of the IDL
-syntax. Most AST classes have direct equivalents in IDL constructs.
-
-The UTL_Scope class defines common functionality for definition scope
-management and name lookup. This is explained in a following section.
-UTL_Scope is defined in include/utl_scope.hh and implemented in
-util/utl_scope.cc.
-
-The AST provides the following classes:
-
-AST_Decl Base of the AST class hierarchy. Each class in the AST
- inherits from AST_Decl. Defined in include/ast_decl.hh
- and implemented in ast/ast_decl.cc
-
-AST_Type Common base class for all classes which represent IDL
- type constructs. Defined in include/ast_type.hh and
- implemented in ast/ast_type.cc. Inherits from AST_Decl.
-
-AST_ConcreteType Common base class for all classes which represent IDL
- types other than interfaces. Defined in the file
- include/ast_concrete_type.hh and implemented in
- ast/ast_concrete_type.cc. Inherits from AST_Type.
-
-AST_PredefinedType Instances of this class represent all predefined types
- such as long, char and so forth. Defined in the file
- include/ast_predefined_type.hh and implemented in
- ast/ast_predefined_type.cc. Inherits from
- AST_ConcreteType.
-
-AST_Module Represents the IDL module construct. Defined in the
- file include/ast_module.hh and implemented in
- ast/ast_module.cc. Inherits from AST_Decl and
- UTL_Scope.
-
-AST_Root Represents the root of the abstract syntax tree being
- constructed. Is a subclass of AST_Module. Can be
- subclassed in BEs to store information associated with
- the entire AST. Defined in the file include/ast_root.hh
- and implemented in ast/ast_root.cc. Inherits from
- AST_Module.
-
-AST_Interface Represents the IDL interface construct. Defined in
- include/ast_interface.hh and implemented in the file
- ast/ast_interface.cc. Inherits from AST_Type and
- UTL_Scope.
-
-AST_InterfaceFwd Represents a forward declaration of an IDL interface.
- Defined in include/ast_interface_fwd.hh and implemented
- in ast/ast_interface_fwd.cc. Inherits from AST_Decl.
-
-AST_Attribute Represents an IDL attribute construct. Defined in
- include/ast_attribute.hh and implemented in the file
- ast/ast_attribute.cc. Inherits from AST_Decl.
-
-AST_Exception Represents an IDL exception construct. Defined in
- include/ast_exception.hh and implemented in the file
- ast/ast_exception.cc. Inherits from AST_Decl.
-
-AST_Structure Represents an IDL struct construct. Defined in the file
- include/ast_structure.hh and implemented in the file
- ast/ast_structure.cc. Inherits from AST_ConcreteType
- and UTL_Scope.
-
-AST_Field Represents a field in an IDL struct or exception
- construct. Defined in include/ast_field.hh and
- implemented in ast/ast_field.cc. Inherits from
- AST_Decl.
-
-AST_Operation Represents an IDL operation construct. Defined in the
- file include/ast_operation.hh and implemented in
- ast/ast_operation.cc. Inherits from AST_Decl and
- UTL_Scope.
-
-AST_Argument Represents an argument to an IDL operation construct.
- Defined in include/ast_argument.hh and implemented in
- ast/ast_argument.cc. Inherits from AST_Field.
-
-AST_Union Represents an IDL union construct. Defined in
- include/ast_union.hh and implemented in
- ast/ast_union.cc. Inherits from AST_ConcreteType and
- from UTL_Scope.
-
-AST_UnionBranch Represents an individual branch in an IDL union
- construct. Defined in include/ast_union_branch.hh and
- implemented in ast/ast_union_branch.cc. Inherits from
- AST_Field.
-
-AST_UnionLabel Represents the label of an individual branch in an IDL
- union construct. Defined in include/ast_union_label.hh
- and implemented in ast/ast_union_label.cc
-
-AST_Constant Represents an IDL constant construct. Defined in
- include/ast_constant.hh and implemented in the file
- ast/ast_constant.cc. Inherits from AST_Decl.
-
-AST_Enum Represents an IDL enum construct. Defined in the file
- include/ast_enum.hh and implemented in ast/ast_enum.cc.
- Inherits from AST_ConcreteType and UTL_Scope.
-
-AST_EnumVal Represents an enumerator in an IDL enum construct.
- Defined in include/ast_enum_val.hh and implemented in
- ast/ast_enum_val.cc. Inherits from AST_Constant.
-
-AST_Sequence Represents an IDL sequence construct. Defined in
- include/ast_sequence.hh and implemented in
- ast/ast_sequence.cc. Inherits from AST_Decl.
-
-AST_String Represents an IDL string construct. Defined in the file
- include/ast_string.hh and implemented in
- ast/ast_string.cc. Inherits from AST_Decl.
-
-AST_Array Represents an array modifier to the type of an IDL
- field or typedef declaration. Defined in the file
- include/ast_array.hh and implemented in
- ast/ast_array.cc. Inherits from AST_Decl.
-
-AST_Typedef Represents an IDL typedef construct. Defined in the file
- include/ast_typedef.hh and implemented in
- ast/ast_typedef.cc. Inherits from AST_Decl.
-
-AST_Expression Represents an IDL expression. Defined in the file
- include/ast_expression.hh and implemented in
- ast/ast_expression.cc.
-
-AST_Root A subclass of AST_Module, an instance of this class
- is used to represent the distinguished root node of
- the AST. Defined in include/ast_root.hh and implemented
- in ast/ast_root.cc. Inherits from AST_Module.
-
-
-USING INSTANCE DATA
--------------------
-
-The AST classes define member data fields in addition to defining
-operations on instances. These member data fields are all private, to allow
-only the instance in which they are stored direct access. Other objects
-(including other instances of the same class) can obtain access to the
-member data fields of an instance through accessor functions. These
-accessor functions allow retrieval of the data, and in some cases update
-functions are also provided to store new values.
-
-There are several reasons why this approach is taken. First, it hides the
-actual implementation of the member data fields from outside the class. For
-example, a Thermometer class would not expose whether its temperature
-reading is stored in Farenheit or Celsius units, and it could allow access
-through either unit method.
-
-Second, protecting access to member data in this manner restricts the
-ability to update it to the instance itself, save where update functions
-are explicitly provided. This makes for more reliable implementations,
-since the manipulation of the data is isolated in the class implementation
-itself.
-
-Third, wrapping a function call around access to member data allows such
-access and update operations to be protected in a multithreaded
-environment. While the CFE itself is not multithreaded and the access
-operations as currently defined do no special work to protect against
-mutliple conflicting access operations, this may be changed in a future
-version. Moving the CFE to a multithreaded environment without protecting
-access to member data in this manner would be extremely difficult.
-
-The protocol defined in the CFE is that member data fields are all private
-and have names which start with the prefix "pd_" (denoting Private Data).
-The access functions have names which are the same as the name of the field
-sans the prefix. For example, AST_Decl has a field pd_defined_in and an
-access function defined_in().
-
-The update functions have names starting with "set_" followed by the name
-of the corresponding access function. Thus, AST_Decl defines a function
-set_in_main_file(boolean) which sets the pd_in_main_file data member's
-value to the boolean provided.
-
-GENERATION OF THE AST
----------------------
-
-The CFE generates the abstract syntax tree after parsing IDL
-input. The nodes of the AST are defined by classes introduced in the
-previous section, or by subclasses thereof as defined by each BE. In
-writing the CFE, we were faced with the following problem: how to generate
-the AST containing nodes of the derived classes as defined in each BE
-without knowledge of the types and conventions of these BE classes.
-
-One alternative was to define a naming scheme which predetermines the names
-of each subclass a BE can define. The AST would then be generated by
-calling an appropriate constructor on the BE derived class. This scheme
-suffers from some shortcomings:
-
-- It breaks the modularity of the compiler and imports knowledge about
- types defined in a BE into the CFE, where this information does not belong.
-- It restricts a compiler to having only one BE loaded at a time because the
- names of these classes can be in use in only one BE at a time.
-- It requires a BE to provide derived classes for all AST classes, even for
- those classes where the BE adds no functionality.
-
-The mechanism we chose is different. We define the AST_Generator class
-which has an operation for each constructor defined on each AST class. The
-operation takes arguments appropriate to the constructor, invokes it and
-returns the created AST node, using the type known to the CFE. All such
-operations on the generator are declared virtual. The names of all
-operations start with "create_" and contain the name of the construct.
-Thus, an operation which invokes a constructor of an AST_Module is named
-create_module. AST_Generator is defined in include/ast_generator.hh and
-implemented in ast/ast_generator.cc.
-
-If a BE derives from any AST class, it must also derive from the
-AST_Generator class and redefine the relevant operations to invoke
-constructors of the BE provided class instead of the AST provided class.
-For example, if BE_Module is a subclass of AST_Module in a BE, the BE would
-also define BE_Generator and redefine create_module to call the constructor
-of BE_Module instead of that provided by AST_Module.
-
-During initialization, the CFE causes an instance of the BE derived
-generator to be created and saved. This is explained in the section on
-REQUIRED ENTRY POINTS SUPPLIED BY A BE. During parsing, actions in the Yacc
-grammar invoke operations on the saved instance to create new nodes for the
-AST as it is being built. These operations invoke constructors for BE
-derived classes or for AST provided classes if they were not overridden.
-
-DEFINITION SCOPES
------------------
-
-IDL is a nested scoped language. The scoping rules are defined by the CORBA
-spec and closely follow those of C++.
-
-Scope management is implemented in two classes provided in the utilities
-library, UTL_Scope and UTL_Stack. UTL_Scope manages associations between
-names and AST nodes, and UTL_Stack manages scope nesting and entry and exit
-from definition scopes as the parse is proceeding. UTL_Scope is defined in
-include/utl_scope.hh and implemented in util/utl_scope.cc. UTL_Stack is
-defined in include/utl_stack.hh and implemented in util/utl_stack.cc.
-
-During initialization, the CFE creates an instance of UTL_Stack and saves
-it. During parsing, as definition scopes are entered and exited, AST nodes
-are pushed onto, or popped from, the stack represented by the saved
-instances. Nodes on the stack are stored as instances of UTL_Scope. Section
-THE NARROWING MECHANISM explains how to obtain the real type of a node
-retrieved from the stack.
-
-All definition scopes are linked in a tree rooted in the distinguished AST
-root node. This linkage is implemented by UTL_Scope and AST_Decl. The
-linkage is a permanent record of the scope nesting while the stack is a
-dynamic record which at each instant represents the current state of the
-parse.
-
-The nesting information is used to do name lookup. IDL uses scoped names
-which are concatenations of definition scope names ending with individual
-construct names. For example, in
-
- interface a {
- struct b {
- long c;
- };
- const long k = 23;
- struct s {
- long ar[k];
- };
- };
-
-the name a::b::c represents the long field in the struct b inside the
-interface a.
-
-Lookup is performed by searching down the linkage chain for the first component
-of the name, then, when found, recursively resolving the remaining
-components in the scope defined by the first component. Lookup is relative
-to the scope of use; in the above example, k could also have been referred to
-as a::k within the struct s.
-
-Nodes are stored in a definition scope as instances of AST_Decl. Thus, name
-lookup returns instances of AST_Decl. The next section, THE NARROWING
-MECHANISM, explains how to obtain the real type of a node retrieved from a
-definition scope.
-
-THE NARROWING MECHANISM
------------------------
-
-Here we give only a cursory explanation of how narrowing works. We
-concentrate on defining the problem and showing how to use our narrowing
-mechanism. The narrowing mechanism is defined in include/idl_narrow.hh.
-
-As explained above, nodes are stored on the scope stack as instances of
-UTL_Scope, and inside definition scopes as instances of AST_Decl. Also,
-nodes are linked in a nesting tree as instances of AST_Decl. Given a node
-retrieved from the stack or a definition scope, one is faced with the task
-of obtaining its real class. C++ does not currently provide an implicit
-mechanism for narrowing to a derived class, so the CFE defines its own
-mechanism. This mechanism requires some work on your part as BE implementor
-and requires some explicit code to be written when it is to be used.
-
-The class AST_Decl defines an enum whose members encode specific AST node
-classes. AST_Decl provides an accessor function, node_type(), which
-retrieves a member of the enum representing the AST type of the node. Thus,
-if an instance of AST_Decl really is an instance of AST_Module, the
-node_type() accessor returns AST_Decl::NT_module.
-
-The class UTL_Scope also provides an accessor function, scope_node_type(),
-which returns a member of the enum encoding the actual type of the node.
-Thus, given an UTL_Scope instance which is really an instance of
-AST_Operation, scope_node_type() would return AST_Decl::NT_op.
-
-Perusing the header files for classes provided by the AST, you will note
-the use of some macros defined in include/idl_narrow.hh. These macros
-define the explicit narrowing mechanism:
-
-DEF_NARROW_METHODSx(<class name>,<parent_x>) for x equal to 0,1,2 or 3,
-defines a narrowing method for the specified class which has 0,1,2 or 3
-immediate base classes from which it inherits. For example, ast_module.hh
-which defines AST_Module contains the following line:
-
- DEF_NARROW_METHODS2(AST_Module, AST_Decl, UTL_Scope)
-
-This is because AST_Module inherits directly from AST_Decl and UTL_Scope.
-
-DEF_NARROW_FROM_DECL(<class name>) appears in class definitions for classes
-which are derived from AST_Decl and which can be stored in a definition
-scope. This macro declares a static operation narrow_from_decl(AST_Decl *)
-on the class in which it appears. The operation returns the provided
-instance as an instance of <class name> if it can be narrowed, or NULL.
-
-DEF_NARROW_FROM_SCOPE(<class name>) appears in class definitions of classes
-which are derived from UTL_Scope and which can be stored on the scope
-stack. This macro declares a static operation narrow_from_scope(UTL_Scope *)
-on the class in which it appears. The operation returns the provided
-instance as an instance of <class name> if it can be narrowed, or NULL.
-
-Now look in the files implementing these classes. You will note occurrences
-of the following macros:
-
-IMPL_NARROW_METHODSx(<class name>,<parent_x>) for x equal to 0,1,2 or 3,
-implements a narrowing method for the specified class which has 0,1,2 or 3
-immediate base classes from which it inherits. For example, ast_module.cc
-which implements AST_Module contains the following line:
-
- IMPL_NARROW_METHODS2(AST_Module, AST_Decl, UTL_Scope)
-
-IMPL_NARROW_FROM_DECL(<class name>) implements a method to narrow from an
-instance of AST_Decl to an instance of <class name> as defined above.
-
-IMPL_NARROW_FROM_SCOPE(<class name>) implements a method to narrow from an
-instance of UTL_Scope to an instance of <class name> as defined above.
-
-To put it all together: In the file ast_module.hh, you will find:
-
- // Narrowing
- DEF_NARROW_METHODS2(AST_Module, AST_Decl, UTL_Scope);
- DEF_NARROW_FROM_DECL(AST_Module);
- DEF_NARROW_FROM_SCOPE(AST_Module);
-
-In the file ast_module.cc, you will see:
-
-/*
- * Narrowing methods
- */
-IMPL_NARROW_METHODS2(AST_Module, AST_Decl, UTL_Scope)
-IMPL_NARROW_FROM_DECL(AST_Module)
-IMPL_NARROW_FROM_SCOPE(AST_Module)
-
-The CFE uses narrowing internally to obtain the correct type of nodes in
-the AST. The CFE contains many code fragments such as the following:
-
- AST_Decl *d = get_an_AST_Decl_from_somewhere();
- AST_Module *m;
- ...
- if (d->node_type() == AST_Decl::NT_module) {
- m = AST_Module::narrow(d);
- if (m == NULL) { // Narrow failed
- ...
- } else { // Success, do normal processing
- ...
- }
- }
- ...
-
-Similar code implements narrowing instances of UTL_Scope to their actual
-types.
-
-In your BE classes which derive from UTL_Scope you must include a line
-defining how to narrow from a scope, so:
-
- DEF_NARROW_FROM_SCOPE(<your BE class>)
-
-and similarly for your BE classes which derive from AST_Decl.
-
-The narrowing mechanism is defined only for narrowing from AST_Decl and
-UTL_Scope. If your BE class inherits directly from one or more classes
-which themselves are derived from AST_Decl and/or UTL_Scope, you must
-include a line
-
- DEF_NARROW_METHODSx(<your class name>,<parent 1>,<parent 2>)
-
-To make this concrete, here is what you'd write in a definition of BE_union
-which inherits from AST_Union:
-
- DEF_NARROW_METHODS1(BE_Union, AST_Union);
- DEF_NARROW_FROM_DECL(BE_Union);
- DEF_NARROW_FROM_SCOPE(BE_Union);
-
-and in the implementation file of BE_Union:
-
-/*
- * Narrowing methods:
- */
-IMPL_NARROW_METHODS1(BE_Union, AST_Union)
-IMPL_NARROW_FROM_DECL(BE_Union)
-IMPL_NARROW_FROM_SCOPE(BE_Union)
-
-Then, in BE code which expects to see an instance of your derived BE_Union
-class, you will write:
-
- AST_Decl *d = get_an_AST_Decl_from_somewhere();
- BE_Union *u;
- ...
- if (d->node_type() == AST_Decl::NT_union) {
- u = BE_Union::narrow_from_decl(d);
- if (u == NULL) { // Narrow failed
- ...
- } else { // Success, do normal processing
- ...
- }
- }
- ...
-
-
-SCOPE MANAGEMENT
-----------------
-
-Instances of classes which are derived from UTL_Scope implement definition
-scopes. A definition scope can contain any kind of AST node as long as it
-is derived from AST_Decl. However, specific kinds of definition scopes such
-as interfaces and unions can contain only a restricted subset of all AST
-node types.
-
-UTL_Scope provides operations to add instances of each AST provided class
-to a definition scope. The names of these operations are constructed by
-prepending the string "add_" to the name of the IDL construct. So, to add
-an interface to a definition scope, invoke the operation add_interface.
-The operations are all defined virtual and are intended to be overridden in
-classes derived from UTL_Scope.
-
-If the node was successfully added to the definition scope, the node is
-returned as the result. Otherwise the node is not added to the definition
-scope and NULL is returned.
-
-All add operation implementations in UTL_Scope return NULL. Thus,
-only the operations which implement legal additions to a specific kind of
-definition scope must be overridden in the implementation of that
-definition scope. For example, in AST_Module the add_interface operation is
-overridden to add the provided instance of AST_Interface to the scope and
-to return the provided instance if the addition was successful. Operations
-which were not overridden return NULL to indicate that the addition is
-illegal in this context. For example, in AST_Operation the definition of
-add_interface is not overridden since it is illegal to store an interface
-inside an operation definition scope.
-
-The add operations are invoked in the actions in the Yacc grammar. The
-following fragment is a representative example of code using the add
-operations:
-
- AST_Constant *d = construct_a_new_constant();
- ...
- if (current_scope->add_constant(d) == NULL) { // Failed
- ...
- } else { // Succeeded
- ...
- }
-
-BE INTERACTION DURING THE PARSING PROCESS
------------------------------------------
-
-The add operations can be overridden in BE derived classes to let the BE
-perform additional house-keeping work during the process of constructing
-the AST. For example, a BE could keep separate lists of interfaces as they
-are being added to a module.
-
-If you override an add operation in your BE, you must invoke the overridden
-operation in the superclass of your derived class to allow the CFE to
-perform its own house-keeping tasks. A good rule is to invoke the operation
-on the superclass before you do your own processing; then, if the
-superclass operation returns NULL, this indicates that the addition failed
-and your own code should immediately return NULL. An example explains this:
-
-AST_Interface *
-BE_Module::add_interface(AST_Interface *i)
-{
- if (AST_Module::add_interface(i) == NULL) // Failed, bail out!
- return NULL;
- ... // Do your own work here
- return i; // Return success indication
-}
-
-We strongly advise you to only define add operations that override add
-operations provided by the AST classes. Add operations which
-do not override equivalent operations in the AST in effect
-extend the semantics of the language accepted by the compiler. For
-example, the CFE does not have an add_interface operation on
-AST_Operation. If you were to define one in your BE_Operation class,
-the resulting compiler would allow an interface to be
-stored in an operation definition scope. The current CORBA specification
-does not allow this.
-
-AST INHERITANCE SCHEME
-----------------------
-
-The AST classes all use public virtual inheritance to construct the
-inheritance tree. This ensures that a class may appear several times in the
-inheritance tree through different paths and the derived class's instances
-will have only one copy of the inherited class's data.
-
-The use of public virtual inheritance has several important effects on how
-a BE is constructed. We explain those effects below.
-
-First, you must define a default constructor for your BE class, since
-your class may be used as a virtual base class of some other class. In this
-case the compiler may want to call a default constructor for your class. It
-is a good idea to have a default constructor anyway, even if you do not
-plan to subclass your BE class, since for most C++ compilers this causes
-the code to be smaller. Your default constructor should initialize all
-constant data members. Additionally, it may initialize any non-constant
-data member whose value must be set before the first time the instance is
-used.
-
-Second, the constructor of your BE derived class must explicitly call all
-constructors of virtual base classes which perform useful work. For
-example, if a class in the AST from which your BE class inherits has an
-initializer for a data member, you must call that constructor. This rule is
-discussed in detail in the C++ ARM. An example may help here.
-
-Suppose you define a class BE_attribute which inherits from AST_Attribute.
-Its constructor should be as follows:
-
- BE_Attribute::BE_Attribute(boolean ro,
- AST_Type *ft,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Attribute(ro, ft, n, p),
- AST_Field(ft, n, p),
- AST_Decl(AST_Decl::NT_attr, n, p)
- {
- }
-
-The calls to the constructors of AST_Attribute, AST_Field and AST_Decl are
-needed because these constructors do useful initializations on their
-classes.
-
-Note that there is some redundancy in the data passed to these
-constructors. We chose to preserve this redundancy since it should be
-possible to create BEs which subclass only some of the classes supplied by
-the AST. This means that the constructors on each class provided by the AST
-should take arguments which are sufficient to construct the instance if
-the AST class is the most derived one.
-
-The code supplied with this release contains a demonstration BE which
-subclasses all the AST provided classes. The constructors for each class
-provided by the BE are found in the file be/be_classes.cc.
-
-INITIALIZATION
---------------
-
-The following steps take place at initialization:
-
-- The global data instance is created, stored in idl_global and filled with
- default values (in driver/drv_init.cc).
-- The command line arguments are parsed (in driver/drv_args.cc).
-- For each IDL input file, a copy of the compiler process is forked (in
- driver/drv_fork.cc).
-- The IDL input is preprocessed (in driver/drv_preproc.cc).
-- FE initialization stage 1 is done: the scopes stack is created and stored
- in the global data variable idl_global->scopes() field (in fe/fe_init.cc).
-- BE_init is called to create the generator instance and the returned
- instance is stored in the global data variable idl_global->gen() field.
-- FE initialization stage 2 is done: the global scope is created, pushed on
- the scopes stack and populated with predefined types (in fe/fe_init.cc).
-
-GLOBAL STATE AND ENTRY POINTS
------------------------------
-
-The CFE has one global variable named idl_global, which stores an instance
-of a class IDL_GlobalData as explained below:
-
-The CFE defines a class IDL_GlobalData which defines the global
-information used in a specific run of the compiler. IDL_GlobalData is
-defined in include/idl_global.hh and implemented in the file
-util/utl_global.cc.
-
-Initialization creates an instance of this class and stores it in the value
-of the global variable idl_global. Thus, the individual pieces of
-information stored in the instance are accessible everywhere.
-
-ERROR HANDLING
---------------
-
-All error handling is defined by a class provided by the CFE, UTL_Error.
-This class is defined in include/utl_error.hh and implemented in the file
-util/utl_error.cc. The class provides several methods for reporting
-specific errors as well as generic error reporting methods taking zero to
-three arguments.
-
-The CFE instantiates the class and stores the instance as part of the
-global state, accessible as idl_global->err(). Thus, to cause an error
-report, you would write code similar to the following:
-
- if (error condition found)
- idl_global->err()->specific_error_message(arg1, ..);
-
-or
-
- if (error condition found)
- idl_global->err()->generic_error_message(flag, arg1, ..);
-
-The flag argument is one of the predefined error conditions found in the
-enum at the head of the UTL_Error class definition. The arguments to the
-specific error message routine are defined by the signature of that
-routine. The arguments to a generic error message routine are always
-instances of AST_Decl.
-
-The running count of errors is accessible as idl_global->err_count(). If
-the value returned by this operation is non-zero after the IDL input has
-been parsed, the BE is not invoked.
-
-HANDLING OF COMMAND LINE ARGUMENTS
-----------------------------------
-
-Defined command line arguments are specified in the document CLI, in this
-directory. The CFE calls the required BE API entry point BE_prep_arg to
-process arguments passed within a -Wb flag.
-
-REQUIRED ENTRY POINTS SUPPLIED BY A BE
---------------------------------------
-
-The following API entry points must be supplied by a BE in order to
-successfully link with the CFE:
-
-extern "C" AST_Generator *BE_init();
-
- Creates an instance of the generator object and returns it. Note
- that the global scope is not yet set up and the scopes stack is
- empty when this routine is called.
-
-extern "C" void BE_produce();
-
- Called by the compiler main program after the IDL input has been
- successfully parsed and processed. The job of this routine is to
- carry out the specific function of the BE. The AST is accessible as
- the value of idl_global->root().
-
-extern "C" void BE_prep_arg(char *, idl_bool);
-
- Called to process an argument passed in with a -Wb flag. The boolean
- will always be FALSE.
-
-extern "C" void BE_abort();
-
- Called when the CFE decides to abort the compilation. Can be used in
- a BE to clean up after itself, e.g. remove temporary files or
- directories it created while the parse was in progress.
-
-extern "C" void BE_version();
-
- Called when a -V argument is processed. This should produce a
- message for the user identifying the BE that is loaded and its
- version information.
-
-PART II. WRITING A BACK END
--=========================-
-
-REQUIRED API THAT EACH BE MUST SUPPORT
---------------------------------------
-
-Below are the API entry points that each BE must supply in order to use the
-CFE framework. This is a repeat of the BE API section:
-
-extern "C" AST_Generator *BE_init();
-
- Creates an instance of the generator object and returns it. Note
- that the scopes stack is still not set up at the time this routine
- is called.
-
-extern "C" void BE_produce();
-
- Called by the compiler main program after the IDL input has been
- successfully parsed and processed. The job of this routine is to
- carry out the specific function of the BE. The AST is accessible as
- the value of idl_global->root().
-
-extern "C" void BE_prep_arg(char *, boolean);
-
- Called to process an argument passed in with a -Wb flag. The boolean
- will always be FALSE.
-
-extern "C" void BE_abort();
-
- Called when the CFE decides to abort the compilation. Can be used in
- a BE to clean up after itself, e.g. remove temporary files or
- directories it created while the parse was in progress.
-
-extern "C" void BE_version();
-
- Called when a -V argument is processed. This should produce a
- message for the user identifying the BE that is loaded and its
- version information.
-
-WHAT FILES TO INCLUDE
----------------------
-
-To use the CFE, each implementation file of your BE must include the
-following two header files:
-
-#include <idl.hh>
-#include <idl_extern.hh>
-
-Following this, you can include any header files needed by your BE.
-
-HOW TO SUBCLASS THE AST
------------------------
-
-Your BE may subclass from any of the classes provided by the AST. Your
-class should use public virtual inheritance to ensure that only one copy of
-the class's data members is present in each instance. Read the section on
-HOW TO WRITE CONSTRUCTORS to learn about additional considerations that you
-must take into account when writing constructors for your BE classes.
-
-HOW TO SUBCLASS THE GENERATOR TO CREATE BE ENHANCED AST NODES
--------------------------------------------------------------
-
-Your BE subclasses from classes provided by the AST. To ensure that
-instances of these classes are constructed when the AST is built, you must
-also subclass AST_Generator and return an instance of your subclass from
-the call to BE_init.
-
-The AST_Generator class provides operations to create instances of all
-classes defined in the AST. For example, the operation to create an
-AST_Attribute node is as follows:
-
- AST_Attribute *
- AST_Generator::create_attribute(...)
- {
- return new AST_Attribute(...);
- }
-
-In your BE_Generator subclass of AST_Generator, you will override methods
-for creation of nodes of all AST classes which you have subclassed. Thus,
-if your BE has a class BE_Attribute which is a subclass of AST_Attribute,
-your BE_Generator class definition has to override the create_attribute
-method to ensure that instances of BE_Attribute are created.
-
-The definition of the overriden operations should call the constructor of
-the derived class and return the new node as an instance of the inherited
-class. Thus, the implementation of create_attribute is as follows:
-
- AST_Attribute *
- BE_Generator::create_attribute(...)
- {
- return new BE_Attribute(...);
- }
-
-The Yacc grammar actions call create_xxx operations on the generator
-instance stored in the global variable idl_global->gen() field. By storing
-an instance of your derived generator class BE_Generator you ensure that
-instances of the BE classes you defined will be created.
-
-HOW TO WRITE CONSTRUCTORS FOR BE CLASSES
-----------------------------------------
-
-As mentioned above, the AST uses public virtual inheritance to derive the
-AST class hierarchy. This has two important effects on how you write a BE,
-specifically how you write constructors for derived BE classes.
-
-First, you must define a default constructor for your BE class, since
-your class may be used as a virtual base class of some other class. In that
-case the compiler may want to call a default constructor for your class. It
-is a good idea to have a default constructor anyway, even if you do not
-plan to subclass your BE class, since for most C++ compilers this causes
-the code to be smaller. Your default constructor should initialize all
-constant data members. Additionally, it may initialize any non-constant
-data member whose value must be set before the first time the instance is
-used.
-
-Second, the constructor for your BE class must explicitly call all
-constructors of virtual base classes which do some useful work. For
-example, if a class in the AST from which your BE class inherits, directly
-or indirectly, has an initializer for a data member, your BE class's
-constructor must call the AST class's constructor. This is discussed
-extensively in the C++ ARM.
-
-Below is a list showing how to write constructors for subclasses of each
-class provided by the BE. For each AST class we show a definition of a
-constructor for a derived class which calls all neccessary constructors on
-AST classes:
-
-AST_Argument:
-
- BE_Argument::BE_Argument(AST_Argument::Direction d,
- AST_Type *ft,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Argument(d, ft, n, p),
- AST_Field(AST_Decl::NT_argument, ft, n, p),
- AST_Decl(AST_Decl::NT_argument, n, p)
- {
- }
-
-AST_Array:
-
- BE_Array::BE_Array(UTL_ScopedName *n,
- unsigned long nd,
- UTL_ExprList *ds)
- : AST_Array(n, nd, ds),
- AST_Decl(AST_Decl::NT_array, n, NULL)
-
- {
- }
-
-AST_Attribute:
-
- BE_Attribute::BE_Attribute(boolean ro,
- AST_Type *ft,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Attribute(ro, ft, n, p),
- AST_Field(AST_Decl::NT_attr, ft, n, p),
- AST_Decl(AST_Decl::NT_attr, n, p)
- {
- }
-
-AST_ConcreteType:
-
- BE_ConcreteType::BE_ConcreteType(AST_Decl::NodeType nt,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Decl(nt, n, p)
- {
- }
-
-AST_Constant:
-
- BE_Constant::BE_Constant(AST_Expression::ExprType t,
- AST_Expression *v,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Constant(t, v, n, p),
- AST_Decl(AST_Decl::NT_const, n, p)
- {
- }
-
-AST_Decl:
-
- BE_Decl::BE_Decl(AST_Decl::NodeType nt,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Decl(nt, n, p)
- {
- }
-
-AST_Enum:
-
- BE_Enum::BE_Enum(UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Enum(n, p),
- AST_Decl(AST_Decl::NT_enum, n, p),
- UTL_Scope(AST_Decl::NT_enum)
- {
- }
-
-AST_EnumVal:
-
- BE_EnumVal::BE_EnumVal(unsigned long v,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_EnumVal(v, n, p),
- AST_Constant(AST_Expression::EV_ulong,
- AST_Decl::NT_enum_val,
- new AST_Expression(v),
- n,
- p),
- AST_Decl(AST_Decl::NT_enum_val, n, p)
- {
- }
-
-AST_Exception:
-
- BE_Exception::BE_Exception(UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Decl(AST_Decl::NT_except, n, p),
- AST_Structure(AST_Decl::NT_except, n, p),
- UTL_Scope(AST_Decl::NT_except)
- {
- }
-
-AST_Field:
-
- BE_Field::BE_Field(AST_Type *ft,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Field(ft, n, p),
- AST_Decl(AST_Decl::NT_field, n, p)
- {
- }
-
-AST_Interface:
-
- BE_Interface::BE_Interface(UTL_ScopedName *n,
- AST_Interface **ih,
- long nih,
- UTL_StrList *p)
- : AST_Interface(n, ih, nih, p),
- AST_Decl(AST_Decl::NT_interface, n, p),
- UTL_Scope(AST_Decl::NT_interface)
- {
- }
-
-AST_InterfaceFwd:
-
- BE_InterfaceFwd::BE_InterfaceFwd(UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_InterfaceFwd(n, p),
- AST_Decl(AST_Decl::NT_interface_fwd, n, p)
- {
- }
-
-AST_Module:
-
- BE_Module::BE_Module(UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Decl(AST_Decl::NT_module, n, p),
- UTL_Scope(AST_Decl::NT_module)
- {
- }
-
-AST_Operation:
-
- BE_Operation::BE_Operation(AST_Type *rt,
- AST_Operation::Flags fl,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Operation(rt, fl, n, p),
- AST_Decl(AST_Decl::NT_op, n, p),
- UTL_Scope(AST_Decl::NT_op)
- {
- }
-
-AST_PredefinedType:
-
- BE_PredefinedType::BE_PredefinedType(
- AST_PredefinedType::PredefinedType *pt,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_PredefinedType(pt, n, p),
- AST_Decl(AST_Decl::NT_pre_defined, n, p)
- {
- }
-
-AST_Root:
-
- BE_Root::BE_Root(UTL_ScopedName *n, UTL_StrList *p)
- : AST_Module(n, p),
- AST_Decl(AST_Decl::NT_module, n, p),
- UTL_Scope(AST_Decl::NT_module)
- {
- }
-
-
-AST_Sequence:
-
- BE_Sequence::BE_Sequence(AST_Expression *ms, AST_Type *bt)
- : AST_Sequence(ms, bt),
- AST_Decl(AST_Decl::NT_sequence,
- new UTL_ScopedName(new String("sequence"), NULL),
- NULL)
- {
- }
-
-AST_String:
-
- BE_String::BE_String(AST_Expression *ms)
- : AST_String(ms),
- AST_Decl(AST_Decl::NT_string,
- new UTL_ScopedName(new String("string"), NULL),
- NULL)
- {
- }
-
-AST_Structure:
-
- BE_Structure::BE_Structure(UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Decl(AST_Decl::NT_struct, n, p),
- UTL_Scope(AST_Decl::NT_struct)
- {
- }
-
-AST_Type:
-
- BE_Type::BE_Type(AST_Decl::NodeType nt,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Decl(nt, n, p)
- {
- }
-
-AST_Typedef:
-
- BE_Typedef::BE_Typedef(AST_Type *bt,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Typedef(bt, n, p),
- AST_Decl(AST_Decl::NT_typedef, n, p)
- {
- }
-
-AST_Union:
-
- BE_Union::BE_Union(AST_ConcreteType *dt,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_Union(dt, n, p),
- AST_Structure(AST_Decl::NT_union, n, p),
- AST_Decl(AST_Decl::NT_union, n, p),
- UTL_Scope(AST_Decl::NT_union)
- {
- }
-
-AST_UnionBranch:
-
- BE_UnionBranch::BE_UnionBranch(AST_UnionLabel *fl,
- AST_Type *ft,
- UTL_ScopedName *n,
- UTL_StrList *p)
- : AST_UnionBranch(fl, ft, n, p),
- AST_Field(ft, n, p),
- AST_Decl(AST_Decl::NT_union_branch, n, p)
- {
- }
-
-AST_UnionLabel:
-
- BE_UnionLabel::BE_UnionLabel(AST_UnionLabel::UnionLabel lk,
- AST_Expression *lv)
- : AST_UnionLabel(lk, lv)
- {
- }
-
-HOW TO USE THE ADD PROTOCOL
----------------------------
-
-As explained the section SCOPE MANAGEMENT, the CFE manages scopes by
-calling type-specific functions to add new nodes to the scope to be
-augmented. These functions can be overridden in your BE classes to do work
-specific to your BE class. For example, in a BE_module class, you might
-override add_interface to do additional work.
-
-The protocol defined by the "add_" functions is that they return NULL to
-indicate failure. They return the node that was added (and which was given
-as an argument) if the operation succeeded. Your functions in your BE class
-should follow the same protocol.
-
-The "add_" functions defined in the BE must call the overridden function in
-the base class defind in the CFE in order for the CFE scope management
-mechanism to work. Otherwise, the CFE does not get an opportunity to
-augment its scopes with the new node to be added. It is good practice to
-call the overridden "add_" function as the first action in your BE
-function, because the success or failure of the CFE operation indicates
-whether your function should complete its task or abort early.
-
-Here is an example. Suppose you have defined a class BE_module which
-inherits from AST_Module. You may wish to override the add_interface
-function as follows:
-
- class BE_Module : public virtual AST_Module
- {
- ....
- /*
- * ADD protocol
- */
- virtual AST_Interface *add_interface(AST_Interface *);
- ...
- };
-
-The implementation of this function would look something like the following:
-
- AST_Interface *
- BE_Module::add_interface(AST_Interface *new_in)
- {
- /*
- * Check that the CFE operation succeeds. If it returns
- * NULL, stop any further work
- */
- if (AST_Module::add_interface(new_in) == NULL)
- return NULL;
- /*
- * OK, non-NULL, this means the BE can do its own work here
- */
- ...
- /*
- * Finally, don't forget to return the argument to indicate
- * success
- */
- return new_in;
- }
-
-HOW TO MAINTAIN BE SPECIFIC INFORMATION
----------------------------------------
-
-The CFE provides a special class AST_Root, a subclass of AST_Module. An
-instance of the AST_Root class is used as the distinguished root of the
-abstract syntax tree built during a parse.
-
-Your BE can subclass BE_Root from AST_Root and override the create_root
-operation in your BE_Generator class derived from AST_Generator. This will
-cause the CFE to create an instance of your BE_Root class as the root of
-the tree being constructed.
-
-You can use the instance of the BE_Root class as a convenient place to
-store information specific to an individual tree. For example, you could
-add operations on the BE_Root class to count how many nodes of each class
-are created.
-
-HOW TO USE MEMBER DATA
-----------------------
-
-As explained above, the AST classes provide access and update functions for
-manipulating data members. Your BE classes must use these functions when
-they require access to data members defined in the AST classes, since the
-data members themselves are private.
-
-It is good practice to follow the same scheme in your BE classes. Make all
-data members private. Prepend the names of all such fields with "pd_".
-Define access functions with names equal to the name of the field without the
-prefix. Define update functions according to need by prepending the name of
-the access function with the prefix "set_".
-
-Using these techniques will allow your BE to enjoy the same benefits that
-are imparted onto the CFE. Your BE will be easier to move to a
-multithreaded environment and its data members will be better protected and
-hidden.
-
-HOW TO BUILD A COMPLETE COMPILER
---------------------------------
-
-We now have all information needed to write a BE and to link it in with the
-CFE, to produce a complete IDL compiler.
-
-The following assumes that your BE will be stored in the "be" directory
-under the "release" directory. See the document ROADMAP for an explanation
-of the directory structure of the source release. If you decide to use a
-different directory to store your BE, you may have to modify the CPP_FLAGS in
-"idl_make_vars" in the top-level directory to allow your BE to find the
-include files it needs. You will also need to modify several targets in
-the Makefile in the top-level directory to correctly compile your BE into a
-library and to correctly link it in with the CFE to produce a complete
-compiler.
-
-You can get started quickly on writing your BE by modifying the sources
-found in the "demo_be" directory. The Makefile supports all the the targets
-that are needed to build a complete system and the maintenance target
-"clean" which assists in keeping the files and directories tidy. The files
-provided in the "demo_be" directory also provide all the API entry points
-that are mandated by this document.
-
-To build a complete compiler, invoke "make" or "make all" in the top-level
-directory. This will compile your BE and all the CFE sources, if this is
-the first invocation. On subsequent invocations this will recompile only
-the modified files. You will rarely if at all modify the CFE sources, so
-the overhead of compiling the CFE is incurred only the first time. To build
-just your BE, you can invoke "make all" or "make" in the "demo_be"
-directory. You can also, from the top-level directory, invoke "make
-demo_be/libbe.a".
-
-HOW TO OBTAIN ASSISTANCE
-------------------------
-
-First, read all the documents provided. If you have unanswered questions,
-mail them to
-
- idl-cfe@sun.com
-
-Sun does not promise to support the IDL CFE source release in any manner.
-However, we will attempt to answer questions and correct problems as time
-allows.
-
-NOTE:
-
-SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
-trademarks or registered trademarks of Sun Microsystems, Inc.
-
-COPYRIGHT NOTICE
-----------------
-
-Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United
-States of America. All Rights Reserved.
-
-This product is protected by copyright and distributed under the following
-license restricting its use.
-
-The Interface Definition Language Compiler Front End (CFE) is made
-available for your use provided that you include this license and copyright
-notice on all media and documentation and the software program in which
-this product is incorporated in whole or part. You may copy and extend
-functionality (but may not remove functionality) of the Interface
-Definition Language CFE without charge, but you are not authorized to
-license or distribute it to anyone else except as part of a product or
-program developed by you or with the express written consent of Sun
-Microsystems, Inc. ("Sun").
-
-The names of Sun Microsystems, Inc. and any of its subsidiaries or
-affiliates may not be used in advertising or publicity pertaining to
-distribution of Interface Definition Language CFE as permitted herein.
-
-This license is effective until terminated by Sun for failure to comply
-with this license. Upon termination, you shall destroy or return all code
-and documentation for the Interface Definition Language CFE.
-
-INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF
-ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS
-FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF
-DEALING, USAGE OR TRADE PRACTICE.
-
-INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT
-ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES
-TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT.
-
-SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
-RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
-INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF.
-
-IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR
-ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
-DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-Use, duplication, or disclosure by the government is subject to
-restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
-Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
-52.227-19.
-
-Sun, Sun Microsystems and the Sun logo are trademarks or registered
-trademarks of Sun Microsystems, Inc.
-
-SunSoft, Inc.
-2550 Garcia Avenue
-Mountain View, California 94043