Program Listing for File SgNodeHelper.h

Program Listing for File SgNodeHelper.h#

Return to documentation for file (src/midend/abstractLayer/SgNodeHelper.h)

#ifndef SgNodeHelper_H
#define SgNodeHelper_H

#include <set>
#include <list>
#include <vector>
#include <string>

class SgNode;
class SgProject;
class SgLocatedNode;

class SgStatement;

class SgScopeStatement;
class SgGlobal;
class SgFunctionDefinition;

class SgDeclarationStatement;
class SgVariableDeclaration;
class SgFunctionDeclaration;
class SgInitializedName;
class SgClassDeclaration;

class SgExpression;
class SgVarRefExp;
class SgFunctionRefExp;
class SgFunctionCallExp;

class SgSymbol;
class SgVariableSymbol;
class SgFunctionSymbol;

class SgType;
class SgPointerType;
class SgReferenceType;
class SgRvalueReferenceType;
class SgFunctionType;

class SgContinueStmt;
class SgCaseOptionStmt;
class SgDefaultOptionStmt;

class SgPragmaDeclaration;
class SgOmpClauseBodyStatement;

namespace SgNodeHelper {

  typedef std::pair<int,int> LineColPair;

  bool hasAssignInitializer(SgVariableDeclaration* decl);

  bool isAggregateDeclarationWithInitializerList(SgVariableDeclaration* decl);

  SgExpression* getInitializerExpressionOfVariableDeclaration(SgVariableDeclaration* decl);

  SgInitializedName* getInitializedNameOfVariableDeclaration(SgVariableDeclaration* decl);

  SgDeclarationStatement* findVariableDeclarationWithVariableSymbol(SgNode* node);

  SgFunctionDeclaration* findFunctionDeclarationWithFunctionSymbol(SgNode* node);

  std::string sourceFilenameLineColumnToString(SgNode* node);

  SgNodeHelper::LineColPair lineColumnPair(SgNode* node);

  std::string sourceFilenameToString(SgNode* node);

  std::string sourceLineColumnToString(SgNode* node);
  std::string sourceLineColumnToString(SgNode* node, std::string separator);

  std::string lineColumnAndSourceCodeToString(SgNode* node);

  std::string locationToString(SgNode* node);

  std::string abbreviatedLocationToString(SgNode* node, size_t maxFileNameLength=30);

  std::string locationAndSourceCodeToString(SgNode* node, size_t maxFileNameLength=30, size_t maxSourceLength=20);

  std::vector<SgVarRefExp*> determineVariablesInSubtree(SgNode* node);

  std::list<SgClassDeclaration*> classDeclarationNestingSequence(SgDeclarationStatement*);

  int scopeNestingLevel(SgNode* node);

  int scopeSequenceNumber(SgNode* node);

  size_t determineChildIndex(SgNode* node);


  std::vector<SgStatement *> & getForInitList(SgNode* node);

  SgExpression * getForIncExpr(SgNode* node);

  bool isForIncExpr(SgNode* node);

  SgNode* getCond(SgNode* node);

  std::string unparseCond(SgNode* node);

  SgNode* getTrueBranch(SgNode* node);

  SgNode* getFalseBranch(SgNode* node);

  SgNode* getLoopBody(SgNode* node);

  SgNode* getFirstOfBlock(SgNode* node);

  SgNode* getLastOfBlock(SgNode* node);

  std::string getLabelName(SgNode* node);

  std::string getFunctionName(SgNode* node);

  SgFunctionDefinition* determineFunctionDefinition(SgFunctionCallExp* fCall);

  bool isForwardFunctionDeclaration(SgNode* declaration);

  SgFunctionDefinition* correspondingSgFunctionDefinition(SgNode* node);

  bool isAstRoot(SgNode* node);

  bool isLoopStmt(SgNode* node);

  bool isLoopCond(SgNode* node);

  bool isCondStmtOrExpr(SgNode* node);

  bool isCondStmt(SgNode* node);

  bool isCondInBranchStmt(SgNode* node);

  bool isCond(SgNode* node);

  void setCond(SgStatement* stmt, SgNode* cond);


  bool isPrefixIncDecOp(SgNode* node);

  bool isPostfixIncDecOp(SgNode* node);

  SgSymbol* getSymbolOfVariableDeclaration(SgVariableDeclaration* decl);

  SgFunctionSymbol* getSymbolOfFunctionDeclaration(SgFunctionDeclaration* decl);

  SgSymbol* getSymbolOfVariable(SgVarRefExp* varRefExp);

  SgFunctionSymbol* getSymbolOfFunction(SgFunctionRefExp* funcRefExp);

  SgSymbol* getSymbolOfInitializedName(SgInitializedName* initName);

  std::string symbolToString(SgSymbol* symbol);

  std::string uniqueLongVariableName(SgNode* node);

  std::set<SgNode*> loopRelevantBreakStmtNodes(SgNode* node);
  std::set<SgContinueStmt*> loopRelevantContinueStmtNodes(SgNode* node);

  std::set<SgCaseOptionStmt*> switchRelevantCaseStmtNodes(SgNode* node);

  SgDefaultOptionStmt* switchRelevantDefaultStmtNode(SgNode* node);

  SgNode* getFirstChild(SgNode* node);

  std::vector<SgExpression *> & getFunctionCallActualParameterList(SgNode* node);

  // schroder3 (2016-07-27): Returns the callee of the given call expression
  SgExpression* getCalleeOfCall(/*const*/ SgFunctionCallExp* call);

  // schroder3 (2016-06-24): Returns the function type of the callee of the given call expression
  SgFunctionType* getCalleeFunctionType(/*const*/SgFunctionCallExp* call);

  std::vector<SgInitializedName *> & getFunctionDefinitionFormalParameterList(SgNode* node);

  SgType* getFunctionReturnType(SgNode* node);

  std::set<SgVariableDeclaration*> localVariableDeclarationsOfFunction(SgFunctionDefinition* funDef);

  SgFunctionDefinition* getClosestParentFunctionDefinitionOfLocatedNode(SgLocatedNode* locatedNode);

  SgNode* getExprStmtChild(SgNode* node);

  SgNode* getExprRootChild(SgNode* node);

  SgNode* getUnaryOpChild(SgNode* node);

  int numChildren(SgNode* node);

  std::string doubleQuotedEscapedString(std::string s1);

  std::string doubleQuotedEscapedHTMLString(std::string s1);

  //a forward declaration. This case no declaration for the variable
  //exists. This is currently not possible in the ROSE AST.
  bool isVariableSymbolInFunctionForwardDeclaration(SgNode* node);

  SgVariableSymbol* isFunctionParameterVariableSymbol(SgNode* node);

  std::string nodeToString(SgNode* node);

  SgNode* getLhs(SgNode* node);

  SgNode* getRhs(SgNode* node);

  SgNode* getParent(SgNode* node);

  std::list<SgGlobal*> listOfSgGlobal(SgProject* project);

  std::list<SgVariableDeclaration*> listOfGlobalVars(SgProject* project);
#if __cplusplus > 199711L
  std::list<SgVariableDeclaration*> listOfGlobalFields(SgProject* project);
#endif
  std::list<SgVariableDeclaration*> listOfGlobalVars(SgGlobal* global);
#if __cplusplus > 199711L
  std::list<SgVariableDeclaration*> listOfGlobalFields(SgGlobal* global);
#endif

  std::list<SgFunctionDefinition*> listOfFunctionDefinitions(SgNode* node);
#if __cplusplus > 199711L
  std::list<SgFunctionDeclaration*> listOfFunctionDeclarations(SgNode* node);
#endif
  std::list<SgVarRefExp*> listOfUsedVarsInFunctions(SgProject* SgProject);

  std::list<SgFunctionDefinition*> listOfGlobalFunctionDefinitions(SgGlobal* global);

  bool isGlobalVariableDeclarationSymbol(SgSymbol* varDecl);
  bool isGlobalVariableDeclaration(SgVariableDeclaration* varDecl);

  bool isArrayElementAssignment(SgNode* node);
  bool isFloatingPointAssignment(SgNode* exp);
  bool isArrayAccess(SgNode* node);
  bool isPointerVariable(SgVarRefExp* var);

  // checks for float, double, long double
  bool isFloatingPointType(SgType* type);

  // schroder3 (2016-07-22): Modified version of SageInterface::isPointerType(...) that returns the
  //  underlying pointer type.
  const SgPointerType* isPointerType(const SgType* t);

  // schroder3 (2016-08-17): Added support for rvalue reference types. See isLvalueReferenceType(...)
  //  if only lvalue references are desired.
  // schroder3 (2016-07-22): Modified version of SageInterface::isReferenceType(...) that
  //  returns the underlying reference type.
  //
  // Returns the underlying (without typedefs and mofifiers) rvalue OR lvalue reference type if the
  //  given type is such a reference type. Returns 0 otherwise.
  const SgType* isReferenceType(const SgType* t);

  // schroder3 (2016-08-22): Modified version of SageInterface::isReferenceType(...) that
  //  returns the underlying LVALUE reference type.
  const SgReferenceType* isLvalueReferenceType(const SgType* t);

  // schroder3 (2016-08-22): Returns the underlying RVALUE reference type if the given type is a
  //  rvalue reference type. Returns 0 otherwise.
  const SgRvalueReferenceType* isRvalueReferenceType(const SgType* t);

  // schroder3 (2016-08-22): Wrapper around SgReferenceType::get_base_type(...) and
  //  SgRvalueReferenceType::get_base_type(...) that works for both reference types.
  //  (This is a workaround for the missing mutual base class of SgReferenceType and
  //  SgRvalueReferenceType.)
  SgType* getReferenceBaseType(const SgType* t);

  // schroder3 (2016-07-26): Returns the given type as a SgPointerType if it is a
  //  function pointer type. Returns 0 otherwise.
  const SgPointerType* isFunctionPointerType(const SgType* type);

  // schroder3 (2016-07-26): Returns the (underlying) function type of the given type if the given
  //  type is eligible for function-to-pointer conversion. Returns 0 otherwise.
  const SgFunctionType* isTypeEligibleForFunctionToPointerConversion(const SgType* type);

  // schroder3 (2016-07-27): Returns the underlying function type of the given expression if it
  //  is callable. Returns 0 otherwise.
  SgFunctionType* isCallableExpression(/*const*/ SgExpression* expr);

  // schroder3 (2016-07-27): Returns the underlying function type if the given type
  //  is callable i.e. a expression of this type could be called. Returns 0 otherwise.
  SgFunctionType* isCallableType(/*const*/ SgType* type);

  // determines whether decl declares an array
  bool isArrayDeclaration(SgVariableDeclaration* decl);

  // determines whether decl is an array or a struct
  bool isAggregateDeclaration(SgVariableDeclaration* decl);

  // returns the list of initializers of an array or struct (e.g. for int a[]={1,2,3} it return the list 1,2,3)
  std::vector<SgExpression *> & getInitializerListOfAggregateDeclaration(SgVariableDeclaration* decl);

  void replaceExpression(SgExpression* e1, SgExpression* e2, bool mode=false);

  void replaceAstWithString(SgNode* node, std::string s);

  typedef std::list<std::pair<std::string,SgNode*> > PragmaList;
  PragmaList collectPragmaLines(std::string pragmaName,SgNode* root);

  std::string getPragmaDeclarationString(SgPragmaDeclaration* pragmaDecl);

  void replaceString(std::string& str, const std::string& from, const std::string& to);

  bool isPrefix(const std::string& prefix, const std::string& s);

  bool isLastChildOf(SgNode* elem, SgNode* parent);

  std::list<SgVariableDeclaration*> memberVariableDeclarationsList(SgClassType* sgType);

#if __cplusplus > 199711L
  bool hasOmpNoWait(SgOmpClauseBodyStatement *ompNode);

  typedef std::vector<SgOmpSectionStatement *> OmpSectionList;
  OmpSectionList getOmpSectionList(SgOmpSectionsStatement *sectionsStmt);
#endif

  namespace Pattern {
    SgFunctionCallExp* matchFunctionCall(SgNode*);
    SgFunctionCallExp* matchReturnStmtFunctionCallExp(SgNode*);

    SgFunctionCallExp* matchExprStmtFunctionCallExp(SgNode*);

    SgFunctionCallExp* matchExprStmtAssignOpVarRefExpFunctionCallExp(SgNode*);

    SgFunctionCallExp* matchFunctionCallExpInVariableDeclaration(SgNode* node);

    SgVariableDeclaration* matchVariableDeclarationWithFunctionCall(SgNode* node);
    std::pair<SgVariableDeclaration*,SgFunctionCallExp*> matchVariableDeclarationWithFunctionCall2(SgNode* node);

    std::pair<SgVarRefExp*,SgFunctionCallExp*> matchExprStmtAssignOpVarRefExpFunctionCallExp2(SgNode* node);

    bool matchAssertExpr(SgNode* node);

    SgVarRefExp* matchSingleVarScanf(SgNode* node);
    SgVarRefExp* matchSingleVarPrintf(SgNode* node);
    SgVarRefExp* matchSingleVarFPrintf(SgNode* node,bool showWarnings=false);

    struct OutputTarget {
      bool isKnown();
      enum OType { VAR,INT,UNKNOWNPRINTF,UNKNOWNOPERATION};
      OutputTarget():varRef(0),intVal(0),outType(UNKNOWNOPERATION){}
      SgVarRefExp* varRef;
      int intVal;
      OType outType;
    };
    OutputTarget matchSingleVarOrValuePrintf(SgNode* node);


  } // end of namespace Pattern

  std::string lineColumnNodeToString(SgNode* node);

  std::string sourceLocationAndNodeToString(SgNode* node);

#if __cplusplus > 199711L
  // Can a given node be changed? (aka transformed)
  bool nodeCanBeChanged(SgLocatedNode * lnode);
#endif


  struct ExtendedCallInfo
  {
      ExtendedCallInfo()
      : rep(NULL)
      {}

      ExtendedCallInfo(SgLocatedNode& callnode)
      : rep(&callnode)
      {}

      SgLocatedNode*            representativeNode() const;

      SgFunctionCallExp*        callExpression()     const;

      SgConstructorInitializer* ctorInitializer()    const;

      //  or the nullptr otherise.
      SgExpression*             functionPointer()    const;

      operator bool() const { return rep != NULL; }

    private:
      SgLocatedNode* rep;
  };

  ExtendedCallInfo
  matchExtendedNormalizedCall(SgNode*);
} // end of namespace SgNodeHelper

#endif