代码之家  ›  专栏  ›  技术社区  ›  Asaf

如何在libclang c++中使用RecursiveASTVisitor提取注释并匹配声明?

  •  16
  • Asaf  · 技术社区  · 12 年前

    我正在编写一个实用程序,它应该解析C++(和C)头文件,提取结构、枚举、字段等,并根据提取的信息生成其他语言的代码。我决定为此使用libclang。

    我正在使用 RecursiveASTVisitor 我似乎能够提取我需要的所有信息,除了评论。

    我希望读取每个声明(字段、结构、类、枚举)正上方的注释,并在用其他语言生成代码时添加其文本。

    问题是我看到的所有使用注释的示例都使用 CxCursor 和C接口,我不知道如何获得 CxCursor公司 在我的背景下。

    所以-我如何在使用时提取评论 递归ASTVisitor ?

    2 回复  |  直到 12 年前
        1
  •  21
  •   Asaf    12 年前

    经过进一步挖掘,我发现:

    对于任何相关访问的Decl( VisitXXXDecl ),我可以这样做:

    virtual bool VisitDecl(Decl* d)
    {
        ASTContext& ctx = d->getASTContext();
        SourceManager& sm = ctx.getSourceManager();
    
        const RawComment* rc = d->getASTContext().getRawCommentForDeclNoCache(d);
        if (rc)
        {
            //Found comment!
            SourceRange range = rc->getSourceRange();
    
            PresumedLoc startPos = sm.getPresumedLoc(range.getBegin());
            PresumedLoc endPos = sm.getPresumedLoc(range.getEnd());
    
            std::string raw = rc->getRawText(sm);
            std::string brief = rc->getBriefText(ctx);
    
            // ... Do something with positions or comments
        }
    
        // ...
    }
    

    请注意,这标识了(据我所见…)代码中当前声明上方(和相邻!)行中的注释,这些注释采用以下格式之一:

    • /// Comment
    • /** Comment */
    • //! Comment

    例如,在以下情况下:

    /// A field with a long long comment
    /// A two-liner
    long long LongLongData;
    

    raw 将:

    /// A field with a long long comment
        /// A two-liner
    

    brief 将:

    A field with a long long comment A two-liner
    

    不管怎样,这都足以满足我的需求。

        2
  •  16
  •   Hemant    9 年前

    上面的答案是完美的。但要使API getRawCommentForDeclNoCache 返回普通注释,如 // or /* 您需要提供选项 “-fparse所有注释” 同时调用clang。因为默认情况下,clang只解析Doxygen风格的注释。