Program Listing for File variables.h

Program Listing for File variables.h#

Return to documentation for file (src/midend/programAnalysis/genericDataflow/variables/variables.h)

#include <featureTests.h>
#ifdef ROSE_ENABLE_SOURCE_ANALYSIS

#ifndef VARIABLES_H
#define VARIABLES_H

#include "genericDataflowCommon.h"
#include <map>
#include <vector>
#include <list>
#include <utility>
#include <set>
#include <string>
#include <iosfwd>

class varID;

/* #########################
   ###### SHARED DATA ######
   ######################### */


extern std::map<SgFunctionDefinition*, std::set<varID> > allVars;
extern std::map<SgFunctionDefinition*, std::set<varID> > activeVars;

extern varID zeroVar;
extern varID oneVar;
extern varID allVar;

/*// = true only after the variables module has been initialized
extern bool variables_module_initialized;

void initVariables(SgProject* project);*/

/* ##############################
   ###### TYPE DEFINITIONS ######
   ############################## */

// virtual base class for other variable expressions
class variable
{
        public:
        //const char* str();
        virtual std::string str() const = 0;

        virtual bool operator == (const variable &that) const = 0;
        virtual bool operator <  (const variable &that) const = 0;

        // returns the scope in which this array variable was declared
        virtual SgScopeStatement* getScope() const=0;

        // returns a SgExpression that corresponds to an access of this variable
        virtual SgExpression* toSgExpression() const=0;

        // returns true if this variable is global and false otherwise
        virtual bool isGlobal() const=0;

        virtual ~variable() {}
};

// type of variable ids, their sets and maps of sets
class varID : public variable
{
        public:
        std::vector<SgInitializedName *> components;
        // Annotations associated with this variable
        std::map<std::string, void*> annotations;
        SgType* varType;
        // special variables do not have associated SgInitializedName nodes and thus, we just give them a name
        std::string name;

        varID(){ }

        varID(std::string name)
        {
                this->name = name;
                varType = NULL;
                genID();
        }

        // creates a varID from an SgNode s.t. isValidVarExp(n) is true
        varID(SgNode *n)
        {
                bool ret = init(n);
                ROSE_ASSERT(ret);
                genID();
        }

        varID(SgInitializedName *name)
        {
                bool ret = init(name);
                ROSE_ASSERT(ret);
                genID();
        }

        // pre-condition: isValidVarExp(refExp) evaluates to true
        varID(const SgExpression *exp)
        {
                bool ret=init(exp);
                ROSE_ASSERT(ret);
                genID();
        }

        varID(const varID& that) : variable()
        {
                init(that);
        }

        // initializes this object from the given varID
        bool init(const varID& that);

        // initializes this object from the given expression (assumed that isValidVarExp(n) is true)
        // returns true on success, false on failure
        bool init(SgNode *n);

        // initializes this object from the given expression (assumed that isValidVarExp(exp) is true)
        // returns true on success, false on failure
        bool init(const SgExpression *exp);

        // initializes this object from the given SgInitializedName (assumed that isValidVarExp(name) is true)
        bool init(SgInitializedName* name);

        void operator = (const variable &that);

        // recursive function that pulls the SgInitializedNames of all the SgVarRefExps inside this SgDotExp
        // returns true on success, false on failure
        bool collectDotComponents(const SgDotExp* dotExp);

        // returns the scope in which this variable was declared
        // for compound variables (i.e. those composed of dot expressions), it is the scope of the leftmost name
        SgScopeStatement* getScope() const;

        // returns a SgExpression that corresponds to an access of this variable
        SgExpression* toSgExpression() const;

protected:
        // returns a SgExpression that corresponds to an access of this variable, including only the components
        // at or after the iterator rest into the components vector
        SgExpression* toSgExpression_rec(std::vector<SgInitializedName *>::const_iterator rest) const;

public:
        // returns true if the given expression is one that can be represented as a variable in our representation
        static bool isValidVarExp(const SgNode* exp);
        static bool isValidVarExp(const SgExpression* exp);
        static bool isValidVarExp(const SgInitializedName* exp);

protected:
        static bool isValidVarExp_rec(const SgExpression* exp);

public:
        void add(SgInitializedName *name);

        // Adds the given annotation to this variable. Returns true if this causes the variable's
        // annotation state to change and false otherwise.
        bool addAnnotation(const std::string& aName, void* annot);

        // Remove the given annotation from this variable. Returns true if this variable
        // previously had this annotation and false otherwise.
        bool remAnnotation(const std::string& aName);

        // Remove the given annotation from this variable. Returns true if this variable
        // previously had this annotation and false otherwise.
        bool remAllAnnotations();

        // Swap this variables annotations, removing [fromAnnotName -> fromAnnotVal] and replacing
        // it with [toAnnotName -> toAnnotVal]. Returns true if this was successful (i.e. the variable
        // does have the [fromAnnotName -> fromAnnotVal] annotation) and false otherwise.
        // If the replacement occurs and this variable already has an annotation named
        //    toAnnotName, this annotation's value is replaced by toAnnotVal.
        bool swapAnnotations(const std::string& fromAnnotName, void* fromAnnotVal,
                             const std::string& toAnnotName, void* toAnnotVal);

        // If this variable has the annotation with the given name, returns it. Otherwise, returns NULL.
        void* getAnnotation(const std::string& aName) const;

        // If this variable has the annotation with the given name, returns true. Otherwise, returns false.
        bool hasAnnotation(const std::string& aName) const;

        // If this variable has the annotation with ANY name in the given set, returns true. Otherwise, returns false.
        bool hasAnyAnnotation(const std::set<std::string>& aNames) const;

        // If this variable has the annotation with EACH name in the given set, returns true. Otherwise, returns false.
        bool hasAllAnnotations(const std::set<std::string>& aNames) const;

        // Returns the total number of annotations associated with this variable
        int numAnnotations() const;

        // Returns the full map of all the annotations associated with this variable
        const std::map<std::string, void*>& getAnnotations() const;

        /******************
         *** COMPARISON ***
         ******************/

public:
        bool equal(const varID& two) const;
        bool lessThan(const varID& two) const;

        bool operator == (const variable &that) const;
        bool operator != (const varID &that) const;
        bool operator <  (const variable &that) const;
        bool operator >  (const varID &that) const;
        bool operator <= (const varID &that) const;
        bool operator >= (const varID &that) const;

        /**************
         *** OUTPUT ***
         **************/

        // string representation of the variable reference.
        // If noAnnot is true, excludes annotations from the name.
        //const char* str();
        std::string str() const;
        std::string str(bool noAnnot) const;

        // string representation of the variable reference, with variable/field names augmented with
        // the line numbers where they were defined. File names are omitted for brevity
        //const char* str_linenum();
        std::string str_linenum() const;

        // string representation of the variable reference, with the variable names replaced
        // with the pointers to their declarations
        //const char* str_ptr();
        std::string str_ptr() const;

        /**********************
         *** SEMANTINC INFO ***
         **********************/

        // returns true if the last field in this variable has an array or pointer type
        bool isArrayType() const;

        // returns true if any of its constituent SgInitializedNames are compiler-generated
        bool isCompilerGenerated() const;

        // returns true if this variable is global and false otherwise
        bool isGlobal() const;

        /*const bool isReferenceType()
        {
                return isSgReferenceType(components[components.size()-1]->get_typeptr());
        }*/

        private:
        // Unique ID generation and access functionality
        // the maximum ID that has been generated for any variable
        static long globalMaxID;
        // the unique ID of this variable
        long ID;
        // generates a new ID for this variable and stores it in ID
        void genID();

        public:
        // returns this variable's ID
        long getID() const;
};

std::ostream &operator<<(std::ostream &stream, varID v);
std::ostream &operator<<(std::ostream &stream, const std::set<varID>::iterator& v);
//ostream &operator<<(ostream &stream, const std::set<varID>::const_iterator& v);

//bool operator == ( const varID &one, const varID &two);

// Variables are ordered in lexicographic order, with element-wise comparisons
// performed using the basic < operator for pointers.
//bool operator < ( const varID &one, const varID &two);
//bool operator > ( const varID &one, const varID &two);

bool operator == (const varID &var, SgInitializedName* iName);
bool operator != (const varID &var, SgInitializedName* iName);
bool operator == (SgInitializedName* iName, const varID &var);
bool operator != (SgInitializedName* iName, const varID &var);

bool operator == (const varID &var, SgExpression* expr);
bool operator != (const varID &var, SgExpression* expr);
bool operator == (SgExpression* expr, const varID &var);
bool operator != (SgExpression* expr, const varID &var);

typedef std::set<varID, std::less<varID> > varIDSet;
typedef std::map<varID, varIDSet *>        m_varID2setPtr;
typedef std::map<varID, quad>              m_varID2quad;
typedef std::map<varID, std::string>            m_varID2str;
typedef std::map<varID, bool>              m_varID2bool;
typedef std::pair<varID, varID>            varIDpair;
typedef std::list<varID>                   varIDlist;
typedef std::map<varID, m_varID2quad>      m_varID2varID2quad;

// type of number sets and maps of their sets
typedef std::set<quad, std::less<quad> > setQuad;
typedef std::map<quad, setQuad *> m_quad2setPtr;

/* #################################
   ###### FUNCTION PROTOTYPES ######
   ################################# */

// Returns the varID that corresponds to the given SgExpression
varID SgExpr2Var(const SgExpression* expr);

// Returns true if the given expression can be interepreted as a concrete variable
bool isVarExpr(SgExpression* expr);

// translate from an expression that uses a variable to that variable's unique id
// currently supported: a (SgVarRefExp), a.i (SgDotExp),
/*varID getVarReference( SgVarRefExp *exp );
varID getVarReference( SgDotExp * );
varID getVarReference( SgInitializedName * );*/

// add the special variable Zero to the given set of variables
void addPredefinedVars(varIDSet &vars);

// returns whether the variable with the given id exists in our set of interest
bool existsVariable( varID x, m_varID2str &vars2Name );
// returns whether the variable in the given reference expression exists in our
// set of interest
bool existsVariable( SgVarRefExp *x, m_varID2str &vars2Name );

// returns whether this is a variable reference or dot expression (field reference)
bool isTypeConsidered( SgNode * exp);

// returns the id in a variable reference or dot expression (field reference)
//varID getRefOfTypeConsidered( SgNode *exp );

/*// mapping from variable declaration node pointer to string variable name for
// all the variables being used in the analysis of the current array
// (i.e. any variables involved in operations with the array, as
//   defined in determineInterestSet()
m_varID2str vars2Name;

// set of all 0, 1, -1, all constants being used in the program +/-1 and the sums of all the above
// may be used to make the widening operator more permissive
varIDSet allConstants;
*/

// returns a set of varIDs that correspond to all the variables (of SgDotExp/SgVarRefExp form)
// that were referenced in the given subtree
varIDSet getVarRefsInSubtree(SgNode* root);

// returns a set of varIDs that correspond to all the variables (of SgDotExp/SgVarRefExp form)
// that were read from in the given subtree
varIDSet getReadVarRefsInSubtree(SgNode* root);

// returns a set of varIDs that correspond to all the variables (of SgDotExp/SgVarRefExp form)
// that were written to in the given subtree
varIDSet getWriteVarRefsInSubtree(SgNode* root);

// returns a set of varIDs that correspond to all the variables (of SgDotExp/SgVarRefExp form)
// that were referenced as arrays (i.e. var[i]) in the given subtree
varIDSet getArrayVarRefsInSubtree(SgNode* root);


class arrayElt : public variable
{
        varID arrayVar;
        std::list<SgExpression*>* indexExprs;

        public:
        arrayElt(SgNode* expr);

        arrayElt(SgExpression* expr);

        std::string str() const;

        bool operator == (const variable &that_arg) const;

        bool operator <  (const variable &that) const;

        // returns true if the given expression is one that can be represented as a variable in our representation
        static bool isValidVarExp(const SgExpression* exp);

        // returns the scope in which this array variable was declared
        // for compound variables (i.e. those composed of dot expressions), it is the scope of the leftmost name
        SgScopeStatement* getScope() const;

        // returns a reference to the array variable, without any indexes
        const varID& getArrayVar();

        // returns a reference to the index expressions
        std::list<SgExpression*>* getIndexExprs();

        // returns a SgExpression that corresponds to an access of this variable
        SgExpression* toSgExpression() const;

        protected:
        // returns the SgPntrArrRefExp that corresponds to the index expressions in indexExprs that start with itIndexes
        // precondition : itIndexes!=index.end()
        SgPntrArrRefExp* toSgExpression_rec(std::list<SgExpression*>::reverse_iterator itIndexes) const;

        public:
        // returns true if this variable is global and false otherwise
        bool isGlobal() const;
};

// returns a set of arrayElts that correspond to all the arrays (of SgDotExp/SgVarRefExp[SgExpression][][][]... form)
// that were referenced in the given subtree
std::set<arrayElt> getArrayRefsInSubtree(SgNode* root);
#endif
#endif