如何在TEXT宏中匹配字符串文字并获得正确的开始/结束位置?

时间:2019-10-16 09:08:27

标签: clang libtooling

我需要用libtooling替换TEXT宏中的字符串文字。例如,在下面的代码段中:

fd_ = CreateFile(TEXT("\\\\.\\") TEXT(PMEM_DEVICE_NAME),
        // Write is needed for IOCTL.
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

如果我用ASTMatcher匹配所有字符串,则getBeginLoc()指向“ TEXT”的第一个T,但是getEndLoc()指向TEXT的最后一个T。

我该如何获取引号之间的内容的源位置?

libTooling中有许多API给出了某些位置,但是关于它们之间差异的文档却很少。

到目前为止,我已经尝试过:

clang::SourceRange LiteralRange = clang::SourceRange(
            ASTRewriter->getSourceMgr().getFileLoc(pLiteral->getBeginLoc()),
            ASTRewriter->getSourceMgr().getFileLoc(pLiteral->getEndLoc())
    );

还有:

bool isMacro = ASTRewriter->getSourceMgr().isMacroBodyExpansion(pLiteral->getBeginLoc());
    bool ReplaceResult;
    std::string Replacement("test");

    if (isMacro) {
        StringRef OrigText = clang::Lexer::getSourceText(CharSourceRange(pLiteral->getSourceRange(), true),
                                                         pContext->getSourceManager(), pContext->getLangOpts());


        if (OrigText.find("TEXT") != std::string::npos) {

            auto EndLoc = clang::Lexer::findLocationAfterToken(LiteralRange.getBegin(), tok::r_paren,
                                                               pContext->getSourceManager(), ASTRewriter->getLangOpts(),
                                                               true);
            LiteralRange.setEnd(ASTRewriter->getSourceMgr().getFileLoc(pLiteral->getEndLoc().getLocWithOffset(-1)));
            LiteralRange.setEnd(EndLoc);
            ASTRewriter->RemoveText(LiteralRange);

            ReplaceResult = ASTRewriter->ReplaceText(LiteralRange, Replacement);

上面的代码片段在某些情况下可以正常工作,但是在大多数情况下,我得到以下信息:

TEXT("something") => test("something"),而我期望TEXT("something")或仅仅是"test"

任何帮助都将不胜感激!

0 个答案:

没有答案