From f5206c93393de181556806cc5e26d27ab4b0a707 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 16 Aug 2017 09:09:03 +0200 Subject: [PATCH] detect noop casts --- alib2cli/src/ast/params/CastParam.h | 8 +++++++- alib2cli/src/ast/statements/CastStatement.h | 8 +++++++- alib2common/src/abstraction/CastRegistry.hpp | 14 ++++++++++++++ alib2common/src/abstraction/Registry.cpp | 4 ++++ alib2common/src/abstraction/Registry.h | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/alib2cli/src/ast/params/CastParam.h b/alib2cli/src/ast/params/CastParam.h index fc4bba8bc9..66bb2aade9 100644 --- a/alib2cli/src/ast/params/CastParam.h +++ b/alib2cli/src/ast/params/CastParam.h @@ -14,11 +14,17 @@ public: } virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > & prev, Environment & environment ) const override { + std::string type = m_type->eval ( environment ); + std::shared_ptr < abstraction::OperationAbstraction > translatedParam = m_param->translateAndEval ( prev, environment ); + if ( abstraction::Registry::isCastNoOp ( type, translatedParam->getReturnType ( ) ) ) { + return translatedParam; + } + bool normalize; - std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getCastAbstraction ( m_type->eval ( environment ), translatedParam->getReturnType ( ), normalize ); + std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getCastAbstraction ( type, translatedParam->getReturnType ( ), normalize ); res->attachInput ( translatedParam, 0 ); res->eval ( ); diff --git a/alib2cli/src/ast/statements/CastStatement.h b/alib2cli/src/ast/statements/CastStatement.h index 73ff0d7dc0..ff6325f114 100644 --- a/alib2cli/src/ast/statements/CastStatement.h +++ b/alib2cli/src/ast/statements/CastStatement.h @@ -14,11 +14,17 @@ public: } virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > & prev, Environment & environment ) const override { + std::string type = m_type->eval ( environment ); + std::shared_ptr < abstraction::OperationAbstraction > translatedStatement = m_statement->translateAndEval ( prev, environment ); + if ( abstraction::Registry::isCastNoOp ( type, translatedStatement->getReturnType ( ) ) ) { + return translatedStatement; + } + bool normalize; - std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getCastAbstraction ( m_type->eval ( environment ), translatedStatement->getReturnType ( ), normalize ); + std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getCastAbstraction ( type, translatedStatement->getReturnType ( ), normalize ); res->attachInput ( translatedStatement, 0 ); res->eval ( ); diff --git a/alib2common/src/abstraction/CastRegistry.hpp b/alib2common/src/abstraction/CastRegistry.hpp index 3f9ccec3ee..2c5f58b371 100644 --- a/alib2common/src/abstraction/CastRegistry.hpp +++ b/alib2common/src/abstraction/CastRegistry.hpp @@ -105,6 +105,20 @@ public: throw exception::CommonException ( "Entry from " + param + " to " + target + " not available." ); } + static bool isNoOp ( const std::string & target, const std::string & param ) { + std::set < std::string > targetTypes; + if ( alib::namingApi::hasTypes ( target ) ) + targetTypes = ext::transform < std::string > ( alib::namingApi::getTypes ( target ), [ ] ( const ext::type_index & type ) { return ext::to_string ( type ); } ); + else + targetTypes.insert ( target ); + + for ( const std::string & toType : targetTypes ) + if ( param == toType ) + return true; + + return false; + } + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & target, const std::string & param ) { bool normalize; return getAbstraction ( target, param, normalize ); diff --git a/alib2common/src/abstraction/Registry.cpp b/alib2common/src/abstraction/Registry.cpp index bcd193558d..a997f9a36b 100644 --- a/alib2common/src/abstraction/Registry.cpp +++ b/alib2common/src/abstraction/Registry.cpp @@ -42,6 +42,10 @@ std::shared_ptr < abstraction::OperationAbstraction > Registry::getCastAbstracti return CastRegistry::getAbstraction ( target, param, normalize ); } +bool Registry::isCastNoOp ( const std::string & target, const std::string & param ) { + return CastRegistry::isNoOp ( target, param ); +} + std::shared_ptr < abstraction::OperationAbstraction > Registry::getImmediateAbstraction ( const std::string & result, std::string value ) { return ImmediateRegistry::getAbstraction ( result, std::move ( value ) ); } diff --git a/alib2common/src/abstraction/Registry.h b/alib2common/src/abstraction/Registry.h index 6e32c1cece..4b096583fb 100644 --- a/alib2common/src/abstraction/Registry.h +++ b/alib2common/src/abstraction/Registry.h @@ -21,6 +21,7 @@ public: static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes ); static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, bool & unwrap, bool & normalize ); static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( const std::string & target, const std::string & param, bool & normalize ); + static bool isCastNoOp ( const std::string & target, const std::string & param ); static std::shared_ptr < abstraction::OperationAbstraction > getImmediateAbstraction ( const std::string & result, std::string value ); static std::shared_ptr < abstraction::OperationAbstraction > getNormalizeAbstraction ( const std::string & param ); static std::shared_ptr < abstraction::OperationAbstraction > getDowncastAbstraction ( const std::string & concrete, const std::string & base ); -- GitLab