簡體   English   中英

獲取C ++函數錯誤的名稱

[英]Getting C++ function mangled name

我正在嘗試跟蹤C ++的代碼覆蓋范圍,並且我想指定特定測試涵蓋的功能。 我想要一個宏或模板,該宏或模板為我提供函數的錯誤名稱,因此在測試中,我可以指定覆蓋哪些方法,並將其與生成的coverage信息中的錯誤名稱進行匹配。 我已經擺弄了一段時間,但一直無法使它正常工作。 更喜歡它也適用於重載方法

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

我不知道這是否可以直接回答您的問題,但是這些資源可能會有所幫助:

這就是我最終想出的方法(至少對於clang而言)

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數據中的錯誤名稱進行比較(首先取消對其進行更改)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM