获取C ++函数名称错误

时间:2018-03-12 07:44:08

标签: c++ clang code-coverage

我正在尝试跟踪C ++的代码覆盖率,我想指定特定测试涵盖的功能。我想有一个宏或模板,它给我功能的错位名称,所以在测试中我可以指定涵盖哪些方法,我可以将其与生成的覆盖信息中的错位名称相匹配。我已经摆弄了一段时间,但却无法让它发挥作用。更喜欢它也适用于重载方法

COVERS_BEGIN_FUNCTIONS
  COVERS_CLASS_FUNCTION( atestfile::aFunction( int ) );
COVERS_END_FUNCTIONS

2 个答案:

答案 0 :(得分:0)

我不知道这是否会直接回答您的问题,但这些资源可能会有所帮助:

答案 1 :(得分:0)

这是我最终提出的似乎有效(至少对于铿锵声)

namespace testing {
    namespace coverage {
    inline std::string toString( const std::list<std::string> &list ) {
      std::ostringstream out;
      bool first = true;
      for ( const auto &item : list ) {
        if ( first ) {
          first = false;
        } else {
          out << std::endl;
        }
        out << item;
      }
      return out.str();
    }

    template<typename T> struct returnExtract { typedef void type; };
    template<typename R, typename...A> struct returnExtract<R( A... )> { typedef R type; };
    template<typename...> struct argsExtract { static std::string toString() { return std::string(); } };
    template<typename T, typename Y, typename... A> struct argsExtract<T, Y, A...> {
      static std::string toString() {
        return boost::core::demangled_name( typeid( T ) ) + ", " + argsExtract<Y, A...>::toString();
      }
    };
    template<typename T> struct argsExtract<T> { static std::string toString() { return boost::core::demangled_name( typeid( T ) ); } };
    template<typename T, typename... A> struct argsExtract<T( A... )> { static std::string toString() { return argsExtract<A...>::toString(); } };
    template<typename T> struct argsExtract<T()> { static std::string toString() { return std::string(); } };

    std::string functionComponentsToString( const std::type_info &returnType, const std::type_info &classType, const char *functionName,
                                            const std::string &argumentTypes, const std::string &templateArguments = std::string() ) {
      std::ostringstream rt;
      if ( not templateArguments.empty() ) {
        rt << boost::core::demangled_name( returnType ) << " ";
      }
      rt << boost::core::demangled_name( classType ) << "::" << functionName;
      if ( not templateArguments.empty() ) {
        rt << "<" << templateArguments << ">";
      }
      rt << "(" << argumentTypes << ")";
      return rt.str();
    }

    template<typename... X> struct functionCheck {};
    template<typename A, typename B, typename... C> struct functionCheck<A, B( C... )> { inline static void func( B (A::*)( C... ) ) {} };
  }
}

#define COVERS_BEGIN_FUNCTIONS { \
  std::list<std::string> functions;
#define COVERS_CLASS_FUNCTION( c, n, s ) \
  functions.emplace_back( testing::coverage::functionComponentsToString( typeid( testing::coverage::returnExtract<s>::type ), typeid( c ), #n, testing::coverage::argsExtract<s>::toString() ) ); \
  testing::coverage::functionCheck<c,s>::func( &c::n );
#define COVERS_CLASS_FUNCTION_T( c, n, s, t... ) \
  functions.emplace_back( testing::coverage::functionComponentsToString( typeid( testing::coverage::returnExtract<s>::type ), typeid( c ), #n, testing::coverage::argsExtract<s>::toString(), testing::coverage::argsExtract<t>::toString() ) ); \
  testing::coverage::functionCheck<c,s>::func( &c::n<t> );
#define COVERS_END_FUNCTIONS RecordProperty("COVERS_FUNCTIONS", testing::coverage::toString(functions) ); \
}

这允许我放

  COVERS_BEGIN_FUNCTIONS
    COVERS_CLASS_FUNCTION( atestfile, aFunction, int( const char *) );
    COVERS_CLASS_FUNCTION_T( atestfile, aTestFunction, void( int ), int );
    COVERS_CLASS_FUNCTION_T( atestfile, aTestFunction, void( const char* ), const char* );
  COVERS_END_FUNCTIONS

在使用换行符分隔的函数签名字符串调用RecordProperty的测试用例中,我可以将其与c​​overage数据中的错位名称进行比较(首先解开它们)