diff --git a/src/Matchers.cpp b/src/Matchers.cpp index b16c88d1a..d9f597c3f 100644 --- a/src/Matchers.cpp +++ b/src/Matchers.cpp @@ -8,54 +8,12 @@ using namespace sc_ast_matchers; // // Helper functions that can be made private to this class. // - -void printTemplateArguments(ModuleDeclarationMatcher::PortType &found_ports) { - // Input ports - for (const auto &i : found_ports) { - llvm::outs() << "name: " << get<0>(i) - << ", FieldDecl*: " << get<1>(i)->getFieldDecl(); - get<1>(i)->getTemplateType()->printTemplateArguments(llvm::outs()); - llvm::outs() << "\n"; - } -} - -auto parseTemplateType(const FieldDecl *fd) { - //}, const ModuleDeclarationMatcher::PortType &found_ports ) { - QualType qual_type{fd->getType()}; - const Type *type_ptr{qual_type.getTypePtr()}; - auto template_ptr{new FindTemplateTypes()}; - template_ptr->Enumerate(type_ptr); - return template_ptr; -} - -template -auto checkMatch(const std::string &name, - const MatchFinder::MatchResult &result) { - return result.Nodes.getNodeAs(name); -} - // AST matcher to detect instances of sc_modules. auto makeInstanceInModuleMatcher(const std::string &name) { auto match_module_instance = fieldDecl( hasType(cxxRecordDecl(isDerivedFrom(hasName("::sc_core::sc_module"))))); return match_module_instance; } - -// AST matcher to detect field declarations -auto makeFieldMatcher(const std::string &name) { - /* clang-format off */ - return cxxRecordDecl( - isExpansionInMainFile(), - isDerivedFrom( - hasName("::sc_core::sc_module") - ), - forEach( - fieldDecl(hasType(cxxRecordDecl(hasName(name)))).bind(name) - ) - ); - /* clang-format on */ -} - // End of helper functions // Register the matchers @@ -71,57 +29,17 @@ auto match_module_decls = ), unless(isDerivedFrom(matchesName("sc_event_queue"))) ); - -auto match_sc_in_clk = cxxRecordDecl( isDerivedFrom(hasName("sc_module")), - forEach( - fieldDecl( - hasType( - namedDecl( - hasName("sc_in_clk") - ) - ) - ).bind("sc_in_clk") - ) - ); - -auto match_non_sc_types = cxxRecordDecl( - match_module_decls, - forEach( - fieldDecl( - allOf( - unless(hasType(cxxRecordDecl(matchesName("sc*")))), - unless(hasType(namedDecl(hasName("sc_in_clk")))) - ) - ).bind("other_fields") - ) - ); - /* clang-format on */ - auto match_in_ports = makeFieldMatcher("sc_in"); - auto match_out_ports = makeFieldMatcher("sc_out"); - auto match_in_out_ports = makeFieldMatcher("sc_inout"); - auto match_internal_signal = makeFieldMatcher("sc_signal"); - // add all the matchers. finder.addMatcher(match_module_decls.bind("sc_module"), this); // add instance matcher instance_matcher.registerMatchers(finder); - finder.addMatcher(match_sc_in_clk, this); - finder.addMatcher(match_in_ports, this); - finder.addMatcher(match_out_ports, this); - finder.addMatcher(match_in_out_ports, this); - finder.addMatcher(match_internal_signal, this); - finder.addMatcher(match_non_sc_types, this); -} + // add port (field) matcher + port_matcher.registerMatchers(finder); -template -void ModuleDeclarationMatcher::insert_port(PortType &port, T *decl) { - auto name{decl->getIdentifier()->getNameStart()}; - port.push_back( - std::make_tuple(name, new PortDecl(name, decl, parseTemplateType(decl)))); } void ModuleDeclarationMatcher::run(const MatchFinder::MatchResult &result) { @@ -145,43 +63,6 @@ void ModuleDeclarationMatcher::run(const MatchFinder::MatchResult &result) { instance_registry.match(*decl, *result.Context); */ } - - if (auto fd = checkMatch("sc_in_clk", result)) { - std::string port_name{fd->getIdentifier()->getNameStart()}; - cout << " Found sc_in_clk: " << port_name << endl; - - insert_port(clock_ports_, fd); - } - - if (auto fd = checkMatch("sc_in", result)) { - auto port_name{fd->getIdentifier()->getNameStart()}; - cout << " Found sc_in: " << port_name << endl; - insert_port(in_ports_, fd); - } - - if (auto fd = checkMatch("sc_out", result)) { - auto port_name{fd->getIdentifier()->getNameStart()}; - cout << " Found sc_out: " << port_name << endl; - insert_port(out_ports_, fd); - } - - if (auto fd = checkMatch("sc_inout", result)) { - auto port_name{fd->getIdentifier()->getNameStart()}; - cout << " Found sc_inout: " << port_name << endl; - insert_port(inout_ports_, fd); - } - - if (auto fd = checkMatch("sc_signal", result)) { - auto signal_name{fd->getIdentifier()->getNameStart()}; - cout << " Found sc_signal: " << signal_name << endl; - insert_port(signal_fields_, fd); - } - - if (auto fd = checkMatch("other_fields", result)) { - auto field_name{fd->getIdentifier()->getNameStart()}; - cout << " Found others fields: " << field_name << endl; - insert_port(other_fields_, fd); - } } void ModuleDeclarationMatcher::pruneMatches() { @@ -265,10 +146,5 @@ void ModuleDeclarationMatcher::dump() { cout << "\n"; cout << "## Printing ports" << endl; - printTemplateArguments(clock_ports_); - printTemplateArguments(in_ports_); - printTemplateArguments(out_ports_); - printTemplateArguments(inout_ports_); - printTemplateArguments(signal_fields_); - printTemplateArguments(other_fields_); + port_matcher.dump(); } diff --git a/src/Matchers.h b/src/Matchers.h index 7df54ca5a..4cd3853d4 100644 --- a/src/Matchers.h +++ b/src/Matchers.h @@ -15,10 +15,12 @@ using namespace scpar; namespace sc_ast_matchers { +/////////////////////////////////////////////////////////////////////////////// // -// InstanceMatcher +// Class InstanceMatcher // // +/////////////////////////////////////////////////////////////////////////////// class InstanceMatcher : public MatchFinder::MatchCallback { public: typedef std::tuple InstanceDeclType; @@ -148,67 +150,192 @@ class InstanceMatcher : public MatchFinder::MatchCallback { } } } +}; +/////////////////////////////////////////////////////////////////////////////// +// Class PortMatcher +// +// +/////////////////////////////////////////////////////////////////////////////// -}; // namespace sc_ast_matchers +class PortMatcher : public MatchFinder::MatchCallback { + public: + typedef std::vector > PortType; + + private: + PortType clock_ports_; + PortType in_ports_; + PortType out_ports_; + PortType inout_ports_; + PortType other_fields_; + PortType signal_fields_; -// FieldMatcher class -class FieldMatcher : public MatchFinder::MatchCallback { public: - void registerMatchers(MatchFinder &finder) { + // AST matcher to detect field declarations + auto makeFieldMatcher(const std::string &name) { /* clang-format off */ - auto match_module_decls = cxxRecordDecl( - // isExpansionInMainFile(), - isDerivedFrom(hasName("::sc_core::sc_module")), - unless(isDerivedFrom(matchesName("sc_event_queue")))); + return cxxRecordDecl( + isExpansionInMainFile(), + isDerivedFrom( + hasName("::sc_core::sc_module") + ), + forEach( + fieldDecl(hasType(cxxRecordDecl(hasName(name)))).bind(name) + ) + ); + /* clang-format on */ + } + + void printTemplateArguments(PortType &found_ports) { + // Input ports + for (const auto &i : found_ports) { + llvm::outs() << "name: " << get<0>(i) + << ", FieldDecl*: " << get<1>(i)->getFieldDecl(); + get<1>(i)->getTemplateType()->printTemplateArguments(llvm::outs()); + llvm::outs() << "\n"; + } + } - auto match_in_ports = cxxRecordDecl(forEach( - fieldDecl(hasType(cxxRecordDecl(hasName("sc_in")))).bind("sc_in"))); + auto parseTemplateType(const FieldDecl *fd) { + //}, const ModuleDeclarationMatcher::PortType &found_ports ) { + QualType qual_type{fd->getType()}; + const Type *type_ptr{qual_type.getTypePtr()}; + auto template_ptr{new FindTemplateTypes()}; + template_ptr->Enumerate(type_ptr); + return template_ptr; + } + + template + void insert_port(PortType &port, T *decl) { + auto name{decl->getIdentifier()->getNameStart()}; + port.push_back(std::make_tuple( + name, new PortDecl(name, decl, parseTemplateType(decl)))); + } + template + auto checkMatch(const std::string &name, + const MatchFinder::MatchResult &result) { + return result.Nodes.getNodeAs(name); + } + + void registerMatchers(MatchFinder &finder) { /* clang-format off */ + auto match_sc_in_clk = cxxRecordDecl( isDerivedFrom(hasName("sc_module")), + forEach( + fieldDecl( + hasType( + namedDecl( + hasName("sc_in_clk") + ) + ) + ).bind("sc_in_clk") + ) + ); + auto match_module_decls = + cxxRecordDecl( + hasDefinition(), // There must be a definition. + unless( isImplicit() ), // Templates generate implicit structs - so ignore. + isDerivedFrom( + hasName("::sc_core::sc_module") + ), + unless(isDerivedFrom(matchesName("sc_event_queue"))) + ); + + auto match_non_sc_types = cxxRecordDecl( + match_module_decls, + forEach( + fieldDecl( + allOf( + unless(hasType(cxxRecordDecl(matchesName("sc*")))), + unless(hasType(namedDecl(hasName("sc_in_clk")))) + ) + ).bind("other_fields") + ) + ); + /* clang-format on */ + + auto match_in_ports = makeFieldMatcher("sc_in"); + auto match_out_ports = makeFieldMatcher("sc_out"); + auto match_in_out_ports = makeFieldMatcher("sc_inout"); + auto match_internal_signal = makeFieldMatcher("sc_signal"); + finder.addMatcher(match_in_ports, this); + finder.addMatcher(match_out_ports, this); + finder.addMatcher(match_in_out_ports, this); + finder.addMatcher(match_internal_signal, this); + finder.addMatcher(match_sc_in_clk, this); + finder.addMatcher(match_non_sc_types, this); } virtual void run(const MatchFinder::MatchResult &result) { - cout << " Trying to find sc_in. " << endl; - if (auto field_decl = const_cast( - result.Nodes.getNodeAs("sc_in"))) { - std::string name{field_decl->getIdentifier()->getNameStart()}; - cout << " Found an sc_in : " << name << endl; - input_port_names.push_back(name); + if (auto fd = checkMatch("sc_in_clk", result)) { + std::string port_name{fd->getIdentifier()->getNameStart()}; + cout << " Found sc_in_clk: " << port_name << endl; + + insert_port(clock_ports_, fd); + } + + if (auto fd = checkMatch("sc_in", result)) { + auto port_name{fd->getIdentifier()->getNameStart()}; + cout << " Found sc_in: " << port_name << endl; + insert_port(in_ports_, fd); + } + + if (auto fd = checkMatch("sc_out", result)) { + auto port_name{fd->getIdentifier()->getNameStart()}; + cout << " Found sc_out: " << port_name << endl; + insert_port(out_ports_, fd); + } + + if (auto fd = checkMatch("sc_inout", result)) { + auto port_name{fd->getIdentifier()->getNameStart()}; + cout << " Found sc_inout: " << port_name << endl; + insert_port(inout_ports_, fd); + } + + if (auto fd = checkMatch("sc_signal", result)) { + auto signal_name{fd->getIdentifier()->getNameStart()}; + cout << " Found sc_signal: " << signal_name << endl; + insert_port(signal_fields_, fd); + } + + if (auto fd = checkMatch("other_fields", result)) { + auto field_name{fd->getIdentifier()->getNameStart()}; + cout << " Found others fields: " << field_name << endl; + insert_port(other_fields_, fd); } } - public: - std::vector input_port_names; + void dump() { + printTemplateArguments(clock_ports_); + printTemplateArguments(in_ports_); + printTemplateArguments(out_ports_); + printTemplateArguments(inout_ports_); + printTemplateArguments(signal_fields_); + printTemplateArguments(other_fields_); + } }; - /////////////////////////////////////////////////////////////////////////////// // Class ModuleDeclarationMatcher // // +/////////////////////////////////////////////////////////////////////////////// class ModuleDeclarationMatcher : public MatchFinder::MatchCallback { // public: typedef std::vector > ModuleDeclarationType; // Map to hold CXXREcordDecl to module declaration type name. - typedef std::pair< CXXRecordDecl*, std::string > ModuleDeclarationPairType; - typedef std::map< CXXRecordDecl*, std::string > ModuleDeclarationMapType; - - typedef std::vector > PortType; + typedef std::pair ModuleDeclarationPairType; + typedef std::map ModuleDeclarationMapType; - //typedef std::tuple InstanceDeclType; + // typedef std::tuple InstanceDeclType; typedef std::vector InstanceListType; - typedef std::pair DeclarationInstancePairType; - typedef std::map< CXXRecordDecl*, InstanceListType > DeclarationsToInstancesMapType; - - private: - // Template functions. - template - void insert_port( PortType & port, T *decl ); - + typedef std::pair + DeclarationInstancePairType; + typedef std::map + DeclarationsToInstancesMapType; private: ModuleDeclarationType found_declarations_; ModuleDeclarationType found_template_declarations_; @@ -218,21 +345,16 @@ class ModuleDeclarationMatcher : public MatchFinder::MatchCallback { DeclarationsToInstancesMapType declaration_instance_map_; - // Match nested instances - InstanceMatcher instance_matcher; - - // Ports - PortType clock_ports_; - PortType in_ports_; - PortType out_ports_; - PortType inout_ports_; - PortType other_fields_; - PortType signal_fields_; + InstanceMatcher instance_matcher; + // Match ports + PortMatcher port_matcher; public: - const DeclarationsToInstancesMapType & getInstances() { return declaration_instance_map_; }; + const DeclarationsToInstancesMapType &getInstances() { + return declaration_instance_map_; + }; void registerMatchers(MatchFinder &finder); virtual void run(const MatchFinder::MatchResult &result); const ModuleDeclarationMapType &getFoundModuleDeclarations() const {