1

Problem: I want generate function prototype if it doesn't exists, in the C file, I have done this, but in case if the prototype already exists in a header file it doesn't feel it, BTW I used 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);
}

The output of the new C Code

#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
}
Mostafa Hassan
  • 288
  • 1
  • 14

1 Answers1

1

I would suggest the following:

  • Traverse the AST to find the IASTFunctionDefinition for which you maybe want to add a prototype.
  • Use getDeclarator().getName() to get the function name,
  • Use IASTName.resolveBinding() to get the function binding.
  • Use IIndex.findDeclarations(IBinding) to find all declarations and definitions of the function.
  • From the resulting IIndexName[], filter out the definition itself (check IName.isDefinition()).
  • Further filter the list to declarations that appear in included header files (since findDeclarations() will return declarations in the entire project). You can do this by calling IASTTranslationUnit.getIndexFileSet() on your AST, and checking IIndexFileSet.contains(name.getFile()) for every IIndexName.
  • If after this filtering, the list is empty, you know you need to add a prototype.
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
  • IIndexFileSet indexFileSet = ast.getIndexFileSet(); always be empty ?? so I can not perform if(indexFileSet.contains(funcDeclarations[i].getFile())) – Mostafa Hassan May 31 '18 at 11:15
  • @MostafaHassan: I don't know why the index file set would be empty. I would expect it to get populated during parsing (inside the `getAST()` call) via `CPreprocessor.executeInclude()` [`case FOUND_IN_INDEX`] -> `CPreprocessor.processInclusionFromIndex()` -> `LocationMap.skippedFile()` -> `ASTTranslationUnit.skippedFile()`. If you're in a position to debug the CDT source, you could check what is going wrong in this sequence of calls. – HighCommander4 May 31 '18 at 22:27
  • boolean prototypeFound = false; indexNames = index.findDeclarations(funcBinding); for(int i=0;i – Mostafa Hassan Jun 07 '18 at 08:55