在抽象语法树CDT中包含头文件

时间:2018-05-29 12:51:07

标签: c eclipse-cdt abstract-syntax-tree

问题:我想要生成函数原型,如果它不存在,在C文件中,我已经完成了这个,但是如果原型已经存在于头文件中它感觉不到它,BTW我用过CDT IIndex

//C Code
#include "test.h" //where it have bar prototype
void bar(void)
{
    //function body
}


//Obtaining the AST [JAVA CDT CHECKER]
ITranslationUnit tu = (ITranslationUnit) CDTUITools.getEditorInputCElement(editor.getEditorInput());
String cFilePath = tu.getResource().getFullPath().toString();
ICProject[] allProjects = CoreModel.getDefault().getCModel().getCProjects();
IIndex **index** = CCorePlugin.getIndexManager().getIndex(allProjects);
IASTTranslationUnit ast = null;
try {
    index.acquireReadLock(); // we need a read-lock on the index
    ast = tu.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
} finally {
    index.releaseReadLock();
    ast = null; // don't use the ast after releasing the read-lock
}


//In the AST visitor class
/**
 * extract prototype and store them into 'prototypes' hash set and then rewrite the AST.
 */
@Override
protected int visit(IASTSimpleDeclaration simpleDeclaration) {
    IASTDeclarator[] declarators = simpleDeclaration.getDeclarators();  
    boolean isProtoFuncDeclaration = false;
    for (IASTDeclarator declarator: declarators) {
        if( declarator instanceof IASTFunctionDeclarator)
        {
            isProtoFuncDeclaration = true;
        }
    }   
    if(isProtoFuncDeclaration)
    {
        prototypes.add(simpleDeclaration);
    }
    return super.visit(simpleDeclaration);
}

新C代码的输出

#include "test.h" //where it have bar prototype
void bar(void) <=== I shouldn't be inserted as it is already in the header

void bar(void)
{
    //function body
}

1 个答案:

答案 0 :(得分:0)

我建议如下:

  • 遍历AST以找到您可能想要添加原型的IASTFunctionDefinition
  • 使用getDeclarator().getName()获取函数名称
  • 使用IASTName.resolveBinding()获取功能绑定。
  • 使用IIndex.findDeclarations(IBinding)查找函数的所有声明和定义。
  • 从生成的IIndexName[]中过滤掉定义本身(选中IName.isDefinition())。
  • 进一步过滤列表以显示在包含的头文件中的声明(因为findDeclarations()将返回整个项目中的声明)。您可以通过在AST上调用IASTTranslationUnit.getIndexFileSet()并针对每个IIndexFileSet.contains(name.getFile())检查IIndexName来执行此操作。
  • 如果在此过滤后,列表为空,则表示您需要添加原型。