ROSE
0.11.96.11
|
Stores named attributes in Sage IR nodes.
This attribute container stores one non-null, heap-allocated attribute per user-specified name. All values are derived from AstAttribute. Any object can have an attribute container data member. For example, each AST node (SgNode) contains one attribute container named SgNode::get_attributeMechanism.
The value class's getOwnershipPolicy method indicates whether the container owns the heap-allocated attribute and therefore whether the container is responsible for invoking delete
on the attribute when the container is destroyed. New attribute subclasses should use the AstAttribute::CONTAINER_OWNERSHIP policy if possible.
IR node attribute values are always on the heap. Whenever an attribute container is copied, the container invokes the copy method on all its attributes. The attributes' copy
should either allocate a new copy of the attribute or return a null pointer. Since these values must be derived from AstAttribute, it is not possible to directly store values whose type the user cannot modify to inherit from AstAttribute. This includes POD types and classes defined in 3rd party libraries (e.g., std::vector
). To store such values, the user must wrap them in another class that does inherit from AstAttribute and which implements the necessary virtual functions.
The names of attributes are strings and the container does not check whether the string supplied to various container methods is spelled correctly. Using a misspelled attribute name is the same as using a different value name–in effect, operating on a completely different, unintended attribute.
The AstAttributeMechanism is used by AST nodes (SgNode) and is available via SgNode::get_attributeMechanism, although that is not the preferred API. Instead, SgNode provides an additional methods that contain "attribute" as part of their name. These "attribute" methods are mostly just wrappers around SgNode::get_attributeMechanism.
Users can also use AstAttributeMechanism as a data member in their own classes. However, Sawyer::Attribute is another choice: not only does it serve as the implementation for AstAttributeMechanism, but it also supports checked attribute names and attributes that are values rather than pointers, including POD, 3rd-party types, and shared-ownership pointers. The amount of boilerplate that needs to be written in order to store a Sawyer::Attribute is much less than that required to store an attribute with AstAttributeMechanism.
For additional information, including examples, see Working with attributes.
Definition at line 248 of file AstAttributeMechanism.h.
#include <AstAttributeMechanism.h>
Public Types | |
typedef std::set< std::string > | AttributeIdentifiers |
Set of attribute names. | |
Public Member Functions | |
AstAttributeMechanism () | |
Default constructor. More... | |
AstAttributeMechanism (const AstAttributeMechanism &other) | |
Copy constructor. More... | |
AstAttributeMechanism & | operator= (const AstAttributeMechanism &other) |
Assignment operator. More... | |
~AstAttributeMechanism () | |
Destructor. More... | |
bool | exists (const std::string &name) const |
Test for attribute existence. More... | |
void | set (const std::string &name, AstAttribute *value) |
Insert an attribute. More... | |
bool | add (const std::string &name, AstAttribute *value) |
Insert a new value if the attribute doesn't already exist. More... | |
bool | replace (const std::string &name, AstAttribute *value) |
Insert a new value if the attribute already exists. More... | |
AstAttribute * | operator[] (const std::string &name) const |
Get an attribute value. More... | |
void | remove (const std::string &name) |
Erases the specified attribute. More... | |
AttributeIdentifiers | getAttributeIdentifiers () const |
List of stored attribute names. More... | |
size_t | size () const |
Number of attributes stored. More... | |
|
inline |
Default constructor.
Constructs an attribute mechanism that holds no attributes.
Definition at line 256 of file AstAttributeMechanism.h.
|
inline |
Copy constructor.
Copying an attribute container will copy the heap-allocated attribute values by invoking each value's copy
method. If the method returns null then the new attribute container will not have that attribute; i.e., the exists method returns false.
New semantics: The original behavior was that if the value's copy
method returned null, the exists predicate returned true even though no value existed.
Definition at line 266 of file AstAttributeMechanism.h.
AstAttributeMechanism::~AstAttributeMechanism | ( | ) |
Destructor.
Destroying the attribute container should cause unused attributes to be destroyed. If an attribute implements the AstAttribute::CONTAINER_OWNERHSIP policy then the container explicitly deletes the attribute, otherwise it is up to the attribute class's designer to implement a deletion policy that prevents leaks.
New semantics: The original implementation did not delete attributes when the container was destroyed, although it had commented-out code to do so.
AstAttributeMechanism& AstAttributeMechanism::operator= | ( | const AstAttributeMechanism & | other | ) |
Assignment operator.
Assigning one attribute container to another will cause the destination container's attributes to be erased and deleted, and the source container's attributes to be copied. The assignment operator is exception safe: it will either successfully copy and assign all attributes or not assign any attributes. However, if an attribute uses anything other than the AstAttribute::CONTAINER_OWNERHSIP ownership policy then it is up to the attribute type's designer to handle deletion of attributes that were copied before the exception occurred.
New semantics: The original implementation had a copy constructor but no assignment operator. Assignment of one attribute container to another caused both containers to share the attribute values allocated on the heap, making it nearly impossible to figure out when they could be safely deleted and therefore leading to memory leaks.
bool AstAttributeMechanism::exists | ( | const std::string & | name | ) | const |
Test for attribute existence.
Test whether this container holds an attribute with the specified name. This predicate returns true only if the name exists and points to a non-null attribute value. The name need not be declared in the attribute system.
New semantics: It is now permissible to invoke this method on a const attribute container and this method no longer copies the name argument.
void AstAttributeMechanism::set | ( | const std::string & | name, |
AstAttribute * | value | ||
) |
Insert an attribute.
Inserts the specified heap-allocated value for the given attribute name, replacing any previous value stored for that same name.
If the new value uses the AstAttribute::CONTAINER_OWNERSHIP policy then ownership is immediately transferred/moved to this container, which becomes responsible for deleting the attribute as appropriate to prevent leasks. Otherwise, the attribute's designer is responsible for implementing an ownership policy that safely prevents leaks.
If the old value (if present) uses the AstAttribute::CONTAINER_OWNERSHIP policy then it is deleted. Otherwise the attribute's designer is responsible for implementing an ownership policy that safely prevents leaks, and the attribute must not be deleted until after this method returns.
New semantics: The old implementation didn't delete the previous attribute value. The old implementation allowed setting a null value, in which case the old exists
returned true but the operator
[] returned no attribute.
bool AstAttributeMechanism::add | ( | const std::string & | name, |
AstAttribute * | value | ||
) |
Insert a new value if the attribute doesn't already exist.
Tests whether an attribute with the specified name exists and if not, invokes set. See set for details about ownership of the new attribute. Returns true if an attribute with the specified name did not already existed.
New semantics: The old implementation was ambiguous about who owned the object after this call. It didn't take ownership of an attribute that wasn't inserted, but it also didn't indicate whether it was inserted. The old implementation printed an error message on standard error if the attribute existed (even if only its name existed but it had no value) and then returned to the caller without doing anything. Inserting a null value was allowed by the old implementation, in which case the old exists
returned true but the old operator
[] returned no attribute.
bool AstAttributeMechanism::replace | ( | const std::string & | name, |
AstAttribute * | value | ||
) |
Insert a new value if the attribute already exists.
Tests whether the specified attribute exists, and if so, invokes set. See set for details about ownership of the old and new attributes. Returns true if an attribute with the specified name already existed.
New semantics: The old implementation was ambiguous about who owned the object after this call. It didn't take ownership of an attribute that wasn't inserted, but it also didn't indicate whether it was inserted. The old implementation printed an error message on standard error if the attribute didn't exist and then returned to the caller without doing anything. Inserting a null value was allowed by the old implementation, in which case the old exists
returned true but the old operator
[] returned no attribute.
AstAttribute* AstAttributeMechanism::operator[] | ( | const std::string & | name | ) | const |
Get an attribute value.
Returns the value associated with the given attribute, or null if the attribute does not exist. This method does not copy the attribute before returning it, therefore the caller should not delete the attribute. Erasing the attribute from the container may cause the pointer to become invalid, depending on the attribute's ownership policy. If the attribute uses the AstAttribute::CONTAINER_OWNERSHIP method then the attribute can be modified through its pointer without affecting attributes in other containers, otherwise the behavior is up to the attribute's designer.
The caller will need to dynamic_cast
the returned pointer to the appropriate subclass of AstAttribute.
New semantics: The old implementation partly created an attribute if it didn't exist: exists
started returning true although operator
[] continued to return no attribute. The old implementation printed an error message to standard error if the attribute did not exist.
void AstAttributeMechanism::remove | ( | const std::string & | name | ) |
Erases the specified attribute.
If an attribute with the specified name exists then it is removed from the container. If the attribute implements the AstAttribute::CONTAINER_OWNERSHIP policy then this container deletes the attribute, otherwise it is up to the attribute's designer to implement a safe way to prevent attribute leaks, and the attribute must not be deleted until after this method returns.
New semantics: The old implementation did not delete the attribute value. It also printed an error message to standard error if the attribute did not exist.
AttributeIdentifiers AstAttributeMechanism::getAttributeIdentifiers | ( | ) | const |
List of stored attribute names.
Returns the set of names for attributes stored in this container. This can be used to iterate over the attributes, as in:
Or using the SgNode API for attributes:
New semantics: The old implementation also returned some names that had no attribute values. For instance, if operator
[] was invoked for an attribute that didn't exist then that name was also returned.
size_t AstAttributeMechanism::size | ( | ) | const |
Number of attributes stored.
Returns the number of attributes stored in this container.
New semantics: The old implementation returned a signed integer instead of size_t
as is customary for size measurements. It also could not be invoked on a const container. It also could return a value larger larger than the number of stored attributes (such as when a previous query for a non-existing attribute occurred).