[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] BindingProblems on the StandaloneIndexer

Hi, I'm using the StandaloneIndexer to index code and ran into a
BindingProblem where it can't create a scope.
I think I've narrowed it down the simplest possible case.
I'm not sure if I set things up wrong or not.  It doesn't seem like this
would be a bug in the Indexer itself.
[still not sure if I should be using GeneratedPDOMApplication or not]

I have 4 four files:
  file1.h: trivial class declartation
  file1.cc:  file that implements that class
             It includes file1.h and file2.h
  file2.cc: only includes file1.h
  file2.h: Has a forward declaration of the class

----------------      -----------------
| file1.h       |     | file2.h        |
| class Simple{ |     | class Simple;  |
|    ...        |     |                |
| }             |     |                |
-----------------     ------------------

| file2.cc         |
| #include file1.h |

| file1.cc              |
| #include file1.h      |
| #include file2.h      |
|                       |
| [*] Simple::Simple() { }
[*] error HERE

If I pass file2.cc and file1.cc to the indexer I get these problems:
[with CPPSemantics.traceBindingResolution turned on]

Resolving Simple:105
  Resolving Simple:97
  Resolved  Simple:97 to Simple CPPClassType:9690924
Indexer: unresolved name at /usr/local/clients/repro/file1.cc(5); A scope could not be created to represent the name Simple
  Resolving z:132
Indexer: unresolved name at /usr/local/clients/repro/file1.cc(5); A scope could not be created to represent the name z

If I pass file1.cc before file2.cc, everything works fine.
If I use the "full" indexer everything works fine.

Real Sample files:

#include "file1.h"
#include "file2.h"

Simple::Simple(const char* fname) :z(1) {

#include "file1.h"
#ifndef _FILE1_H
#define _FILE1_H

class Simple {
  Simple(const char* fname);
  int z;

#ifndef _FILE2_H
#define _FILE2_H

class Simple;


I couldn't find any sample code that runs the standalone indexer so here is
my attempt.

To compile/run:
   javac -cp "all_jars_from_eclipse_plugin_dir" MyStandaloneIndexer.java
   java -cp "all_jars_from_eclipse_plugin_dir" MyStandaloneIndexer file2.cc file1.cc

NOTE: that the include path is setup to find file2.h and file1.h in the directory you
run java from or in /tmp.


import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.index.URIRelativeLocationConverter;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.indexer.ILanguageMapper;
import org.eclipse.cdt.internal.core.indexer.IStandaloneScannerInfoProvider;
import org.eclipse.cdt.internal.core.indexer.StandaloneFastIndexer;
import org.eclipse.cdt.internal.core.indexer.StdoutLogService;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCLinkageFactory;
import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkageFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

 * @author rbraunstein@xxxxxxxxxx (Ronald Braunstein)
public class MyStandaloneIndexer extends StandaloneFastIndexer {

  // Used by the cdt to help figure out which internal parsers to use for C, c++ and fortran.
  static HashMap<String, IPDOMLinkageFactory> linkageFactoryMappings =
      new HashMap<String, IPDOMLinkageFactory>();
  static {
    linkageFactoryMappings.put(ILinkage.CPP_LINKAGE_NAME, new PDOMCPPLinkageFactory());

  public static void main(String args[]) throws Exception {
    File writableIndex = new File("/tmp/standaloneIndexFile.pdom");
    MyStandaloneIndexer indexer = new MyStandaloneIndexer(writableIndex);
    ArrayList<String> files = new ArrayList();
    for (String arg : args) {
    indexer.rebuild(files, new MyProgressMonitor());

  public MyStandaloneIndexer(File writableIndexFile) throws Exception {
        new URIRelativeLocationConverter(new URI("file", "/", null)),
        new MyScannerProvider(),
        new MyLanguageMapper(),
        new StdoutLogService());

  static public class MyLanguageMapper implements ILanguageMapper {
    public ILanguage getLanguage(String file) {
      return GPPLanguage.getDefault();

 static public class MyScannerProvider implements IStandaloneScannerInfoProvider {
   MyScannerInfo myInfo = new MyScannerInfo();
   public IScannerInfo getScannerInformation(String path) {
     return myInfo;
    public IScannerInfo getDefaultScannerInformation(int linkageID) {
      return myInfo;

  // NOTE: sets include path to /tmp followed by the current dir.
  static public class MyScannerInfo implements IScannerInfo {
    final String[] includePath = new String[] {
    final Map<String, String> defines = new HashMap<String, String>();
    public Map<String, String> getDefinedSymbols() {
      return defines;
    public String[] getIncludePaths() {
      return includePath;

  // Use NullProgressMonitor if we don't care.
  static public class MyProgressMonitor implements IProgressMonitor {
    public void beginTask(String name, int totalWork) {
      System.out.println("monitor: Beginning task: " + name);
    public void done() {  System.out.println("monitor: DONE"); }
    public void internalWorked(double work) { System.out.println("monitor: internalWorked: " + work); }
    public boolean isCanceled() { return false; }
    public void setCanceled(boolean value) { System.out.println("monitor: setCanceled: " + value); }
    public void setTaskName(String name) { System.out.println("monitor: setTaskName: " + name); }
    public void subTask(String name) { System.out.println("monitor: subtask: " + name); }
    public void worked(int work) { System.out.println("monitor: worked: " + work); }