diff --git a/src/Matchers.h b/src/Matchers.h index 3f54ef9e6..91871ee78 100644 --- a/src/Matchers.h +++ b/src/Matchers.h @@ -8,8 +8,8 @@ #include "PortDecl.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/ASTMatchers/ASTMatchersMacros.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" using namespace clang; using namespace clang::ast_matchers; @@ -23,7 +23,6 @@ auto checkMatch(const std::string &name, return result.Nodes.getNodeAs(name); } - /* AST_MATCHER_P(CXXCtorInitializer, forField, internal::Matcher, InnerMatcher) { @@ -32,12 +31,38 @@ auto checkMatch(const std::string &name, InnerMatcher.matches(*NodeAsDecl, Finder, Builder)); } */ - + AST_MATCHER(FieldDecl, matchesTypeName) { - auto type_ptr { Node.getType().getTypePtr()}; + auto type_ptr{Node.getType().getTypePtr()}; llvm::outs() << "[[OWN MATCHER]]\n"; - type_ptr->dump(); - return true; + Node.dump(); + + if ((type_ptr == nullptr) || (type_ptr->isBuiltinType())) { + type_ptr->dump(); + return true; + } else { + FindTemplateTypes te; + te.Enumerate(type_ptr); + te.printTemplateArguments(llvm::outs()); + + auto args{te.getTemplateArgumentsType()}; + FindTemplateTypes::argVectorType::iterator ait{args.begin()}; + + if (args.size() == 0) { + return true; + } + + string field_type{ait->getTypeName()}; + llvm::outs() << "\n@@@@@ Field type: " << field_type << "\n"; + + if ((field_type != "sc_in") && (field_type != "sc_out") && + (field_type != "sc_signal") && (field_type != "sc_stream_in") && + (field_type != "sc_stream_out")) { + return true; + } else { + return false; + } + } }; /////////////////////////////////////////////////////////////////////////////// @@ -86,6 +111,7 @@ class InstanceMatcher : public MatchFinder::MatchCallback { return (rt == decl); } } + return false; }); if (found_it != instances_.end()) { @@ -332,14 +358,14 @@ class PortMatcher : public MatchFinder::MatchCallback { .bind("sc_out")), forEach(fieldDecl(hasType(cxxRecordDecl(hasName("sc_inout")))) .bind("sc_inout")), - forEach(fieldDecl( - hasType(cxxRecordDecl(isDerivedFrom(hasName("sc_signal_inout_if")))) - ).bind("sc_signal")), + forEach(fieldDecl(anyOf(hasType(arrayType()), + hasType(cxxRecordDecl(isDerivedFrom( + hasName("sc_signal_inout_if")))))) + .bind("sc_signal")), forEach(fieldDecl(hasType(cxxRecordDecl(hasName("sc_stream_in")))) .bind("sc_stream_in")), forEach(fieldDecl(hasType(cxxRecordDecl(hasName("sc_stream_out")))) - .bind("sc_stream_out")) - ) + .bind("sc_stream_out"))) // classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl())) /* @@ -354,20 +380,15 @@ class PortMatcher : public MatchFinder::MatchCallback { */ ); - auto match_non_sc_types = cxxRecordDecl( - forEachDescendant( - fieldDecl( - anyOf(hasType(builtinType()), - hasType(cxxRecordDecl( - allOf( - unless(hasName("sc_in")), - unless(hasName("sc_inout")), - unless(hasName("sc_out")), - unless(hasName("sc_signal")), - unless(hasName("sc_stream_in")), - unless(hasName("sc_stream_out")) - ))))).bind("other_fields")) - ); + auto match_non_sc_types = cxxRecordDecl(forEachDescendant( + fieldDecl( + anyOf(hasType(builtinType()), + hasType(cxxRecordDecl(allOf( + unless(hasName("sc_in")), unless(hasName("sc_inout")), + unless(hasName("sc_out")), unless(hasName("sc_signal")), + unless(hasName("sc_stream_in")), + unless(hasName("sc_stream_out"))))))) + .bind("other_fields"))); // unless( // forEach(fieldDecl(hasType(cxxRecordDecl(hasName("sc_signal")))))), @@ -389,14 +410,14 @@ class PortMatcher : public MatchFinder::MatchCallback { finder.addMatcher(match_stream_in_ports, this); finder.addMatcher(match_stream_out_ports, this); */ - //finder.addMatcher(match_all_ports, this); - //finder.addMatcher(match_non_sc_types, this); - - + finder.addMatcher(match_all_ports, this); + finder.addMatcher(match_non_sc_types, this); +// // test own matcher - auto matcher_test = cxxRecordDecl(forEachDescendant(fieldDecl(matchesTypeName()).bind("other_fields"))); - finder.addMatcher(matcher_test, this); - + // auto matcher_test = cxxRecordDecl( + // forEachDescendant(fieldDecl(matchesTypeName()).bind("other_fields"))); +// + // finder.addMatcher(matcher_test, this); } virtual void run(const MatchFinder::MatchResult &result) { @@ -434,8 +455,8 @@ class PortMatcher : public MatchFinder::MatchCallback { auto field_name{fd->getIdentifier()->getNameStart()}; llvm::outs() << " Found other_fields: " << field_name << "\n"; insert_port(other_fields_, fd); - llvm::outs() << "WHOA dump\n"; - fd->dump(); + //llvm::outs() << "WHOA dump\n"; + //fd->dump(); } if (auto fd = checkMatch("sc_stream_in", result)) { @@ -579,10 +600,10 @@ class ModuleDeclarationMatcher : public MatchFinder::MatchCallback { // specializations or not. // if (isa(decl)) { - //llvm::outs() << "TEMPLATE SPECIAL\n"; + // llvm::outs() << "TEMPLATE SPECIAL\n"; found_template_declarations_.push_back(std::make_tuple(name, decl)); } else { - //llvm::outs() << "NOT TEMPLATE SPECIAL\n"; + // llvm::outs() << "NOT TEMPLATE SPECIAL\n"; found_declarations_.push_back(std::make_tuple(name, decl)); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 12cd287e3..be08b0824 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,8 +16,8 @@ file(COPY ../examples/llnl-examples DESTINATION ${CMAKE_BINARY_DIR}/tests/data ) set( UNIT_TEST_LIST # t1 # t2 - # t3 - # sreg-test + t3 + sreg-test # t4-matchers t5-template-matching # subtree-matcher-test diff --git a/tests/data/templated-module.cpp b/tests/data/templated-module.cpp index 0c42af5a4..a3ec1f278 100644 --- a/tests/data/templated-module.cpp +++ b/tests/data/templated-module.cpp @@ -35,6 +35,11 @@ SC_MODULE( test ){ sc_signal not_data_array[10]; + // These are all others + static const int ORDER = 5; + static const double c[ORDER+1]; + sc_buffer i[ORDER]; + // FieldDecl of an sc_module //non_template simple_module; diff --git a/tests/matchers/match-structural.cmd.cpp b/tests/matchers/match-structural.cmd.cpp index 661cf73e4..a589dc9a3 100644 --- a/tests/matchers/match-structural.cmd.cpp +++ b/tests/matchers/match-structural.cmd.cpp @@ -63,4 +63,6 @@ set output dump #m cxxRecordDecl(forEachDescendant(fieldDecl(hasName("array_signal")))) -m cxxRecordDecl(isExpansionInMainFile(), forEach(fieldDecl(hasType(arrayType())))) +#m cxxRecordDecl(isExpansionInMainFile(), forEach(fieldDecl(hasType(arrayType())))) + +m cxxRecordDecl(isExpansionInMainFile(), isDerivedFrom(hasName("::sc_core::sc_module"))).bind("sc_module") diff --git a/tests/t3.cpp b/tests/t3.cpp index dc93d7f44..ca1e4365c 100644 --- a/tests/t3.cpp +++ b/tests/t3.cpp @@ -43,5 +43,17 @@ TEST_CASE("Read SystemC model from file for testing", "[parsing]") { "FAIL_TEST: A module must have a port bound for it to be " "recognized."); REQUIRE(test_module != module_decl.end()); + auto module_ptr{ test_module->second}; + + REQUIRE(module_ptr->getInstanceName() == "testing"); + + REQUIRE(module_ptr->getIPorts().size() == 2); + REQUIRE(module_ptr->getOPorts().size() == 1); + REQUIRE(module_ptr->getIOPorts().size() == 0); + REQUIRE(module_ptr->getSignals().size() == 1); + REQUIRE(module_ptr->getOtherVars().size() == 0); + REQUIRE(module_ptr->getInputStreamPorts().size() == 0); + REQUIRE(module_ptr->getOutputStreamPorts().size() == 0); + } } diff --git a/tests/t5-template-matching.cpp b/tests/t5-template-matching.cpp index de4dfe279..8d5c99c50 100644 --- a/tests/t5-template-matching.cpp +++ b/tests/t5-template-matching.cpp @@ -154,7 +154,8 @@ TEST_CASE("Testing top-level module: test", "[top-module]") { auto found_decl{found_module_testing->second}; REQUIRE(found_decl->getIPorts().size() == 4); REQUIRE(found_decl->getOPorts().size() == 1); - REQUIRE(found_decl->getSignals().size() == 1); + // This is 4 because sc_buffer is also inheriting from the signal interface. + REQUIRE(found_decl->getSignals().size() == 4); REQUIRE(found_decl->getOtherVars().size() == 0); // TODO: Check the template parameters. @@ -163,7 +164,8 @@ TEST_CASE("Testing top-level module: test", "[top-module]") { auto found_decl2{found_module_testing_float->second}; REQUIRE(found_decl2->getIPorts().size() == 4); REQUIRE(found_decl2->getOPorts().size() == 1); - REQUIRE(found_decl2->getSignals().size() == 1); + // 1 regular signal, 2 array signals, 1 sc_buffer, which is a signal too. + REQUIRE(found_decl2->getSignals().size() == 4); REQUIRE(found_decl2->getOtherVars().size() == 0); // TODO: Check the template parameters.