首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clang匹配ostream <<

clang匹配ostream <<
EN

Stack Overflow用户
提问于 2018-01-03 06:28:42
回答 1查看 206关注 0票数 2

我正在尝试为某些涉及流媒体的场景写一个整洁的检查。考虑一下这个简单的函数:

代码语言:javascript
复制
#include <iostream>
#include <stdint.h>

void foo(std::ostream& os, uint8_t i) {
    os << i;
    os << 4 << i;
}

如果我运行clang-query来测试一些匹配器:

代码语言:javascript
复制
$ clang-query foo.cxx --
clang-query> match cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))
// [ ... snip some std library matches ... ]
Match #7:

foo.cxx:5:5: note: "root" binds here
    os << i;
    ^~~~~~~

Match #8:

foo.cxx:6:5: note: "root" binds here
    os << 4 << i;
    ^~~~~~~~~~~~

Match #9:

foo.cxx:6:5: note: "root" binds here
    os << 4 << i;
    ^~~~~~~

这与我在这个程序中对operator<<的3个用法都是一致的。太棒了。但是,如果我尝试为第一个参数添加一个筛选器:

代码语言:javascript
复制
clang-query> match cxxOperatorCallExpr(hasOverloadedOperatorName("<<"), hasArgument(0, expr(hasType(asString("std::ostream")))))

Match #1:

foo.cxx:5:5: note: "root" binds here
    os << i;
    ^~~~~~~

Match #2:

foo.cxx:6:5: note: "root" binds here
    os << 4 << i;
    ^~~~~~~

就这样。它不匹配整个表达式os << 4 << i。为什么不行?该表达式的类型为std::ostream。如果我直接转储AST,我会看到:

代码语言:javascript
复制
|-CXXOperatorCallExpr 0x953f618 <line:6:5, col:16> 'basic_ostream<char, struct std::char_traits<char> >':'class std::basic_ostream<char>' lvalue
| |-ImplicitCastExpr 0x953f600 <col:13> 'basic_ostream<char, struct std::char_traits<char> > &(*)(basic_ostream<char, struct std::char_traits<char> > &, unsigned char)' <FunctionToPointerDecay>
| | `-DeclRefExpr 0x953f5d8 <col:13> 'basic_ostream<char, struct std::char_traits<char> > &(basic_ostream<char, struct std::char_traits<char> > &, unsigned char)' lvalue Function 0x94bcd40 'operator<<' 'basic_ostream<char, struct std::char_traits<char> > &(basic_ostream<char, struct std::char_traits<char> > &, unsigned char)'
| |-CXXOperatorCallExpr 0x953f160 <col:5, col:11> 'std::basic_ostream<char, struct std::char_traits<char> >::__ostream_type':'class std::basic_ostream<char>' lvalue
| | |-ImplicitCastExpr 0x953f148 <col:8> 'std::basic_ostream<char, struct std::char_traits<char> >::__ostream_type &(*)(int)' <FunctionToPointerDecay>
| | | `-DeclRefExpr 0x953f0c0 <col:8> 'std::basic_ostream<char, struct std::char_traits<char> >::__ostream_type &(int)' lvalue CXXMethod 0x94b7740 'operator<<' 'std::basic_ostream<char, struct std::char_traits<char> >::__ostream_type &(int)'
| | |-DeclRefExpr 0x953ec88 <col:5> 'std::ostream':'class std::basic_ostream<char>' lvalue ParmVar 0x953e470 'os' 'std::ostream &'
| | `-IntegerLiteral 0x953ecb0 <col:11> 'int' 4
| `-ImplicitCastExpr 0x953f5c0 <col:16> 'uint8_t':'unsigned char' <LValueToRValue>
|   `-DeclRefExpr 0x953f1a8 <col:16> 'uint8_t':'unsigned char' lvalue ParmVar 0x953e500 'i' 'uint8_t':'unsigned char'

外部和内部CXXOperatorCallExpr都表示它们的表达式是class std::basic_ostream<char> lvalue。正确匹配这个论点的正确方法是什么?

EN

回答 1

Stack Overflow用户

发布于 2018-01-24 05:48:50

这肯定是<<的第一个子调用的返回类型有问题,请参阅下面的匹配器,该匹配器也与"class std::__1::basic_ostream<char>"和缺少的调用进行匹配:

代码语言:javascript
复制
clang-query> match callExpr(hasArgument(0, expr(hasType(anyOf(asString("class std::__1::basic_ostream<char>"), asString("std::ostream"))))))

Match #1:

/Users/ug/clangtest/main.cc:5:5: note: "root" binds here
    os << i;
    ^~~~~~~

Match #2:

/Users/ug/clangtest/main.cc:6:5: note: "root" binds here
    os << 4 << i;
    ^~~~~~~~~~~~

Match #3:

/Users/ug/clangtest/main.cc:6:5: note: "root" binds here
    os << 4 << i;
    ^~~~~~~
3 matches.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48068716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档