LCOV - code coverage report
Current view: top level - home/yyan7/compiler/rexompiler/src/midend/astProcessing - AstAttributeMechanism.h (source / functions) Hit Total Coverage
Test: ROSE Lines: 5 45 11.1 %
Date: 2022-12-08 13:48:47 Functions: 0 27 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #ifndef ROSE_AstAttributeMechanism_H
       2             : #define ROSE_AstAttributeMechanism_H
       3             : 
       4             : #include "rosedll.h"
       5             : #include <Sawyer/Attribute.h>
       6             : #include <list>
       7             : #include <set>
       8             : 
       9             : class SgNode;
      10             : class SgNamedType;
      11             : class SgTemplateParameter;
      12             : class SgTemplateParameterList;
      13             : 
      14             : /** Base class for all IR node attribute values.
      15             :  *
      16             :  *  This is the base class for all attribute values stored in the Sage IR node using the @ref AstAttributeMechanism. IR node
      17             :  *  attributes are polymorphic based on this abstract class, and are always allocated on the heap. Once the attribute value is
      18             :  *  handed to an attribute container method the container owns the value and is reponsible for deleting it.  In the case of
      19             :  *  methods that only optionally insert a value, the value is deleted immediately if it's not inserted.  But see @ref
      20             :  *  getOwnershipPolicy for additional information.
      21             :  *
      22             :  *  The underlying @ref Sawyer::Attribute mechanism can store values of any type, including POD, 3rd party types, and
      23             :  *  pointers. On the other hand, the @ref AstAttributeMechanism interface described here stores only pointers to values
      24             :  *  allocated on the stack, owns those values, and supports operations that are useful specifically in IR nodes.
      25             :  *
      26             :  *  Subclasses should each implement a virtual @ref copy constructor, which should allocate a new copy of the value.  The
      27             :  *  implementation in this base class returns a null pointer, which means that the attribute is not copied into a new AST node
      28             :  *  when its AST node is copied.  If a subclass fails to implement the virtual copy constructor and a superclass has an
      29             :  *  implementation that return non-null, then copying the AST node will copy only the superclass part of the attribute and the
      30             :  *  new attribute will have the dynamic type of the superclass--probably not what you want!
      31             :  *
      32             :  *
      33             :  *
      34             :  *  For a more detailed description of using attributes in ROSE (and your own classes) see @ref attributes. */
      35           0 : class ROSE_DLL_API AstAttribute {
      36             : public:
      37             :     /** Who owns this attribute.
      38             :      *
      39             :      *  See @ref getOwnershipPolicy. */
      40             :     enum OwnershipPolicy {
      41             :         CONTAINER_OWNERSHIP,                            /**< Container owns attribute. New subclasses should use this! */
      42             :         NO_OWNERSHIP,                                   /**< Attributes are always leaked. */
      43             :         CUSTOM_OWNERSHIP,                               /**< Subclass defines ownership policy. */
      44             :         UNKNOWN_OWNERSHIP                               /**< Default for old subclasses. */
      45             :     };
      46             : 
      47             :     /** Who owns this attribute.
      48             :      *
      49             :      *  The original implementation of this class from the early 2000's did not have clear rules about who owned a
      50             :      *  heap-allocated attribute.  The documentation was silent on the issue, and the implementation seemed to imply that
      51             :      *  container ownership was intended but was then commented out at some point.  Any ownership policy should have the
      52             :      *  following properties:
      53             :      *
      54             :      *  @li Attributes allocated on the heap should not be leaked. For instance, if an AST is deleted, then the attributes that
      55             :      *      were referenced by the AST nodes should also be eventually deleted.
      56             :      *  @li The mechanism should not place undue burden on the user.  For instance, if a user copies and later deletes an AST
      57             :      *      to which some analysis has attached attributes, the user should not need to be concerned with deleting attributes
      58             :      *      stored in the copy.
      59             :      *  @li The mechanism should be able to support either deep or shallow attribute copies as appropriate for the
      60             :      *      attribute. The deep vs. shallow copying policy is implemented by the virtual @ref copy method, which must
      61             :      *      coordinate with the ownership policy to ensure no leaks.
      62             :      *
      63             :      *  We define four ownership policies, although from the standpoint of an attribute container there are really only two:
      64             :      *  the container either deletes attributes or doesn't delete attributes.  The four ownership policies are:
      65             :      *
      66             :      *  @li @c CONTAINER_OWHERSHIP: The simple approach to ownership, and the one that we recommend for all new attribute
      67             :      *      subclasses, is that the attribute container owns the attributes.  When the container is copied (e.g., as part of
      68             :      *      copying an AST node) then it invokes the @ref copy methods of its attributes, and when the container is deleted
      69             :      *      (e.g., as part of deleting an AST node) then it explicitly deletes its attributes. This policy is an "allocate and
      70             :      *      forget" approach: once the creator inserts an attribute into the container it transfers/moves ownership to the
      71             :      *      container and the creator never needs to invoke @c delete.  This policy also means that users never need to
      72             :      *      explicitly delete attributes if they copy and then delete an AST.  Newly designed attribute subclasses should use
      73             :      *      this policy unless they have a very good reason to use another policy.
      74             :      *
      75             :      *  @li @c NO_OWNERSHIP: Another simple approach is that ownership is transfered to the operating system.  In other words,
      76             :      *     the attribute is <em>never</em> deleted by the program and its memory is reclaimed only when the program terminates.
      77             :      *     Attribute containers that are incorporated into objects that are frequently allocated and/or copied and then deleted
      78             :      *     will result in a large number of leaked attributes.  This approach is not recommended and is present only for
      79             :      *     laziness.
      80             :      *
      81             :      *  @li @c CUSTOM_OWNERSHIP: A third approach is that the attribute subclass implements its own ownership policy, which
      82             :      *     ideally should have the properties listed above. An attribute using this policy will never be deleted by an
      83             :      *     attribute container; the class must implement some other mechanism for tracking which attributes are allocated and
      84             :      *     whether they can be safely deleted.
      85             :      *
      86             :      *  @li @c UNKNOWN_OWNERSHIP: This final policy is for subclasses implemented before clear attribute ownership rules were
      87             :      *     defined.  Due to the ambiguity in the original AstAttributeMechanism implementation and the fact that attributes
      88             :      *     are used by code outside the ROSE library, this must be the default implementation.
      89             :      *
      90             :      *  Regardless of the ownership policy, an attribute must not be deleted while it is a member of an AstAttributeMechanism
      91             :      *  container. This is because in order for the container to decide whether it should delete the attribute, it must first
      92             :      *  ask the attribute for its ownership policy.  In other words, the following code will likely result in a segmentation
      93             :      *  fault:
      94             :      *
      95             :      *  @code
      96             :      *   SgDirectedGraphEdge *edge = ...;
      97             :      *   delete edge->getAttribute("info");
      98             :      *   delete edge; // INVALID ACCESS TO EDGE ATTRIBUTE HERE
      99             :      *  @endcode */
     100             :     virtual OwnershipPolicy getOwnershipPolicy() const;
     101             : 
     102             :     /** Support for attibutes to specify edges in the dot graphs. */
     103             :     class ROSE_DLL_API AttributeEdgeInfo {
     104             :     public:
     105             :         SgNode* fromNode;
     106             :         SgNode* toNode;
     107             :         std::string label;
     108             :         std::string options;
     109             : 
     110           0 :         AttributeEdgeInfo(SgNode* fromNode, SgNode* toNode, std::string label, std::string options)
     111           0 :             : fromNode(fromNode), toNode(toNode), label(label), options(options) {}
     112             : 
     113           0 :         ~AttributeEdgeInfo() {
     114           0 :             fromNode = NULL;
     115           0 :             toNode = NULL;
     116           0 :         };
     117             :     };
     118             : 
     119             :     /** Support for adding nodes to DOT graphs. */
     120             :     class ROSE_DLL_API AttributeNodeInfo {
     121             :     public:
     122             :         SgNode* nodePtr;
     123             :         std::string label;
     124             :         std::string options;
     125             : 
     126             :         AttributeNodeInfo(SgNode* nodePtr, std::string label, std::string options)
     127             :             : nodePtr(nodePtr), label(label), options(options) {}
     128             : 
     129           0 :         ~AttributeNodeInfo() {};
     130             :     };
     131             : 
     132             : public:
     133          15 :     AstAttribute() {}
     134           7 :     virtual ~AstAttribute() {}
     135             : 
     136             :     /** Virtual default constructor.
     137             :      *
     138             :      *  Default-constructs a new object on the heap and returns its pointer.  All subclasses <em>must</em> implement this in
     139             :      *  order to instantiate the correct dynamic type, although many don't.  Invoking this constructor in a subclass that fails
     140             :      *  to implement it will return an attribute that's an incorrect dynamic type.
     141             :      *
     142             :      *  It would be nice if we could make this pure virtual, but unfortunately ROSETTA-generated code fails to compile because
     143             :      *  it generates an instantiation of this interface (whether or not that code is ever executed is unknown). [Robb Matzke
     144             :      *  2015-11-10]. */
     145           0 :     virtual AstAttribute* constructor() const {
     146           0 :         return new AstAttribute;                        // it doesn't make much sense to instantiate this type!
     147             :     }
     148             : 
     149             :     /** Virtual copy constructor.
     150             :      *
     151             :      *  Copy-constructs a new object on the heap and returns its pointer.  All subclasses must implement this in order to
     152             :      *  instantiate the correct dynamic type, although many don't.  If this @ref copy method returns a null pointer (like the
     153             :      *  base implementation) then the attribute is not copied as part of copying its container.  E.g., an attribute stored in
     154             :      *  an AST will not be copied when the AST is copied if that attribute is directly derived from @ref AstAttribute and fails
     155             :      *  to implement @ref copy.  If a subclass fails to implement @ref copy and inherits from a class that does implement a
     156             :      *  @ref copy that returns non-null, then the copied attribute will have an incorrect dynamic type.
     157             :      *
     158             :      *  It would be nice if we could make this pure virtual, but unfortunately ROSETTA-generated code fails to compile because
     159             :      *  it generates an instantiation of this interface (whether or not that code is ever executed is unkown). [Robb Matzke
     160             :      *  2015-11-10] */
     161           0 :     virtual AstAttribute* copy() const {
     162           0 :         return NULL;                                    // attribute will not be copied when the containing obj is copied
     163             :     }
     164             : 
     165             :     // DO NOT DOCUMENT!  The original implementation used a non-const copy constructor and many subclasses that implemented a
     166             :     // copy constructor didn't use C++11's "override" word as a defensive measure. Since we don't have access to all those
     167             :     // subclasses, we must continue to support the non-const version.  Subclasses should only have to implement one or the
     168             :     // other, not both.
     169           0 :     virtual AstAttribute* copy() {
     170           0 :         return const_cast<const AstAttribute*>(this)->copy();
     171             :     }
     172             : 
     173             :     /** Attribute class name.
     174             :      *
     175             :      *  Returns the name of the dynamic type. All subclasses must implement this in order to return the correct type name,
     176             :      *  although many don't.  If a subclass fails to implement this then it will return an incorrect class name.
     177             :      *
     178             :      *  It would be nice if this could be pure virtual, but unfortunately ROSETTA-generated code fails to compile because it
     179             :      *  generates an instantiation of this interface (whether or not that code is ever executed is unknown). [Robb Matzke
     180             :      *  2015-11-10] */
     181           7 :     virtual std::string attribute_class_name() const {
     182           7 :         return "AstAttribute";                          // almost certainly not the right dynamic type name!
     183             :     }
     184             : 
     185             :     /** Convert an attribute to a string.
     186             :      *
     187             :      *  This is used by other components to print the value of an attribute. For example the pdf generation calls this function
     188             :      *  to print the value of an attribute in the pdf file. The default implementation is to return the attribute address in
     189             :      *  the heap as a string. */
     190             :     virtual std::string toString();
     191             : 
     192             :     /** Packing support.
     193             :      *
     194             :      * @{ */
     195             :     virtual int packed_size();
     196             :     virtual char* packed_data();
     197             :     virtual void unpacked_data( int size, char* data );
     198             :     /** @} */
     199             : 
     200             :     /** DOT support.
     201             :      *
     202             :      *  @{ */
     203             :     virtual std::string additionalNodeOptions();
     204             :     virtual std::vector<AttributeEdgeInfo> additionalEdgeInfo();
     205             :     virtual std::vector<AttributeNodeInfo> additionalNodeInfo();
     206             :     /** @} */
     207             : 
     208             :     /** Eliminate IR nodes in DOT graphs.
     209             :      *
     210             :      *  Or to tailor the presentation of information about ASTs. */
     211             :     virtual bool commentOutNodeInGraph();
     212             : };
     213             : 
     214             : 
     215             : /** Stores named attributes in Sage IR nodes.
     216             :  *
     217             :  *  This attribute container stores one non-null, heap-allocated attribute per user-specified name.  All values are derived
     218             :  *  from @ref AstAttribute.  Any object can have an attribute container data member. For example, each AST node (@ref SgNode)
     219             :  *  contains one attribute container named @ref SgNode::get_attributeMechanism.
     220             :  *
     221             :  *  The value class's @ref AstAttribute::getOwnershipPolicy "getOwnershipPolicy" method indicates whether the container owns
     222             :  *  the heap-allocated attribute and therefore whether the container is responsible for invoking @c delete on the attribute
     223             :  *  when the container is destroyed.  New attribute subclasses should use the @ref AstAttribute::CONTAINER_OWNERSHIP policy if
     224             :  *  possible.
     225             :  *
     226             :  *  IR node attribute values are always on the heap. Whenever an attribute container is copied, the container invokes the @ref
     227             :  *  AstAttribute::copy "copy" method on all its attributes. The attributes' @c copy should either allocate a new copy of the
     228             :  *  attribute or return a null pointer. Since these values must be derived from @ref AstAttribute, it is not possible to
     229             :  *  directly store values whose type the user cannot modify to inherit from @ref AstAttribute. This includes POD types and
     230             :  *  classes defined in 3rd party libraries (e.g., @c std::vector). To store such values, the user must wrap them in another
     231             :  *  class that does inherit from @ref AstAttribute and which implements the necessary virtual functions.
     232             :  *
     233             :  *  The names of attributes are strings and the container does not check whether the string supplied to various container
     234             :  *  methods is spelled correctly.  Using a misspelled attribute name is the same as using a different value name--in effect,
     235             :  *  operating on a completely different, unintended attribute.
     236             :  *
     237             :  *  The @ref AstAttributeMechanism is used by AST nodes (@ref SgNode) and is available via @ref SgNode::get_attributeMechanism,
     238             :  *  although that is not the preferred API.  Instead, @ref SgNode provides an additional methods that contain "attribute" as
     239             :  *  part of their name. These "attribute" methods are mostly just wrappers around @ref SgNode::get_attributeMechanism.
     240             :  *
     241             :  *  Users can also use @ref AstAttributeMechanism as a data member in their own classes. However, @ref Sawyer::Attribute is
     242             :  *  another choice: not only does it serve as the implementation for @ref AstAttributeMechanism, but it also supports checked
     243             :  *  attribute names and attributes that are values rather than pointers, including POD, 3rd-party types, and shared-ownership
     244             :  *  pointers. The amount of boilerplate that needs to be written in order to store a @ref Sawyer::Attribute is much less than
     245             :  *  that required to store an attribute with @ref AstAttributeMechanism.
     246             :  *
     247             :  *  For additional information, including examples, see @ref attributes. */
     248             : class ROSE_DLL_API AstAttributeMechanism {
     249             :     // Use containment because we want to keep the original API.
     250             :     Sawyer::Attribute::Storage<> attributes_;
     251             : 
     252             : public:
     253             :     /** Default constructor.
     254             :      *
     255             :      *  Constructs an attribute mechanism that holds no attributes. */
     256           8 :     AstAttributeMechanism() {}
     257             : 
     258             :     /** Copy constructor.
     259             :      *
     260             :      *  Copying an attribute container will copy the heap-allocated attribute values by invoking each value's @c copy
     261             :      *  method. If the method returns null then the new attribute container will not have that attribute; i.e., the @ref exists
     262             :      *  method returns false.
     263             :      *
     264             :      *  <b>New semantics:</b> The original behavior was that if the value's @c copy method returned null, the @ref exists
     265             :      *  predicate returned true even though no value existed. */
     266           0 :     AstAttributeMechanism(const AstAttributeMechanism &other) {
     267           0 :         assignFrom(other);
     268           0 :     }
     269             : 
     270             :     /** Assignment operator.
     271             :      *
     272             :      *  Assigning one attribute container to another will cause the destination container's attributes to be erased and
     273             :      *  deleted, and the source container's attributes to be copied.  The assignment operator is exception safe: it will either
     274             :      *  successfully copy and assign all attributes or not assign any attributes. However, if an attribute uses anything other
     275             :      *  than the @ref AstAttribute::CONTAINER_OWNERHSIP ownership policy then it is up to the attribute type's designer to
     276             :      *  handle deletion of attributes that were copied before the exception occurred.
     277             :      *
     278             :      *  <b>New semantics:</b> The original implementation had a copy constructor but no assignment operator. Assignment of one
     279             :      *  attribute container to another caused both containers to share the attribute values allocated on the heap, making it
     280             :      *  nearly impossible to figure out when they could be safely deleted and therefore leading to memory leaks. */
     281             :     AstAttributeMechanism& operator=(const AstAttributeMechanism &other);
     282             : 
     283             :     /** Destructor.
     284             :      *
     285             :      *  Destroying the attribute container should cause unused attributes to be destroyed.  If an attribute implements the @ref
     286             :      *  AstAttribute::CONTAINER_OWNERHSIP policy then the container explicitly deletes the attribute, otherwise it is up to the
     287             :      *  attribute class's designer to implement a deletion policy that prevents leaks.
     288             :      *
     289             :      *  <b>New semantics:</b> The original implementation did not delete attributes when the container was destroyed, although
     290             :      *  it had commented-out code to do so. */
     291             :     ~AstAttributeMechanism();
     292             : 
     293             :     /** Test for attribute existence.
     294             :      *
     295             :      *  Test whether this container holds an attribute with the specified name.  This predicate returns true only if the name
     296             :      *  exists and points to a non-null attribute value.  The name need not be declared in the attribute system.
     297             :      *
     298             :      *  <b>New semantics:</b> It is now permissible to invoke this method on a const attribute container and this method no
     299             :      *  longer copies the name argument. */
     300             :     bool exists(const std::string &name) const;
     301             : 
     302             :     /** Insert an attribute.
     303             :      *
     304             :      *  Inserts the specified heap-allocated value for the given attribute name, replacing any previous value stored for
     305             :      *  that same name.
     306             :      *
     307             :      *  If the new value uses the @ref AstAttribute::CONTAINER_OWNERSHIP policy then ownership is immediately transferred/moved
     308             :      *  to this container, which becomes responsible for deleting the attribute as appropriate to prevent leasks.  Otherwise,
     309             :      *  the attribute's designer is responsible for implementing an ownership policy that safely prevents leaks.
     310             :      *
     311             :      *  If the old value (if present) uses the @ref AstAttribute::CONTAINER_OWNERSHIP policy then it is deleted. Otherwise the
     312             :      *  attribute's designer is responsible for implementing an ownership policy that safely prevents leaks, and the attribute
     313             :      *  must not be deleted until after this method returns.
     314             :      *
     315             :      *  <b>New semantics:</b> The old implementation didn't delete the previous attribute value.  The old implementation
     316             :      *  allowed setting a null value, in which case the old @c exists returned true but the @c operator[] returned no
     317             :      *  attribute. */
     318             :     void set(const std::string &name, AstAttribute *value);
     319             : 
     320             :     /** Insert a new value if the attribute doesn't already exist.
     321             :      *
     322             :      *  Tests whether an attribute with the specified name @ref exists and if not, invokes @ref set.  See @ref set for details
     323             :      *  about ownership of the new attribute. Returns true if an attribute with the specified name did not already existed.
     324             :      *
     325             :      *  <b>New semantics:</b> The old implementation was ambiguous about who owned the object after this call. It didn't take
     326             :      *  ownership of an attribute that wasn't inserted, but it also didn't indicate whether it was inserted.  The old
     327             :      *  implementation printed an error message on standard error if the attribute existed (even if only its name existed but
     328             :      *  it had no value) and then returned to the caller without doing anything. Inserting a null value was allowed by the old
     329             :      *  implementation, in which case the old @c exists returned true but the old @c operator[] returned no attribute. */
     330             :     bool add(const std::string &name, AstAttribute *value);
     331             : 
     332             :     /** Insert a new value if the attribute already exists.
     333             :      *
     334             :      *  Tests whether the specified attribute exists, and if so, invokes @ref set. See @ref set for details about ownership of
     335             :      *  the old and new attributes.  Returns true if an attribute with the specified name already existed.
     336             :      *
     337             :      *  <b>New semantics:</b> The old implementation was ambiguous about who owned the object after this call. It didn't take
     338             :      *  ownership of an attribute that wasn't inserted, but it also didn't indicate whether it was inserted. The old
     339             :      *  implementation printed an error message on standard error if the attribute didn't exist and then returned to the caller
     340             :      *  without doing anything. Inserting a null value was allowed by the old implementation, in which case the old @c exists
     341             :      *  returned true but the old @c operator[] returned no attribute. */
     342             :     bool replace(const std::string &name, AstAttribute *value);
     343             : 
     344             :     /** Get an attribute value.
     345             :      *
     346             :      *  Returns the value associated with the given attribute, or null if the attribute does not exist.  This method does not
     347             :      *  copy the attribute before returning it, therefore the caller should not delete the attribute. Erasing the attribute
     348             :      *  from the container may cause the pointer to become invalid, depending on the attribute's ownership policy. If the
     349             :      *  attribute uses the @ref AstAttribute::CONTAINER_OWNERSHIP method then the attribute can be modified through its pointer
     350             :      *  without affecting attributes in other containers, otherwise the behavior is up to the attribute's designer.
     351             :      *
     352             :      *  The caller will need to @c dynamic_cast the returned pointer to the appropriate subclass of @ref AstAttribute.
     353             :      *
     354             :      *  <b>New semantics:</b> The old implementation partly created an attribute if it didn't exist: @c exists started
     355             :      *  returning true although @c operator[] continued to return no attribute. The old implementation printed an error message
     356             :      *  to standard error if the attribute did not exist. */
     357             :     AstAttribute* operator[](const std::string &name) const;
     358             : 
     359             :     /** Erases the specified attribute.
     360             :      *
     361             :      *  If an attribute with the specified name exists then it is removed from the container. If the attribute implements the
     362             :      *  @ref AstAttribute::CONTAINER_OWNERSHIP policy then this container deletes the attribute, otherwise it is up to the
     363             :      *  attribute's designer to implement a safe way to prevent attribute leaks, and the attribute must not be deleted until
     364             :      *  after this method returns.
     365             :      *
     366             :      *  <b>New semantics:</b> The old implementation did not delete the attribute value. It also printed an error message
     367             :      *  to standard error if the attribute did not exist. */
     368             :     void remove(const std::string &name);
     369             : 
     370             :     /** Set of attribute names. */
     371             :     typedef std::set<std::string> AttributeIdentifiers;
     372             : 
     373             :     /** List of stored attribute names.
     374             :      *
     375             :      *  Returns the set of names for attributes stored in this container. This can be used to iterate over the attributes,
     376             :      *  as in:
     377             :      *
     378             :      *  @snippet binaryAttribute.C iterate 2
     379             :      *
     380             :      *  Or using the @ref SgNode API for attributes:
     381             :      *
     382             :      *  @snippet binaryAttribute.C iterate 3
     383             :      *
     384             :      *  <b>New semantics:</b> The old implementation also returned some names that had no attribute values. For instance, if
     385             :      *  @c operator[] was invoked for an attribute that didn't exist then that name was also returned. */
     386             :     AttributeIdentifiers getAttributeIdentifiers() const;
     387             : 
     388             :     /** Number of attributes stored.
     389             :      *
     390             :      *  Returns the number of attributes stored in this container.
     391             :      *
     392             :      *  <b>New semantics:</b> The old implementation returned a signed integer instead of @c size_t as is customary for size
     393             :      *  measurements. It also could not be invoked on a const container. It also could return a value larger larger than the
     394             :      *  number of stored attributes (such as when a previous query for a non-existing attribute occurred). */
     395             :     size_t size() const;
     396             : 
     397             : private:
     398             :     // Called by copy constructor and assignment.
     399             :     void assignFrom(const AstAttributeMechanism &other);
     400             : };
     401             : 
     402             : 
     403             : 
     404             : /** Attribute corresponding to a metric.
     405             :  *
     406             :  *  A metric attribute represents a numeric value obtained by either dynamic analysis (gprof or hpct) or static analysis (for
     407             :  *  example number of flop operations in a function) It MetricAttribute can be a raw (observed), or a propagated (derived)
     408             :  *  count It containes no name-string, because the attribute is stored in an AttributeMechanism-map, where the name is the
     409             :  *  key. */
     410           0 : class ROSE_DLL_API MetricAttribute: public AstAttribute {
     411             : protected:
     412             :     bool is_derived_;
     413             :     double value_;
     414             : 
     415             : public:
     416             :     MetricAttribute()
     417             :         : is_derived_(false), value_(0) {}
     418             :     
     419             :     MetricAttribute(double value, bool is_derived=false)
     420             :         : is_derived_(is_derived), value_(value) {}
     421             :     
     422             :     virtual AstAttribute* copy() const override;
     423             :     virtual std::string attribute_class_name() const override;
     424             : 
     425           0 :     virtual bool isDerived() const { return is_derived_; }
     426           0 :     virtual double getValue()  const { return value_; }
     427           0 :     virtual void setValue(double newVal) { value_ = newVal; }
     428             : 
     429             :     virtual std::string toString() override;
     430             : 
     431             :     virtual int packed_size() override;
     432             :     virtual char* packed_data() override;
     433             :     virtual void unpacked_data(int size, char* data) override;
     434             : 
     435             :     MetricAttribute& operator+=(const MetricAttribute &other);
     436             :     MetricAttribute& operator-=(const MetricAttribute &other);
     437             :     MetricAttribute& operator*=(const MetricAttribute &other);
     438             :     MetricAttribute& operator/=(const MetricAttribute &other);
     439             : };
     440             : 
     441             : 
     442             : /** IR node attribute that stores a copyable value.
     443             :  *
     444             :  *  Since IR node attributes must all inherit from @ref AstAttribute we need to write wrappers around POD types and 3rd party
     445             :  *  types when we want to store them as IR attributes. We've ended up with a proliferation of such attributes that all do
     446             :  *  almost the same thing but have different names to access their data members. Hopefully by providing one class template we
     447             :  *  can avoid further proliferation. */
     448             : template<class T>
     449             : class ROSE_DLL_API AstValueAttribute: public AstAttribute {
     450             : public:
     451             :     /** Type of value this wrapper holds. */
     452             :     typedef T Value;
     453             : private:
     454             :     Value value_;
     455             : public:
     456             :     /** Default constructor. Constructs an attribute wrapper having a default-constructed value. */
     457             :     AstValueAttribute() {}
     458             : 
     459             :     /** Constructs an attribute containing a specified value. */
     460             :     explicit AstValueAttribute(const T &value): value_(value) {}
     461             : 
     462             :     /** Copy constructor. Invokes the copy-constructor of the contained value. */
     463           0 :     AstValueAttribute(const AstValueAttribute &other): value_(other.value_) {}
     464             : 
     465           0 :     virtual AstAttribute* copy() const override { return new AstValueAttribute(*this); }
     466           0 :     virtual std::string attribute_class_name() const override { return "AstValueAttribute"; }
     467             : 
     468             :     /** Return the stored value by reference.
     469             :      *
     470             :      * @{ */
     471             :     const T& get() const { return value_; }
     472           0 :     T& get() { return value_; }
     473             :     /** @} */
     474             : 
     475             :     /** Assign a new value. */
     476             :     void set(const T& value) { value_ = value; }
     477             : };
     478             : 
     479             : // DQ (11/21/2009): Added new kind of attribute for handling regex trees.
     480             : /** Attribute containing a regex expression as a string.
     481             :  *
     482             :  *  An AstRegExAttribute is added to each part of an AST tree pattern specification to a RegEx tree. */
     483           0 : class ROSE_DLL_API AstRegExAttribute: public AstAttribute {
     484             : public:
     485             :     std::string expression;
     486             : 
     487             :     AstRegExAttribute() {}
     488             :     
     489             :     explicit AstRegExAttribute(const std::string & s)
     490             :         : expression(s) {}
     491             : 
     492           0 :     virtual AstAttribute* copy() const override {
     493           0 :         return new AstRegExAttribute(*this);
     494             :     }
     495             : 
     496           0 :     virtual std::string attribute_class_name() const override {
     497           0 :         return "AstRegExAttribute";
     498             :     }
     499             : };
     500             : 
     501             : 
     502             : // PC (10/21/2012): Added new kind of attribute for handling regex trees.
     503             : /** Attribute storing an SgNode.
     504             :  *
     505             :  *  A SgNode attribute may be used to "dynamically add" an SgNode field to an AST node. */
     506             : class ROSE_DLL_API AstSgNodeAttribute: public AstValueAttribute<SgNode*> {
     507             : public:
     508             :     typedef AstValueAttribute<SgNode*> Super;
     509             :     AstSgNodeAttribute(): Super(NULL) {}
     510             :     explicit AstSgNodeAttribute(SgNode *value): Super(value) {}
     511           0 :     AstSgNodeAttribute(const AstSgNodeAttribute &other): Super(other) {}
     512           0 :     virtual AstAttribute* copy() const override { return new AstSgNodeAttribute(*this); }
     513           0 :     virtual std::string attribute_class_name() const override { return "AstSgNodeAttribute"; }
     514           0 :     SgNode* getNode() { return get(); }
     515             :     void setNode(SgNode *node) { set(node); }
     516             : };
     517             : 
     518             : class ROSE_DLL_API AstSgNodeListAttribute: public AstValueAttribute<std::vector<SgNode*> > {
     519             : public:
     520             :     typedef AstValueAttribute<std::vector<SgNode*> > Super;
     521             :     AstSgNodeListAttribute() {}
     522             :     explicit AstSgNodeListAttribute(std::vector<SgNode *> &value): Super(value) {}
     523           0 :     AstSgNodeListAttribute(const AstSgNodeListAttribute &other): Super(other) {}
     524           0 :     virtual AstAttribute* copy() const override { return new AstSgNodeListAttribute(*this); }
     525           0 :     virtual std::string attribute_class_name() const override { return "AstSgNodeListAttribute"; }
     526             :     std::vector<SgNode*> &getNodeList() { return get(); }
     527             :     void addNode(SgNode *n) { get().push_back(n); }
     528             :     void setNode(SgNode*, int);
     529             :     SgNode *getNode(int);
     530             :     int size() { return get().size(); }
     531             : };
     532             : 
     533             : class ROSE_DLL_API AstIntAttribute : public AstValueAttribute<int> {
     534             : public:
     535             :     typedef AstValueAttribute<int> Super;
     536             :     AstIntAttribute(): Super(0) {}
     537             :     explicit AstIntAttribute(int value): Super(value) {}
     538           0 :     AstIntAttribute(const AstIntAttribute &other): Super(other) {}
     539           0 :     virtual AstAttribute* copy() const override { return new AstIntAttribute(*this); }
     540           0 :     virtual std::string attribute_class_name() const override { return "AstIntAttribute"; }
     541             :     int getValue() { return get(); }
     542             : };
     543             : 
     544             : #endif

Generated by: LCOV version 1.14