Inferno  0.2
cpptree.hpp
Go to the documentation of this file.
00001 #ifndef CPPTREE_HPP
00002 #define CPPTREE_HPP
00003 
00004 #include "clang/Basic/SourceLocation.h"
00005 #include "clang/Basic/TokenKinds.h"
00006 #include "llvm/ADT/APSInt.h"
00007 #include "llvm/ADT/APFloat.h"
00008 #include <string>
00009 #include <deque>
00010 #include "node/node.hpp"
00011 #include "clang/Parse/DeclSpec.h"
00012 #include "tree/type_db.hpp"
00013 
00014 /// CPPTree namespace contains node definitions that represent elements of the C++ language
00015 namespace CPPTree {
00016 
00017 //////////////////////////// Underlying Node Types ////////////////////////////
00018 
00019 /// Property is the base class for property nodes. 
00020 /** Each kind of property has an
00021  intermediate which can represent any value of the property. Enum-like and
00022  bool-like are implemented by choosing one of a choice of empty nodes derived
00023  from the intermediate. Other properties that cannot be represented this way
00024  have a Specific<Foo> node that actually contains the datatype (eg int, string
00025  etc). The intermediates should be the target of SharedPtrs and may be used in
00026  search patterns. The actual tree nodes for a program should always be the leaf
00027  node type. */
00028 struct Property : virtual Node { NODE_FUNCTIONS };
00029 
00030 /// Variable initialiser or function body
00031 /** This intermediate is used for an initial value for for a variable/object in
00032  which case it will be an Expression, or for the implementation of a Callable
00033  in which case it will be a Compound. For an uninitialised variable/object
00034  or a function declaration, it will be Uninitialised. */
00035 struct Initialiser : virtual Node { NODE_FUNCTIONS };
00036 
00037 /// an uninitialised Instance.
00038 struct Uninitialised : Initialiser { NODE_FUNCTIONS_FINAL }; 
00039 
00040 /// Represents a statement as found inside a function body. 
00041 /** Basically anything 
00042  that ends with a ; inside a function body, as well as labels (which we consider as 
00043  statements in their own right). */
00044 struct Statement : virtual Node { NODE_FUNCTIONS };
00045 
00046 /// An expression that computes a result value. 
00047 /** Can be used anywhere a statement can, per C syntax rules. */
00048 struct Expression : virtual Statement,
00049                     Initialiser { NODE_FUNCTIONS };
00050 
00051 /// Any abstract data type
00052 /** Any abstract data type including fundamentals, structs, function prototypes
00053  and user-named types. */
00054 struct Type : virtual Node { NODE_FUNCTIONS };
00055 
00056 /// A declaration specifies the creation of a UserType or an Instance. 
00057 /** Declaration can appear where statements can and also inside structs etc
00058  and at top level. */
00059 struct Declaration : virtual Node { NODE_FUNCTIONS };
00060 
00061 /// A scope is any space in a program where declarations may appear. Declarations
00062 /** in the collection are associated with the scope node but unordered. Scopes
00063  are used for name resolution during parse. */
00064 struct Scope : virtual Node
00065 {
00066     NODE_FUNCTIONS
00067     Collection<Declaration> members; /// The declarations in this scope
00068 };
00069 
00070 /// The top level of a program
00071 /** The top level of a program is considered a collection of declarations.
00072  main() would typically be a function instance somewhere in this collection. */
00073 struct Program : Scope { NODE_FUNCTIONS_FINAL };
00074 
00075 /// Indicates that the node cannot be combinationalised
00076 struct Uncombable : virtual Node { NODE_FUNCTIONS };
00077 
00078 //////////////////////////// Literals ///////////////////////////////
00079 
00080 /// A property that can also be used as a literal in a program
00081 /** There are also used as properties, so that we do not need to 
00082  duplicate literals and properties. */
00083 struct Literal : Expression,
00084                  Property
00085 {
00086     NODE_FUNCTIONS
00087 };
00088 
00089 /// Intermediate property node that represents a string of any value.
00090 struct String : Literal { NODE_FUNCTIONS };
00091 
00092 /// A string with a specific value 
00093 /** Value must be filled in. 
00094  TODO could be a problem with memory management here or nearby. See
00095  comment in test harness in search_replace.cpp. */
00096 struct SpecificString : String
00097 {
00098   NODE_FUNCTIONS_FINAL
00099     SpecificString() {} ///< default constructor, for making architypes 
00100     SpecificString( string s ) :
00101       value(s) /// Construct with a given STL string
00102     {
00103     }
00104   virtual bool IsLocalMatch( const Matcher *candidate ) const /// Overloaded comparison for search&replace
00105   {
00106     ASSERT( candidate );
00107       const SpecificString *c = dynamic_cast<const SpecificString *>(candidate);
00108       return c && c->value == value;
00109   } 
00110   virtual operator string() const /// Produce a string for debug
00111   {
00112     // Since this is a string literal, output it quoted
00113     return "\"" + value + "\"";
00114   }
00115 private:
00116     string value; ///< The string itself
00117 };
00118 
00119 /// Intermediate property node that represents a number of any value 
00120 /** (anything you
00121  can do +, - etc on). */
00122 struct Number : Literal { NODE_FUNCTIONS };
00123 
00124 #define INTEGER_DEFAULT_WIDTH 32
00125 
00126 /// Intermediate property node that represents an integer of any value and signedness. 
00127 struct Integer : Number { NODE_FUNCTIONS };
00128 
00129 /// Property node for a specific integer value. 
00130 /** We use LLVM's class for this, 
00131  so that we can deal with any size of number (so this can be used for
00132  large bit vectors). The LLVM object also stores the signedness. The
00133  value must always be filled in. */
00134 struct SpecificInteger : Integer, llvm::APSInt
00135 {
00136   NODE_FUNCTIONS_FINAL
00137     SpecificInteger() {} ///< default constructor, for making architypes 
00138     SpecificInteger( llvm::APSInt i ) : llvm::APSInt(i) {} ///< Construct with an LLVM-style integer
00139     SpecificInteger( int i ) : llvm::APSInt(INTEGER_DEFAULT_WIDTH) { *(llvm::APSInt *)this = i; } ///< Construct with an ordinary int
00140   virtual bool IsLocalMatch( const Matcher *candidate ) const /// Overloaded comparison for search&replace
00141   {
00142     ASSERT( candidate );
00143       const SpecificInteger *c = dynamic_cast<const SpecificInteger *>(candidate);
00144       return c && *(llvm::APSInt *)c == *(llvm::APSInt *)this;
00145   }
00146   virtual operator string() const /// Produce a string for debug
00147   {
00148         return string(toString(10)) + // decimal
00149                (isUnsigned() ? "U" : "") +
00150                (getBitWidth()>TypeDb::integral_bits[clang::DeclSpec::TSW_unspecified] ? "L" : "") +
00151                (getBitWidth()>TypeDb::integral_bits[clang::DeclSpec::TSW_long] ? "L" : "");
00152                // note, assuming longlong bigger than long, so second L appends first to get LL
00153   }
00154 };
00155 
00156 /// Intermediate property node that represents a floating point number of any value. 
00157 struct Float : Number { NODE_FUNCTIONS };
00158 
00159 /// Property node for a specific floating point value.
00160 /** We use LLVM's class for this, 
00161  so that we can deal with any representation convention. The value must 
00162  always be filled in. To determine the type, use llvm::getSemantics() */
00163 struct SpecificFloat : Float, llvm::APFloat
00164 {
00165   NODE_FUNCTIONS_FINAL
00166     SpecificFloat() : llvm::APFloat(0.0) {} ///< default constructor, for making architypes 
00167     SpecificFloat( llvm::APFloat v ) : llvm::APFloat(v) {}; ///< Construct with an LLVM-style float
00168   virtual bool IsLocalMatch( const Matcher *candidate ) const /// Overloaded comparison for search&replace
00169   {
00170     ASSERT( candidate );
00171       const SpecificFloat *c = dynamic_cast<const SpecificFloat *>(candidate);
00172       return c && bitwiseIsEqual( *c );
00173   }
00174   virtual operator string() const /// Produce a string for debug
00175   {
00176     char hs[256];
00177     // generate hex float since it can be exact
00178     convertToHexString( hs, 0, false, llvm::APFloat::rmTowardNegative); // note rounding mode ignored when hex_digits==0
00179     return string(hs) +
00180          (&getSemantics()==TypeDb::float_semantics ? "F" : "") +
00181          (&getSemantics()==TypeDb::long_double_semantics ? "L" : "");
00182   }
00183 };
00184 
00185 /// Intermediate property node that represents either boolean value.
00186 /** Note: Bool here is considered a noun, and in general Property/Literal
00187  intermediates are named using nouns. C.f. the Type node Boolean */
00188 struct Bool : Literal { NODE_FUNCTIONS };
00189 
00190 /// Property node for boolean value true 
00191 struct True : Bool
00192 {
00193   NODE_FUNCTIONS_FINAL
00194   virtual operator string() const { return "true"; } ///< Produce a string for debug
00195 };
00196 
00197 /// Property node for boolean value false 
00198 struct False : Bool
00199 {
00200   NODE_FUNCTIONS_FINAL
00201   virtual operator string() const { return "false"; } ///< Produce a string for debug
00202 };
00203 
00204 //////////////////////////// Declarations /////////////////////
00205 
00206 /// Property node for any identifier
00207 /** An Identifier is a name given to a user-defined entity within 
00208  the program (variable/object/function, user-defined type or
00209  label). In the inferno tree, these are fully scope resolved
00210  and are maintained as unique nodes so that the declaration
00211  and all usages all point to the same node, this preserving
00212 
00213  identity via topology. We store a string, but it isn't strictly 
00214  needed and there's no need to uniquify it (it's really just 
00215  a hint for users examining the output). */
00216 struct Identifier : virtual Property { NODE_FUNCTIONS };
00217 
00218 /// Property for a specific identifier, linked to by a particular Declaration
00219 /** This is for unquoted strings, as opposed to String. Strictly,
00220  Inferno doesn't need to keep this data, but it helps
00221  to make renders and graphs clearer. Inferno will uniquify
00222  the name when rendering code. */
00223 struct SpecificIdentifier : virtual Property
00224 { 
00225     NODE_FUNCTIONS
00226   SpecificIdentifier() {} ///< default constructor, for making architypes 
00227   SpecificIdentifier( string s ) : name(s) {} ///< construct with a given name
00228     virtual shared_ptr<Cloner> Duplicate( shared_ptr<Cloner> p ) /// Overloaded duplication function for search&replace
00229     {
00230       return p; // duplicating specific identifiers just gets the same id, since they are unique.
00231       // This means x.Duplicate() matches x, wheras x.Clone() does not
00232     }
00233   virtual bool IsLocalMatch( const Matcher *candidate ) const /// Overloaded comparison for search&replace
00234   {
00235     ASSERT( candidate );
00236     return candidate == this;
00237   }
00238   virtual string GetName() const /// This is relied upon to just return the identifier name for rendering
00239   {
00240     return name;
00241   }
00242 private:
00243   string name;
00244 };
00245 
00246 /// Identifier for any Instance (variable or object or function)
00247 struct InstanceIdentifier : Identifier,
00248                             Expression { NODE_FUNCTIONS };
00249                                
00250 /// Identifier for a specific Instance, linked to by a particular Declaration                           
00251 struct SpecificInstanceIdentifier : InstanceIdentifier,
00252                                     SpecificIdentifier
00253 {
00254   SpecificInstanceIdentifier() {} ///< Default constructor
00255   SpecificInstanceIdentifier( string s ) : SpecificIdentifier(s) {} ///< make identifier with the given name
00256   NODE_FUNCTIONS_FINAL
00257 };
00258                             
00259 
00260 /// Identifier for any user defined type.
00261 struct TypeIdentifier : Identifier,
00262                         Type { NODE_FUNCTIONS };
00263                            
00264 /// Identifier for a specific user defined type, linked to by a particular Declaration.
00265 struct SpecificTypeIdentifier : TypeIdentifier,
00266                                 SpecificIdentifier
00267 {
00268   SpecificTypeIdentifier() {} ///< Default constructor
00269   SpecificTypeIdentifier( string s ) : SpecificIdentifier(s) {} ///< make identifier with the given name
00270   NODE_FUNCTIONS_FINAL
00271 };
00272 
00273 // General note about identifiers: in a valid program tree, there should
00274 // be *one* Declaration node that points to the identifier and serves to 
00275 // declare it. There should be 0 or more "users" that point to the
00276 // identifier. 
00277 
00278 /// Property for a member function that may or may not be virtual.
00279 struct Virtuality : Property { NODE_FUNCTIONS };
00280 
00281 /// Property for a virtual member funciton
00282 struct Virtual : Virtuality
00283 {
00284   NODE_FUNCTIONS_FINAL
00285     // TODO pure when supported by clang
00286 };
00287 /// Property for a non-virtual member funciton
00288 struct NonVirtual : Virtuality { NODE_FUNCTIONS_FINAL };
00289 
00290 /// Property for any access spec
00291 /** Property for C++ access specifiers public, protected and private. AccessSpec
00292  represents any access spec, the subsequent empty nodes specify particular
00293  access specs. Inferno uses access specs for all Instance. Declaration
00294  in Record are as specified, Function parameters and external Declaration
00295  are Public, all others Private. It is anticipated that the access spec will
00296  control generated high-level interfaces. Note that we only specify access
00297  for physical things like instances. Abstract stuff like TypeDef are always
00298  considered Public. */
00299 struct AccessSpec : Property { NODE_FUNCTIONS };
00300 
00301 /// Property for public access
00302 struct Public : AccessSpec { NODE_FUNCTIONS_FINAL };
00303 
00304 /// Property for private access
00305 struct Private : AccessSpec { NODE_FUNCTIONS_FINAL };
00306 
00307 /// Property for protected access
00308 struct Protected : AccessSpec { NODE_FUNCTIONS_FINAL };
00309 
00310 /// Property that indicates whether some Instance is constant.
00311 struct Constancy : Property { NODE_FUNCTIONS };
00312 
00313 /// Property indicating the Instance is constant
00314 struct Const : Constancy { NODE_FUNCTIONS_FINAL };
00315 
00316 /// Property indicating the Instance is not constant
00317 struct NonConst : Constancy { NODE_FUNCTIONS_FINAL };
00318 // TODO add mutable when supported by clang
00319 
00320 /// Declaration of a variable, object or function
00321 /** Instance represents a variable/object or a function. In case of function, type is a
00322  type under Callable and initialiser is a Statement (or Uninitialised for a function
00323  declaration). For a variable/object, type is basically anything else, and if there is
00324  an initialiser, it is an Expression. We allow init here for various reasons including
00325  - it can be hard to know where to put stand-alone init for statics
00326  - C++ constructors tie init to declaration
00327  - Fits in with single-static-assignment style
00328  The instance node can go into a Declaration Collection or a Statement Sequence.
00329  The latter case is used where initialisaiton/construction demands ordering. It points
00330  to an InstanceIdentifier, and all usages of the instance actually point to the
00331  InstanceIdentifier. */
00332 struct Instance : Declaration,
00333                   Statement
00334 {
00335     NODE_FUNCTIONS
00336     TreePtr<InstanceIdentifier> identifier; ///< acts as a handle for the instance, and holds its name only as a hint
00337     TreePtr<Type> type; ///< the Type of the instance, can be data or Callable type
00338     TreePtr<Initialiser> initialiser; ///< init value for data, body for Callable type
00339 };
00340 
00341 /// A variable or function with one instance across the entire program. 
00342 /** This includes extern and
00343  static scope for globals, as well as static locals. If a Static variable is Const, then it may be
00344  regarded as a compile-time constant. A static constant function may be regarded as idempotent. */
00345 struct Static : Instance
00346 {
00347   NODE_FUNCTIONS_FINAL
00348     TreePtr<Constancy> constancy; ///< is the instance constant (ie compile time value)?
00349 };
00350 
00351 /// A non-static member Instance (function or variable)
00352 /** A variable or function with one instance for each object of the containing class, ie
00353  non-static members. Functions have a "this" pointer. Note that access and constancy
00354  are intended to control the generation of read/write lines for modules. This usage of
00355  Constancy differs from that in Static, so we do not try to introduce a common intermediate.
00356  Note that static members are Static, not Field */
00357 struct Field : Instance
00358 {
00359   NODE_FUNCTIONS_FINAL
00360   TreePtr<Virtuality> virt; ///< Is the field virtual?
00361     TreePtr<AccessSpec> access; ///< Is it accessible outside the current Scope?
00362     TreePtr<Constancy> constancy; ///< Is the field constant (ie only written by constructor)
00363 };
00364 
00365 /// Any variable local to a Compound-statement. Cannot be a function.
00366 struct LocalVariable : Instance
00367 {
00368   NODE_FUNCTIONS
00369 };
00370 
00371 /// A local variable with automatic allocation
00372 /** A variable with one instance for each *invocation* of a function, ie
00373     non-static locals. Safe across recursion. Note that static locals
00374     are Static, not Automatic. */
00375 struct Automatic : LocalVariable
00376 {
00377   NODE_FUNCTIONS_FINAL
00378 };
00379 
00380 /// A local temp variable not preserved across function calls
00381 /** A local variable with unspecified storage which may be used within a function but is not preserved
00382  across recursion or between calls (such a variable could safely be implemented as any of
00383  Static, Field or Automatic since it supports only those guarantees common to all). */
00384 struct Temporary : LocalVariable
00385 {
00386   NODE_FUNCTIONS_FINAL
00387 };
00388 
00389 /// Node for a base class within a class declaration, specifies another class from which to inherit
00390 struct Base : Declaration
00391 {
00392   NODE_FUNCTIONS_FINAL
00393     TreePtr<AccessSpec> access; ///< Can inherited members be accessed?
00394     TreePtr<TypeIdentifier> record; ///< what do we inherit? must refer to InheritanceRecord
00395 };              
00396 
00397 /// Identifier for a label that can be any label.
00398 /** LabelIdentifier is an Expression as well as an Identifier so that
00399     it may be assigned to variables and used in ?: expressions as 
00400     supported in the gcc variable-label extenstion. Inferno tree
00401     does not require any representation of && or * - Labels
00402     and expressions may be mixed directly. */
00403 struct LabelIdentifier : Identifier,
00404                          Expression { NODE_FUNCTIONS };
00405 
00406 /// Identifier for a specific label that has been declared somewhere.
00407 struct SpecificLabelIdentifier : LabelIdentifier,
00408                                  SpecificIdentifier
00409 {
00410   SpecificLabelIdentifier() {} ///< Default constructor
00411   SpecificLabelIdentifier( string s ) : SpecificIdentifier(s) {} ///< construct with initial name
00412   NODE_FUNCTIONS_FINAL
00413 };
00414 
00415 /// Declaration of a label for switch, goto etc.
00416 /** This node represents a label such as mylabel:
00417  It serves to declare the label; the identifier should be
00418  used for references. */
00419 struct Label : Declaration, //TODO commonize with Case and Default
00420                Statement,
00421                Uncombable
00422 {
00423   NODE_FUNCTIONS_FINAL
00424     TreePtr<LabelIdentifier> identifier; ///< a handle for the label to be referenced elewhere
00425 };
00426 
00427 //////////////////////////// Anonymous Types ////////////////////////////
00428 
00429 /// Anything that can be called
00430 /** Types under Callable refer to a function's interface as seen by 
00431  caller and as used in eg function pointers (which is simply Pointer to
00432  the function type). To actually have a function, with a body, you need
00433  an Instance with type filled in to something derived from Callable. */
00434 struct Callable : Type
00435 {
00436     NODE_FUNCTIONS
00437 };
00438 
00439 /// Anything that can be called and has parameters
00440 /** Parameters are generated as a sequence of automatic variable/object 
00441  declarations (ie Instances) inside the Scope we derive from. */
00442 struct CallableParams : Callable,
00443                         Scope // For the parameters
00444 {
00445     NODE_FUNCTIONS
00446 };
00447 
00448 /// Anything that can be called and has parameters and return value
00449 struct CallableParamsReturn : CallableParams
00450 {
00451     NODE_FUNCTIONS
00452     TreePtr<Type> return_type; ///< The return type
00453 };
00454 
00455 /// Subroutine like in Basic, no params or return.
00456 /** Note: Subroutine has *explicitly* no params or return, this may be relied upon
00457     in transformations that use Subroutine as a wildcard */
00458 struct Subroutine : Callable 
00459 {
00460     NODE_FUNCTIONS
00461 };
00462 
00463 /// A procedure like in pascal etc, params but no return value. 
00464 /** Note: Procedure has *explicitly* no return, this may be relied upon
00465     in transformations that use Subroutine as a wildcard */
00466 struct Procedure : CallableParams
00467 {
00468     NODE_FUNCTIONS
00469 };
00470 
00471 /// A function like in C, Pascal; params and a single return value of the specified type.
00472 struct Function : CallableParamsReturn
00473 {
00474   NODE_FUNCTIONS_FINAL
00475 };
00476 
00477 /// A C++ constructor. The init list is just zero or more calls to constructors in the body
00478 struct Constructor : Procedure { NODE_FUNCTIONS_FINAL };
00479 
00480 /// A C++ destructor
00481 struct Destructor : Subroutine { NODE_FUNCTIONS_FINAL };
00482 
00483 /// This is the type of an array that contains the specified number of elements of the specified type.
00484 struct Array : Type
00485 {
00486   NODE_FUNCTIONS_FINAL
00487     TreePtr<Type> element; ///< the element type
00488     TreePtr<Initialiser> size; ///< evaluates to the size or Uninitialised if not given eg []
00489 };
00490 
00491 /// Intermediate for indirect access to some type as specified
00492 struct Indirection : Type
00493 {
00494     NODE_FUNCTIONS
00495     TreePtr<Type> destination; ///< reaching an object of this type, indirectly
00496 };
00497 
00498 /// A C/C++ pointer
00499 struct Pointer : Indirection { NODE_FUNCTIONS_FINAL };
00500 
00501 /// A C++ reference
00502 struct Reference : Indirection { NODE_FUNCTIONS_FINAL };
00503 
00504 /// The pseudo-type void, disallowed in some circumstances as per C.
00505 struct Void : Type { NODE_FUNCTIONS_FINAL };
00506 
00507 /// Boolean type. 
00508 /** We support bool separately from 1-bit ints, at least for now.
00509  (note that (bool)2==true but (int:1)2==0)
00510  Note: Boolean here is considered an adjective, and in general Type
00511  nodes are named using adjectives. C.f. the Property/Literal intermediate Bool */
00512 struct Boolean : Type { NODE_FUNCTIONS_FINAL };
00513 
00514 /// Intermediate for any type that represents a number that you can eg add and subtract. 
00515 struct Numeric : Type { NODE_FUNCTIONS };
00516 
00517 /// Type represents an integral (singed or unsigned) type. 
00518 /** The total number of bits (including sign when signed, and 
00519  fractional if fixed-point) is given */
00520 struct Integral : Numeric
00521 {
00522     NODE_FUNCTIONS
00523     TreePtr<Integer> width;  ///< Number of bits, not bytes
00524 };
00525 
00526 /// Type of a signed integer number (2's complement).
00527 struct Signed : Integral { NODE_FUNCTIONS_FINAL };
00528 
00529 /// Type of an unsigned integer number.
00530 struct Unsigned : Integral { NODE_FUNCTIONS_FINAL };
00531 
00532 /// Property for the details of any floating point behaviour
00533 /** implying representation size and implementation. */
00534 struct FloatSemantics : Property { NODE_FUNCTIONS };
00535 
00536 /// Property for the details of a specific floating point behaviour
00537 struct SpecificFloatSemantics : FloatSemantics
00538 {
00539   NODE_FUNCTIONS_FINAL
00540     SpecificFloatSemantics() {} ///< default constructor, for making architypes 
00541     SpecificFloatSemantics( const llvm::fltSemantics *s ) : /// Construct from LLVM's class
00542       value(s)
00543     {
00544     }
00545   virtual bool IsLocalMatch( const Matcher *candidate ) const /// Overloaded comparison for search&replace
00546   {
00547     ASSERT( candidate );
00548       const SpecificFloatSemantics *c = dynamic_cast<const SpecificFloatSemantics *>(candidate);
00549       return c && c->value == value;
00550   }
00551   virtual operator string() const /// get a debug string
00552   {
00553     return SSPrintf("fltSemantics@%p", value );
00554   }
00555   operator const llvm::fltSemantics &() const /// convert back to LLVM's class
00556   {
00557     return *value;
00558   }
00559     const llvm::fltSemantics *value;
00560 };    
00561 
00562 /// Type of a floating point number.
00563 struct Floating : Numeric 
00564 { 
00565   NODE_FUNCTIONS_FINAL
00566     TreePtr<FloatSemantics> semantics; ///< These are the semantics of the representation
00567 }; 
00568 
00569 /// Type of a variable that can hold a label. Similar to the GCC extension
00570 /// for labels-in-variables but we use this type not void * (which is 
00571 /// inconvenient for stataic analysis). To declare a conventional label
00572 /// at a particular position, use Label.
00573 struct Labeley : Type
00574 {
00575   NODE_FUNCTIONS_FINAL   
00576 };
00577 
00578 //////////////////////////// User-defined Types ////////////////////////////
00579 
00580 /// Intermediate declaration of a user defined type of any kind (struct, typedef etc).
00581 /* The user type node is a declaration and goes into a declaration scope. It points
00582  to a TypeIdentifier, and all usages of the type actually point to the
00583  TypeIdentifier. */
00584 struct UserType : Declaration 
00585 { 
00586     NODE_FUNCTIONS
00587     TreePtr<TypeIdentifier> identifier; ///< The handle to the type that has been declared
00588 };
00589 
00590 /// Represents a typedef. 
00591 /** Typedef is to the specified type. We do not expand these at parse, but try to retain
00592     them for as long as possible */
00593 struct Typedef : UserType
00594 {
00595   NODE_FUNCTIONS_FINAL
00596     TreePtr<Type> type; ///< emulate this type
00597 }; 
00598 
00599 /// Intermediate for declaration of a struct, class, union or enum. 
00600 /** The set of member Declaration (which will be Field
00601  or Static) is in the Scope. They can be variables/objects in all 
00602  cases and additionally Callable instances in Struct/Class. */
00603 struct Record : UserType,
00604                 Scope // Member declarations go in here
00605 {
00606     NODE_FUNCTIONS
00607 };
00608 
00609 /// A union, as per Record.
00610 struct Union : Record { NODE_FUNCTIONS_FINAL };
00611 
00612 /// An Enum, as per record. 
00613 /** We regard enumerations as static const variables, initialised as per 
00614  the given value. Values are always explicit. */
00615 struct Enum : Record { NODE_FUNCTIONS_FINAL };
00616 
00617 /// A record that can inherit from other records and be inherited from. 
00618 /** We add in a list of base class declarations. */
00619 struct InheritanceRecord : Record
00620 {
00621     NODE_FUNCTIONS
00622     Collection<Base> bases; ///< contains the InheritanceRecords from which we inherit
00623     // TODO just chuck them into Record::members? 
00624 };
00625 
00626 /// Struct as per InheritanceRecord
00627 struct Struct : InheritanceRecord { NODE_FUNCTIONS_FINAL };
00628 
00629 /// Class as per InheritanceRecord
00630 struct Class : InheritanceRecord { NODE_FUNCTIONS_FINAL };
00631 
00632 //////////////////////////// Expressions ////////////////////////////
00633 
00634 /// An operator
00635 //TODO maybe fix the number of operands for binop and unop categories.
00636 struct Operator : Expression
00637 {
00638   NODE_FUNCTIONS
00639 };
00640 
00641 /// An operator with operands whose order is defined
00642 struct NonCommutativeOperator : Operator
00643 {
00644   NODE_FUNCTIONS
00645   Sequence<Expression> operands; ///< the operands are here, order preserved
00646 };
00647 
00648 /// An operator with operands whose order does not matter
00649 struct CommutativeOperator : Operator
00650 {
00651   NODE_FUNCTIONS
00652   Collection<Expression> operands; ///< the operands are here, order not preserved
00653 };
00654 
00655 // Intermediate categories of operators. We categorise based on
00656 // topology, and commutative is considered topologically
00657 // distinct from non-commutative.
00658 
00659 /// An operator with a single operand
00660 struct Unop : NonCommutativeOperator { NODE_FUNCTIONS };
00661 
00662 /// An operator with two operands
00663 struct Binop : NonCommutativeOperator { NODE_FUNCTIONS };
00664 
00665 /// An operator with three operands
00666 struct Ternop : NonCommutativeOperator { NODE_FUNCTIONS };
00667 
00668 /// An operator with two interchangable operands
00669 struct CommutativeBinop : CommutativeOperator { NODE_FUNCTIONS };
00670 
00671 /// An operator with two operands, that writes its result back to the first operand
00672 struct AssignmentOperator : NonCommutativeOperator { NODE_FUNCTIONS };
00673 
00674 // Use an include file to generate nodes for all the actual operators based on
00675 // contents of operator_db.inc
00676 #define PREFIX(TOK, TEXT, NODE, BASE, CAT) struct NODE : BASE { NODE_FUNCTIONS_FINAL };
00677 #define POSTFIX(TOK, TEXT, NODE, BASE, CAT) struct NODE : BASE { NODE_FUNCTIONS_FINAL };
00678 #define INFIX(TOK, TEXT, NODE, BASE, CAT) struct NODE : BASE { NODE_FUNCTIONS_FINAL };
00679 #define OTHER(TOK, TEXT, NODE, BASE, CAT) struct NODE : BASE { NODE_FUNCTIONS_FINAL };
00680 #include "operator_db.inc"
00681 
00682 /// Property indicating whether a New/Delete is global 
00683 /** New/Delete is global if it has :: in
00684  front of it. This differentiates when placement args are given as follows:
00685  Global: must be one placement arg, it is address to construct at
00686  NonGlobal: all placement args go to a corresponding operator new which returns address to construct at
00687  TODO bring these in line with Call etc */
00688 struct Globality : Property { NODE_FUNCTIONS };
00689 
00690 /// Property indicating ::new/::delete was used
00691 struct Global : Globality { NODE_FUNCTIONS_FINAL }; 
00692 
00693 /// Property indicating just new/delete, no :: was used
00694 struct NonGlobal : Globality { NODE_FUNCTIONS_FINAL }; 
00695 
00696 /// Property indicating whether a delete should delete an array.
00697 /** Apologies for the tenuous grammar. */
00698 struct DeleteArrayness : Property { NODE_FUNCTIONS };
00699 
00700 /// Property indicating delete[] was used
00701 struct DeleteArray : DeleteArrayness { NODE_FUNCTIONS_FINAL }; 
00702 
00703 /// Property indicating delete, no []
00704 struct DeleteNonArray : DeleteArrayness { NODE_FUNCTIONS_FINAL }; 
00705 
00706 /// Node for the C++ new operator
00707 /** gives all the syntactical elements required for allocation and initialisation */
00708 struct New : Operator
00709 {
00710   NODE_FUNCTIONS_FINAL
00711     TreePtr<Type> type; ///< Type of object to be constructed
00712     Sequence<Expression> placement_arguments; ///< arguments for placement usage
00713     Sequence<Expression> constructor_arguments; ///< arguments to the constructor
00714     TreePtr<Globality> global; ///< whether placement is global
00715 };
00716 
00717 /// Node for C++ delete operator
00718 struct Delete : Operator // TODO Statement surely? (clang forces it to be an Expression)
00719 {
00720   NODE_FUNCTIONS_FINAL
00721     TreePtr<Expression> pointer; ///< pointer to object to delete
00722     TreePtr<DeleteArrayness> array; ///< whether array delete
00723     TreePtr<Globality> global; ///< whether global placement
00724 };
00725 
00726 /// Node for accessing an element in a record as in base.member
00727 /** Note that the parser breaks down a->b into (*a).b which may
00728  be detected using a search pattern if desired. */
00729 struct Lookup : Operator
00730 {
00731   NODE_FUNCTIONS_FINAL
00732     TreePtr<Expression> base; ///< the Record we look in
00733     TreePtr<InstanceIdentifier> member; ///< the member to find
00734 };
00735 
00736 /// Node for a c-style cast. 
00737 // TODO C++ casts are not in here yet and C casts will be harmonised into whatever scheme I use for that.
00738 struct Cast : Operator
00739 {
00740   NODE_FUNCTIONS_FINAL
00741     TreePtr<Expression> operand; ///< the expression to cast
00742     TreePtr<Type> type; ///< the desired new type
00743 };
00744 
00745 /// Associates an Expression with an InstanceIdentifier. 
00746 /** Basically a key-value pair of identifier and value. Use in Maps. */
00747 struct MapOperand : virtual Node
00748 {
00749   NODE_FUNCTIONS_FINAL
00750   TreePtr<InstanceIdentifier> identifier; ///< the handle for this particualar operand
00751   TreePtr<Expression> value; ///< the Expression for this operand
00752 };
00753 
00754 /// An operator with operands whose order is established by mapping
00755 /** Maps a multiplicity of Instances to Expressions via their InstanceIdentifiers.*/
00756 struct MapOperator : Operator
00757 {
00758   NODE_FUNCTIONS
00759   Collection<MapOperand> operands; ///< Operands whose relationship is established via identifiers
00760 };
00761 
00762 /// A function call to specified function passing in specified arguments
00763 /* Function is an expression to allow eg function pointer dereference. Normal
00764  calls have callee -> some InstanceIdentifier for a Callable Instance.
00765  Arguments passed via MapOperator - mapped to the parameters in the callee
00766  type (if it's a CallableParams). */
00767 struct Call : MapOperator, Uncombable
00768 {
00769   NODE_FUNCTIONS_FINAL
00770     TreePtr<Expression> callee; ///< evaluates to the Callable Instance we must call
00771 };
00772 
00773 /// Initialiser for a record 
00774 /** Uses a map to associate elements with corresponding record 
00775  members. We also give the record type explicitly since the map is
00776  not enough information. */
00777 struct MakeRecord : MapOperator
00778 {
00779   NODE_FUNCTIONS_FINAL
00780   TreePtr<TypeIdentifier> type; ///< handle of the type of the record we are making
00781 };
00782 
00783 /// Operator that operates on data types as parameters. 
00784 /** Where either is allowed we use the type one, since it's more concise. */
00785 struct TypeOperator : Operator
00786 {
00787     NODE_FUNCTIONS
00788     TreePtr<Type> operand; ///< This Type is an input operand 
00789 };
00790 
00791 /// sizeof() a type
00792 struct SizeOf : TypeOperator { NODE_FUNCTIONS_FINAL }; 
00793 
00794 /// alignof() a type
00795 struct AlignOf : TypeOperator { NODE_FUNCTIONS_FINAL };
00796 
00797 //////////////////////////// Statements ////////////////////////////
00798 
00799 /// A sequence of statements in a scope that shall execute in sequence
00800 /** Note that local declarations
00801  can go in the members of the Scope or in the statements (since Declaration
00802  derives from Statement). There is a sequence point between each statement. */
00803 struct SequentialScope : Scope,
00804                          virtual Statement
00805 {
00806     NODE_FUNCTIONS
00807     Sequence<Statement> statements; ///< Can contain local declarations and code
00808 };
00809 
00810 /// Declarations and Statements inside {} or begin/end. 
00811 struct Compound : SequentialScope,      ///< Local declarations go in here (preferably)
00812                   Initialiser ///< Can "initialise" a function (with the body) 
00813 {
00814     NODE_FUNCTIONS_FINAL
00815 };                   
00816 
00817 /// GCC extension for compound statements that return a value
00818 /** The returned value is that returned by the last statement if it
00819     is an expresison. Otherwise evaluates to void */
00820 struct CompoundExpression : Expression, ///< Evaluates to whatever the last statement evaluates to
00821                             SequentialScope       ///< Local declarations go in here (preferably)
00822 {
00823     NODE_FUNCTIONS_FINAL
00824 };                   
00825 
00826 /// The return statement of a function
00827 /** return_value is an Expression giving the return value or 
00828  Uninitialised if none is present. */
00829 struct Return : Statement
00830 {
00831   NODE_FUNCTIONS_FINAL
00832     TreePtr<Initialiser> return_value; ///< return value or Uninitialised
00833 };
00834 
00835 /// A goto statement
00836 /** inferno tree supports goto-a-variable because
00837  it is expected to be useful during sequential lowering (state-out).
00838  Therefore we do not directly require LabelIdentifier, but the Expression
00839  must evaluate to one. No * or && needed. */
00840 struct Goto : Statement, Uncombable
00841 {
00842   NODE_FUNCTIONS_FINAL
00843     // Dest is an expression for goto-a-variable support.
00844     // Ordinary gotos will have Label here.
00845     TreePtr<Expression> destination; ///< where to go to, expresison allowed
00846 };
00847 
00848 /// If statement
00849 struct If : Statement
00850 {
00851   NODE_FUNCTIONS_FINAL
00852     TreePtr<Expression> condition; ///< condition to test
00853     TreePtr<Statement> body;       ///< executes when true
00854     TreePtr<Statement> else_body;  ///< executes when false, can be Nop if no else clause
00855 };
00856 
00857 /// Designate a statement that may be broken out of
00858 /** A "break" statement jumps out of the innermost one of these
00859     and then execution commences immediately after this statement.
00860     We must specify a body here; the break statement will be 
00861     within the body */
00862 struct Breakable : Statement 
00863 {
00864     NODE_FUNCTIONS
00865     TreePtr<Statement> body; ///< a break in here jumps to the end of here
00866 };
00867 
00868 /// Any loop.
00869 /** A "continue" statement jumps out of the innermost one of 
00870     these and goes to the bottom of the body. So this is effectively
00871     "Continuable". Our body is inherited from Breakable. */
00872 struct Loop : Breakable { NODE_FUNCTIONS };
00873 
00874 /// While loop
00875 struct While : Loop, Uncombable
00876 {
00877   NODE_FUNCTIONS_FINAL
00878     TreePtr<Expression> condition; ///< Tested before each iteration; false terminates immediately
00879 };
00880 
00881 /// Do loop (first iteration always runs)
00882 struct Do : Loop, Uncombable // a do..while() construct 
00883 {
00884   NODE_FUNCTIONS_FINAL
00885     TreePtr<Expression> condition; ///< Tested after each iteration; false terminates immediately
00886 };
00887 
00888 /// C-style for loop. 
00889 struct For : Loop
00890 {
00891   NODE_FUNCTIONS_FINAL
00892     TreePtr<Statement> initialisation; // Initialiser; use Nop if absent
00893     TreePtr<Expression> condition;     // Condition; use True if absent
00894     TreePtr<Statement> increment;      // Increment; use Nop if absent
00895 };
00896 
00897 /// Switch statement. 
00898 /** Body (From Breakable) is just a statement scope - case labels
00899  and breaks are dropped into the sequence at the corresponding 
00900  positions. This caters for fall-throughs etc. Really just a 
00901  Compound with a goto-a-variable at the top and some mapping. */
00902 struct Switch : Breakable
00903 {
00904   NODE_FUNCTIONS_FINAL
00905     TreePtr<Expression> condition; ///< Evaluates to a value whose case we'll jump to
00906 };
00907 
00908 /// Intermediate for labels in a switch statement.
00909 struct SwitchTarget : Statement { NODE_FUNCTIONS };
00910 
00911 /// Case label, supporting range extension in case useful for optimisation
00912 struct RangeCase : SwitchTarget
00913 {
00914   NODE_FUNCTIONS_FINAL
00915     // support gcc extension of case x..y:
00916     TreePtr<Expression> value_lo; ///< start of range, inclusive
00917     TreePtr<Expression> value_hi; ///< end of range, inclusive
00918 }; 
00919 
00920 /// Case label
00921 struct Case : SwitchTarget
00922 {
00923   NODE_FUNCTIONS_FINAL
00924     TreePtr<Expression> value; ///< Switch jumps here when condition is this value
00925 };
00926 
00927 /// Default label in a switch statement
00928 struct Default : SwitchTarget { NODE_FUNCTIONS_FINAL };
00929 
00930 /// Continue (to innermost Loop)
00931 struct Continue : Statement, Uncombable { NODE_FUNCTIONS_FINAL };
00932 
00933 /// Break (from innermost Breakable)
00934 struct Break : Statement { NODE_FUNCTIONS_FINAL };
00935 
00936 /// Do nothing; these get optimised out where possible
00937 struct Nop : Statement { NODE_FUNCTIONS_FINAL };
00938   
00939 }; // end namespace  
00940    
00941 #endif
00942