Program Listing for File AstConsistencyTests.h#
↰ Return to documentation for file (src/midend/astDiagnostics/AstConsistencyTests.h)
// Author: Markus Schordan
// $Id: AstConsistencyTests.h,v 1.8 2008/01/25 02:25:46 dquinlan Exp $
#ifndef ASTTESTS_H
#define ASTTESTS_H
// DQ (12/7/2003): use platform independent macro defined in config.h
// #include IOSTREAM_HEADER_FILE
#include <iostream>
#include "rosedll.h"
#include "AstStatistics.h"
// #include "AstPDFGeneration.h"
#include "AstTextAttributesHandling.h"
#include "AstNodePtrs.h"
#include "AstReverseProcessing.h"
class TestAstPropertiesSA
{
public:
TestAstPropertiesSA():val(true),node(NULL) {}
bool val;
SgNode* node;
};
class TestAstProperties : public AstBottomUpProcessing<TestAstPropertiesSA>
{
private:
// DQ (8/3/2004): This list is used to record and report any IR nodes that have missing file
// info the file info object is present, but the information is it is default information
// (e.g. filename = NULL_FILE, line = 0, column = 0)
std::list<SgNode*> listOfNodesWithoutValidFileInfo;
std::list<SgNode*> listOfNodesFileInfo;
public:
// DQ (10/24/2004): Track count of nodes without proper ending file info object
int nodeWithoutFileInfoFrequencyCount[V_SgNumVariants];
TestAstProperties();
private:
TestAstPropertiesSA evaluateSynthesizedAttribute(SgNode* node, SubTreeSynthesizedAttributes l);
};
class ROSE_DLL_API AstTests
{
public:
// some handy string functions used when testing the RTI information of a SgNode
static bool isPrefix(std::string prefix, std::string s);
static unsigned int numPrefix(std::string prefix, std::vector<std::string> vs);
// properties of SgNodes
static unsigned int numSuccContainers(SgNode* node);
static unsigned int numSingleSuccs(SgNode* node);
static bool isProblematic(SgNode* node);
static void runAllTests(SgProject* sageProject);
static bool isCorrectAst(SgProject* sageProject);
};
#ifndef SWIG
// DQ (3/10/2013): Swig has a problem with this class (remove from visability to swig).
class TestAstNullPointers : public AstNodePtrs {
public:
TestAstNullPointers() {}
virtual void visitWithAstNodePointersList(SgNode* node, AstNodePointersList l);
};
#endif
// these dummy classes are just to show the interfaces of the 4 kinds of traversals
// void dummyTests(SgProject* sageProject); // traverse AST with all 4 kinds of traversals
class DI : AstInheritedAttribute {}; // Dummy inherited attribute
class DS : AstSynthesizedAttribute {}; // Dummy synthesized attribute
class DummyISTestQuery1 : public AstTopDownBottomUpProcessing<DI,DS> {
DI evaluateInheritedAttribute(SgNode*, DI inh) { return inh; }
DS evaluateSynthesizedAttribute(SgNode*, DI, SubTreeSynthesizedAttributes) { DS syn; return syn; }
};
class DummyITestQuery1 : public AstTopDownProcessing<DI> {
DI evaluateInheritedAttribute(SgNode*, DI inh) { return inh; }
};
class DummySTestQuery1 : public AstBottomUpProcessing<DS> {
DS evaluateSynthesizedAttribute(SgNode*, SubTreeSynthesizedAttributes) { DS syn; return syn; }
};
class DummyTestQuery1 : public AstSimpleProcessing {
void visit(SgNode*) {}
};
class DummyISTestQuery2 : public AstReversePrefixInhSynProcessing<DI,DS> {
DI evaluateInheritedAttribute(SgNode*, DI inh) { return inh; }
DS evaluateSynthesizedAttribute(SgNode*, DI, SubTreeSynthesizedAttributes) { DS syn; return syn; }
};
class DummyITestQuery2 : public AstReversePrefixInhProcessing<DI> {
DI evaluateInheritedAttribute(SgNode*, DI inh) { return inh; }
};
class DummySTestQuery2 : public AstReversePrefixSynProcessing<DS> {
DS evaluateSynthesizedAttribute(SgNode*, SubTreeSynthesizedAttributes) { DS syn; return syn; }
};
class DummyTestQuery2 : public AstReversePrefixSimpleProcessing {
void visit(SgNode*) {}
};
class DummyISTestQuery3 : public AstReverseBranchInhSynProcessing<DI,DS> {
DI evaluateInheritedAttribute(SgNode*, DI inh) { return inh; }
DS evaluateSynthesizedAttribute(SgNode*, DI, SubTreeSynthesizedAttributes) { DS syn; return syn; }
};
class DummyITestQuery3 : public AstReverseBranchInhProcessing<DI> {
DI evaluateInheritedAttribute(SgNode*, DI inh) { return inh; }
};
class DummySTestQuery3 : public AstReverseBranchSynProcessing<DS> {
DS evaluateSynthesizedAttribute(SgNode*, SubTreeSynthesizedAttributes) { DS syn; return syn; }
};
class DummyTestQuery3 : public AstReverseBranchSimpleProcessing {
void visit(SgNode*) {}
};
// DQ (3/30/2004): Added tests on templates!
// class TestAstTemplateProperties : public AstPreOrderTraversal
class TestAstTemplateProperties : public AstSimpleProcessing
{
// This class uses a traversal to test properties of template
// specific IR nodes in the AST.
public:
void visit ( SgNode* node );
};
class TestAstForUniqueStatementsInScopes : public AstSimpleProcessing
{
// This class uses a traversal to test properties of AST.
// We look for redundent entries in any single scope (not
// redundent entries in the AST!).
public:
void visit ( SgNode* node );
};
// DQ (4/2/2012): This appears to be a test that we have not got into place yet.
// the test code: test2012_59.C demonstrates an example where a IR node is shared
// between the global scope and a class definition scope. This causes an error
// in the generated code, so we want to detect this case.
class TestAstForUniqueNodesInAST : public AstSimpleProcessing
{
// This class uses a traversal to test properties of AST.
// We look for redundent entries anywhere in the AST.
// This test has to save a pointer to ever AST IR node
// that is traversed so it is a bit expensive in memory.
std::set<SgNode*> astNodeSet;
public:
void visit ( SgNode* node );
static void test ( SgNode* node );
};
// DQ (4/3/2012): Simple globally visible function to call (used for debugging elsewhee in ROSE).
void testAstForUniqueNodes ( SgNode* node );
class TestAstCompilerGeneratedNodes : public AstSimpleProcessing
{
// This class uses a traversal to test properties of compiler generated IR nodes.
public:
void visit ( SgNode* node );
};
class TestAstForProperlyMangledNames : public AstSimpleProcessing
{
// This class uses a traversal to test properties of namged names.
public:
unsigned long saved_maxMangledNameSize;
unsigned long saved_totalMangledNameSize;
unsigned long saved_numberOfMangledNames;
void visit ( SgNode* node );
// DQ (8/28/2006): Added constructor to permit data members to be set properly
TestAstForProperlyMangledNames();
// DQ (2/7/2006): This is Rich's function to simplify the testing
// (we make it static so that it can be easily called from elsewhere).
static bool isValidMangledName (std::string name);
};
class TestAstForProperlySetDefiningAndNondefiningDeclarations : public AstSimpleProcessing
{
// This class uses a traversal to test the values of the definingDeclaration and
// firstNondefiningDeclaration pointers in each SgDeclarationStatement. See code for
// details, since both of these pointers are not always set.
public:
void visit ( SgNode* node );
};
class TestAstSymbolTables : public AstSimpleProcessing
{
// This class uses a traversal to test properties of symbol tables
// (global function type symbol table and local symbol tables in each scope).
public:
void visit ( SgNode* node );
};
class TestAstAccessToDeclarations : public AstSimpleProcessing
{
// This class uses a traversal to test the get_declaration() member function on each
// IR node where relavant. The goal is to verify that each member function, were
// appropriate, returns a valid declaration.
public:
static void test(SgNode* node);
void visit ( SgNode* node );
};
class TestExpressionTypes : public AstSimpleProcessing
{
// This class uses a traversal to test the get_type() member function on each
// SgExpression IR node. The goal is to verify that each member function, were
// appropriate, returns a valid type.
public:
// static void test(SgNode* node);
// DQ (10/31/2016): Added constructor so that we could test using set_useDefaultIndexBasedTraversal(false);
TestExpressionTypes();
void visit ( SgNode* node );
};
class TestLValues : public AstSimpleProcessing
{
// This class uses a traversal to test the isLValue() and isDefinable() member functions on each
// SgExpression IR node. The goal is to verify that each member function, were
// appropriate, returns whether or not its argument is an lvalue or definable.
public:
// static void test(SgNode* node);
void visit ( SgNode* node );
};
// class TestMangledNames : public AstSimpleProcessing
class TestMangledNames : public ROSE_VisitTraversal
{
// This class uses a traversal to test the generation of mangled names.
public:
virtual ~TestMangledNames() {};
static void test();
unsigned long saved_maxMangledNameSize;
unsigned long saved_totalMangledNameSize;
unsigned long saved_numberOfMangledNames;
unsigned long totalLongMangledNameSize;
unsigned long totalNumberOfLongMangledNames;
// DQ (8/28/2006): Added constructor to permit data members to be set properly
TestMangledNames();
void visit ( SgNode* node );
};
#if 0
class TestParentPointersOfSymbols : public ROSE_VisitTraversal
{
// This class uses a traversal to test the parent pointers of symbols.
public:
static void test();
void visit ( SgNode* node );
};
#endif
#if 0
void testParentPointersOfSymbols();
#endif
// DQ (6/26/2006): Added test of parents of IR nodes using memory pool!
// void testParentPointersInMemoryPool();
class TestParentPointersInMemoryPool : public ROSE_VisitTraversal
{
public:
virtual ~TestParentPointersInMemoryPool() {};
static void test();
void visit (SgNode* node);
};
class TestChildPointersInMemoryPool : public ROSE_VisitTraversal
{
public:
virtual ~TestChildPointersInMemoryPool() {};
static void test();
virtual void visit( SgNode * );
};
class TestFirstNondefiningDeclarationsForForwardMarking : public ROSE_VisitTraversal
{
public:
virtual ~TestFirstNondefiningDeclarationsForForwardMarking() {};
static void test();
virtual void visit( SgNode * );
};
class TestMappingOfDeclarationsInMemoryPoolToSymbols : public ROSE_VisitTraversal
{
public:
virtual ~TestMappingOfDeclarationsInMemoryPoolToSymbols() {};
static void test();
virtual void visit( SgNode * );
};
class TestLValueExpressions : public AstSimpleProcessing
{
// This class uses a traversal to test expressions that should be marked
// as lvalues and makes sure that other expressions are not marked as lvalues.
public:
// static void test(SgNode* node);
void visit ( SgNode* node );
};
class TestMultiFileConsistancy : public ROSE_VisitTraversal // AstSimpleProcessing
{
// DQ (3/7/2010): Corrected the documentation for this class.
// Test the declarations to make sure that defining and non-defining appear in
// the same file (for outlining consistency).
public:
static void test();
void visit ( SgNode* node );
};
class BuildListOfConnectedNodesInAST : public AstSimpleProcessing
{
// DQ (3/7/2010): This class is part of a test to detect disconnected
// parts of the AST. These are currently a problem for the AST File I/O
// and need to be eliminated.
public:
std::set<SgNode*> & nodeSet;
BuildListOfConnectedNodesInAST(std::set<SgNode*> & s);
void visit ( SgNode* node );
};
class BuildListOfNodesInAST : public ROSE_VisitTraversal
{
// DQ (3/7/2010): This class Corrected the documentation for this class.
// Test the declarations to make sure that defining and non-defining appear in
// the same file (for outlining consistency).
public:
const std::set<SgNode*> & constNodeSet;
std::set<SgNode*> & nodeSet;
BuildListOfNodesInAST(const std::set<SgNode*> & s1,std::set<SgNode*> & s2);
void visit ( SgNode* node );
};
class TestForDisconnectedAST
{
// DQ (3/7/2010): This uses the results form the BuildListOfConnectedNodesInAST
// and BuildListOfNodesInAST and identifies the differences.
public:
static void test(SgNode* node);
};
class TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute : AstInheritedAttribute
{
public:
// Use the source file as a way to report better quality errors.
SgSourceFile* sourceFile;
// This will be set as we encounter the SgSourceFile at the top of the AST within the traversal.
bool caseInsensitive;
// Required constructor.
TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute(bool b);
// Required copy constructor.
TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute(const TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute & X);
};
class TestForProperLanguageAndSymbolTableCaseSensitivity : public AstTopDownProcessing<TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute>
{
// DQ (11/28/2010): This class is part of a test to verify consistancy of
// symbol table case sensitivity with languge. C/C++ codes should use only
// case sensitive symbol tables, while Fortran codes should use only case
// insensitive symbol table handling.
public:
// Overloaded pure virtual function.
TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute evaluateInheritedAttribute(SgNode* node, TestForProperLanguageAndSymbolTableCaseSensitivity_InheritedAttribute inheritedAttribute);
// Simple funtion to call to get the traversal started (sets up the inherited attribute, etc.).
static void test(SgNode* node);
};
class TestForReferencesToDeletedNodes : public ROSE_VisitTraversal
{
// DQ (9/26/2011): This class is part of a test to verify consistancy of
// the AST by verifying that no IR node referenced in the AST is a SgNode.
// Note that in a proper AST all IR nodes are derived from an SgNode, but
// that there should be no IR nodes in the AST that are only SgNode types.
// It can happen that a referenced IR nodes will only be able to report
// that it is a SgNode, when this happens it is generally because it is
// and dangling pointer to an IR node that was deleted (at which point
// it can no longer be identified by type to be more than an SgNode).
// So this is a test for references in the AST to IR nodes that have been
// deleted.
private:
int detect_dangling_pointers;
std::string filename;
public:
TestForReferencesToDeletedNodes(int input_detect_dangling_pointers, const std::string & s );
// Overloaded pure virtual function.
void visit( SgNode* node );
// Simple funtion to call to get the traversal started...
static void test( SgProject* project );
};
class TestForParentsMatchingASTStructure: public AstPrePostProcessing
{
// DQ (3/19/2012): This is a test from Robb that I want to use uniformally in the AST.
// This has been used to catch several locations in the AST where parents were not set
// as they are defined to be set in the AST (based on a traversal). So this test is
// an important addition to the EDG 4.3 work to fix a number of the bugs in the EDG 3.3
// work and define a cleaner representation of the AST.
// Check that all nodes have the correct parent. This code is not thread safe.
public:
std::vector<SgNode*> stack; // current path within the AST
#ifndef USE_ROSE
// DQ (3/6/2013): Disable code that is a problem for SWIG (vesion 2.0.9).
// This data member is a problem for SWIG, so ignore it when
// processing using USE_ROSE which we define when using SWIG.
std::ostream &output; // where to emit warning/error messages
#endif
size_t nproblems; // number of problems detected
size_t limit; // number of errors to allow before exit
std::string prefix; // line prefix
public:
explicit TestForParentsMatchingASTStructure(std::ostream &output, const std::string & prefix = "");
bool check(SgNode *ast, size_t limit = 0);
void preOrderVisit(SgNode *node);
void postOrderVisit(SgNode *node);
void show_details_and_maybe_fail(SgNode *node);
// Simple funtion to call to get the traversal started...
static void test( SgProject* project );
};
class TestForSourcePosition: public AstSimpleProcessing
{
// DQ (12/3/2012): This tests for Sg_File_Info objects that have an empty filename.
// These have been set at an early stage in the defelopment of the edg4x work and
// now they are a problem. so it is time to detect them and get rid of them.
public:
void testFileInfo( Sg_File_Info* fileInfo );
void visit ( SgNode* node );
};
class TestForMultipleWaysToSpecifyRestrictKeyword: public AstSimpleProcessing
{
// DQ (12/11/2012): This tests for the two different ways in which const-volitile-restrict
// modifiers can be specified. It is a consiquence of the CV-modifier (SgTypeModifier) being
// a part of the type declaration modifier and also the SgModifierType and the SgDeclarationModifier.
// Both are required and as a result it can be confusing that there are two locations to set
// these. Historically in the EDG 3.3 version we used the SgModifierType for C-V, but the
// SgDeclarationModifier for the restrict keyword. In the edg 4.x version of ROSE, we now want
// to make this more uniform and use the SgModifierType everywhere. To address the inconsistancy,
// we want to check that both are always set consistanly.
public:
void visit ( SgNode* node );
};
// DQ (10/27/2015): This test is part of debugging test2015_97.C which
// is a reduced version of the 600K line ROSEExample_test_01.C file.
// The issue is that we have previously generated a cycle in typedef types
// and so we want to detect these as errors.
class TestAstForCyclesInTypedefs : public ROSE_VisitTraversal
{
// This class uses a traversal to test properties of AST.
// We look for redundent entries anywhere in the AST.
// This test has to save a pointer to ever AST IR node
// that is traversed so it is a bit expensive in memory.
// std::set<SgNode*> astNodeSet;
public:
virtual ~TestAstForCyclesInTypedefs() {};
// Overloaded pure virtual function.
void visit( SgNode* node );
// Simple funtion to call to get the traversal started...
static void test();
};
#if 0
// DQ (10/25/2016): Test traversal to check for basic IR node integrity.
// This is being used to debug merge AST support where it failes on a
// specific version of RH 7.2 OS (only one one machine, hudson-rose-26).
class TestNodes : public ROSE_VisitTraversal
{
public:
void visit ( SgNode* node );
static void test();
};
#endif
#endif