获取 CXCursor_BinaryOperator 的运算符类型

问题描述 投票:0回答:2

我正在尝试在 C++ 源文件中查找作业:

x = 10;

我正在使用 libclang 来解析它并遍历 AST。有一个

CXCursor_BinaryOperator
代表二元运算符。有没有办法确定它是赋值还是任何其他二元运算符(如
+
<=
!=
)?如果不是,那么我如何确定表达式是否是赋值?

提前致谢。

c++ clang abstract-syntax-tree libclang
2个回答
2
投票

适用于 Clang 17 或更高版本

从 Clang 17 开始,可以使用

clang_getCursorBinaryOperatorKind()
来获取此信息。

历史信息:该问题于 2016 年首次提交为 issue 29138。它在提交7fbc9de455中得到修复,并流入 Clang 17.0.1,并于 2023-09-09 发布。

适用于 Clang 16 及更早版本

(这是最初的答案,仍然适用于 Clang 17 作为如何获取令牌的演示,尽管获取二进制表达式的运算符的特定任务不再需要它。)

@notetau 的答案只是搜索带有文本

=
的任何标记,但是当该标记出现在表达式中而不是顶层的某个位置时,就会失败。

这是一个获取左侧操作数中所有标记之后第一个标记的文本的版本:

// Get the first child of 'cxNode'.
static CXCursor getFirstChild(CXCursor cxNode)
{
  struct Result {
    CXCursor child;
    bool found;
  } result;
  result.found = false;

  clang_visitChildren(cxNode,
    [](CXCursor c, CXCursor parent, CXClientData client_data) {
      Result *r = (Result*)client_data;
      r->found = true;
      r->child = c;
      return CXChildVisit_Break;
    },
    &result);

  assert(result.found);
  return result.child;
}

// Get the operator of binary expression 'cxExpr' as a string.
std::string getBinaryOperator(CXTranslationUnit cxTU, CXCursor cxExpr)
{
  // Get tokens in 'cxExpr'.
  CXToken *exprTokens;
  unsigned numExprTokens;
  clang_tokenize(cxTU, clang_getCursorExtent(cxExpr),
    &exprTokens, &numExprTokens);

  // Get tokens in its left-hand side.
  CXCursor cxLHS = getFirstChild(cxExpr);
  CXToken *lhsTokens;
  unsigned numLHSTokens;
  clang_tokenize(cxTU, clang_getCursorExtent(cxLHS),
    &lhsTokens, &numLHSTokens);

  // Get the spelling of the first token not in the LHS.
  assert(numLHSTokens < numExprTokens);
  CXString cxString = clang_getTokenSpelling(cxTU,
    exprTokens[numLHSTokens]);
  std::string ret(clang_getCString(cxString));

  // Clean up.
  clang_disposeString(cxString);
  clang_disposeTokens(cxTU, lhsTokens, numLHSTokens);
  clang_disposeTokens(cxTU, exprTokens, numExprTokens);

  return ret;
}

但是,在某些涉及宏的情况下,即使这样也会失败,例如:

#define MINUS -
int f(int a, int b)
{
  return a MINUS b;
}

对于这段代码,

getBinaryOperator
将返回
MINUS
,除了首先进行预处理(作为单独的步骤),然后将预处理后的输出传递给
clang
进行进一步分析之外,我还没有找到任何解决该问题的方法.


1
投票

以下代码可能适合您:

  CXToken *tokens;
  unsigned numTokens;
  CXSourceRange range = clang_getCursorExtent(cursor);
  clang_tokenize(tu, range, &tokens, &numTokens);
  for(unsigned i=0; i<numTokens; i++) {
    CXString s = clang_getTokenSpelling(tu, tokens[i]);
    const char* str = clang_getCString(s);
    if( strcmp(str, "=") == 0 ) {
      /* found */
    }
    clang_disposeString(s);
  }
  clang_disposeTokens(tu, tokens, numTokens);
© www.soinside.com 2019 - 2024. All rights reserved.