Esempio n. 1
0
int main(int argc, char *argv[]) 
{
  CXIndex Index = clang_createIndex(0, 0);
  
  CXTranslationUnit TU;
  
  TU = clang_parseTranslationUnit(Index, 0, 
                                  (const char**)argv, argc, 
                                  0, 0, CXTranslationUnit_None);
  
        
  CXCodeCompleteResults *results = clang_codeCompleteAt(TU, argv[1], 20, 7, NULL, 0, clang_defaultCodeCompleteOptions());
      
     
  unsigned i;
  for(i =0; i<results->NumResults; i++)
    {
      printf("%s",results->Results[i].CompletionString);
    }
   
    
  //            clang_disposeString(String);
  
  clang_disposeCodeCompleteResults(results);
  clang_disposeTranslationUnit(TU);
  clang_disposeIndex(Index);
 
  return 0;
}
Esempio n. 2
0
const char* libclang_vim::at_specific_location(
    const location_tuple& location_tuple,
    const std::function<std::string(CXCursor const&)>& predicate) {
    static std::string vimson;
    char const* file_name = location_tuple.file.c_str();
    auto const args_ptrs = get_args_ptrs(location_tuple.args);

    cxindex_ptr index =
        clang_createIndex(/*excludeDeclsFromPCH*/ 1, /*displayDiagnostics*/ 0);
    std::vector<CXUnsavedFile> unsaved_files =
        create_unsaved_files(location_tuple);
    cxtranslation_unit_ptr translation_unit(clang_parseTranslationUnit(
        index, file_name, args_ptrs.data(), args_ptrs.size(),
        unsaved_files.data(), unsaved_files.size(),
        CXTranslationUnit_Incomplete));
    if (!translation_unit)
        return "{}";

    CXFile file = clang_getFile(translation_unit, file_name);
    auto const location = clang_getLocation(
        translation_unit, file, location_tuple.line, location_tuple.col);
    CXCursor const cursor = clang_getCursor(translation_unit, location);

    vimson = predicate(cursor);

    return vimson.c_str();
}
TranslationUnit::TranslationUnit(
    CXIndex index
  , const KUrl& filename_url
  , const clang::compiler_options& options
  , const unsigned parse_options
  , const clang::unsaved_files_list& unsaved_files
  )
  : m_filename(filename_url.toLocalFile().toUtf8())
{
    kDebug(DEBUG_AREA) << "Parsing a translation unit: " << filename_url.toLocalFile();
    kDebug(DEBUG_AREA) << "w/ the following compiler options:" << options;

    auto files = unsaved_files.get();
    auto clang_options = options.get();
    // Ok, ready to parse
    m_unit = clang_parseTranslationUnit(
        index
      , m_filename.constData()
      , clang_options.data()
      , clang_options.size()
      , files.data()
      , files.size()
      , parse_options
      );
    if (!m_unit)
        throw Exception::ParseFailure(
            i18nc("@item:intext", "Failure to parse C++ code").toAscii().constData()
          );
    updateDiagnostic();
}
Esempio n. 4
0
    std::string tokenize_as_vimson(char const* const* args, size_t const argc)
    {
        CXIndex index = clang_createIndex(/*excludeDeclsFromPCH*/ 1, /*displayDiagnostics*/0);

        translation_unit = clang_parseTranslationUnit(index, file_name.c_str(), args, argc, NULL, 0, CXTranslationUnit_Incomplete);
        if (translation_unit == NULL) {
            clang_disposeIndex(index);
            return "{}";
        }
        auto file_range = get_range_whole_file();
        if (clang_Range_isNull(file_range)) {
            clang_disposeTranslationUnit(translation_unit);
            clang_disposeIndex(index);
            return "{}";
        }

        CXToken *tokens_;
        unsigned int num_tokens;
        clang_tokenize(translation_unit, file_range, &tokens_, &num_tokens);
        std::vector<CXToken> tokens(tokens_, tokens_ + num_tokens);

        auto result = make_vimson_from_tokens(tokens);

        clang_disposeTokens(translation_unit, tokens_, num_tokens);
        clang_disposeTranslationUnit(translation_unit);
        clang_disposeIndex(index);

        return result;
    }
Esempio n. 5
0
CXTranslationUnit CodeFile::ParseTranslationUnit() {

   /* if (translationUnit) {
        clang_disposeTranslationUnit(translationUnit);
    }
    */

    std::vector<const char*> arguments;
    arguments.push_back("c++");
    arguments.push_back("-std=c++11");
    arguments.push_back("-stdlib=libc++");
    
    arguments.push_back("-I/Users/Jeppe/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/include/c++/v1");
    arguments.push_back("-I/Users/Jeppe/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/lib/clang/3.7.0/include");
    
    //arguments.push_back("-I/usr/include");
    //arguments.push_back("-I/usr/include/c++/4.2.1/");
    arguments.push_back("-I/Projects/PocketEngine/Pocket/Data/");
    arguments.push_back("-I/Projects/PocketEngine/Pocket/ComponentSystem/");
    arguments.push_back("-I/Projects/PocketEngine/Pocket/ComponentSystem/Meta/");
    
    CXIndex index = clang_createIndex(0,1);
    CXTranslationUnit tu  = clang_parseTranslationUnit(index, path.c_str(), &arguments[0], (int)arguments.size(), NULL, 0, 0);
    
    return tu;
}
/**
 * Параметр CXTranslationUnit_SkipFunctionBodies позволяет ускорить разбор
 * за счёт игнорирования парсером тел функций
 * Внутри функций обычно нет глобальных переменных
 */
void fileAction(const std::string &path)
{
    CXTranslationUnit unit = clang_parseTranslationUnit(
                g_index,
                path.c_str(),
                nullptr, /* argv */
                0, /* argc */
                nullptr, /* unsaved files */
                0, /* num unsaved files */
                CXTranslationUnit_SkipFunctionBodies
                | CXTranslationUnit_DetailedPreprocessingRecord
                );

    if (unit == nullptr)
    {
        std::cout << "Cannot parse: " << path << std::endl;
        return;
    }

    // Получаем курсор для всей единицы трансляции
    CXCursor cursorTU = clang_getTranslationUnitCursor(unit);
    clang_visitChildren(cursorTU, globalsFinder, NULL);

    clang_disposeTranslationUnit(unit);
}
Esempio n. 7
0
TEST_F(LibclangReparseTest, ReparseWithModule) {
  const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
  const char *HeaderBottom = "\n};\n#endif\n";
  const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
                         " struct Foo foo; foo.bar = 7; foo.baz = 8; }\n";
  const char *ModFile = "module A { header \"HeaderFile.h\" }\n";
  std::string HeaderName = "HeaderFile.h";
  std::string MName = "MFile.m";
  std::string ModName = "module.modulemap";
  WriteFile(MName, MFile);
  WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
  WriteFile(ModName, ModFile);

  std::string ModulesCache = std::string("-fmodules-cache-path=") + TestDir;
  const char *Args[] = { "-fmodules", ModulesCache.c_str(),
                         "-I", TestDir.c_str() };
  int NumArgs = sizeof(Args) / sizeof(Args[0]);
  ClangTU = clang_parseTranslationUnit(Index, MName.c_str(), Args, NumArgs,
                                       nullptr, 0, TUFlags);
  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
  DisplayDiagnostics();

  // Immedaitely reparse.
  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));

  std::string NewHeaderContents =
      std::string(HeaderTop) + "int baz;" + HeaderBottom;
  WriteFile(HeaderName, NewHeaderContents);

  // Reparse after fix.
  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
  EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
}
Esempio n. 8
0
TEST_F(LibclangReparseTest, Reparse) {
  const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
  const char *HeaderBottom = "\n};\n#endif\n";
  const char *CppFile = "#include \"HeaderFile.h\"\nint main() {"
                         " Foo foo; foo.bar = 7; foo.baz = 8; }\n";
  std::string HeaderName = "HeaderFile.h";
  std::string CppName = "CppFile.cpp";
  WriteFile(CppName, CppFile);
  WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);

  ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0,
                                       nullptr, 0, TUFlags);
  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
  DisplayDiagnostics();

  // Immedaitely reparse.
  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));

  std::string NewHeaderContents =
      std::string(HeaderTop) + "int baz;" + HeaderBottom;
  WriteFile(HeaderName, NewHeaderContents);

  // Reparse after fix.
  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
  EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
}
Esempio n. 9
0
int main(int argc, const char* argv[]) {
    if (argc < 4) {
        std::cerr << "Usage:\n"
            << "    " << argv[0] << " <dbFilename> <indexFilename> [<options>] <sourceFilename>\n";
        return 1;
    }

    const char* dbFilename = argv[1];
    const char* indexFilename = argv[2];
    const char* sourceFilename = argv[argc-1];

    // Set up the clang translation unit
    CXIndex cxindex = clang_createIndex(0, 0);
    CXTranslationUnit tu = clang_parseTranslationUnit(
        cxindex, 0,
        argv + 3, argc - 3, // Skip over dbFilename and indexFilename
        0, 0,
        CXTranslationUnit_None);

    // Print any errors or warnings
    int n = clang_getNumDiagnostics(tu);
    if (n > 0) {
        int nErrors = 0;
        for (unsigned i = 0; i != n; ++i) {
            CXDiagnostic diag = clang_getDiagnostic(tu, i);
            CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
            fprintf(stderr, "%s\n", clang_getCString(string));
            if (clang_getDiagnosticSeverity(diag) == CXDiagnostic_Error
                    || clang_getDiagnosticSeverity(diag) == CXDiagnostic_Fatal)
                nErrors++;
        }
    }

    // Create the index
    EverythingIndexer visitor(sourceFilename);
    clang_visitChildren(
            clang_getTranslationUnitCursor(tu),
            &visitorFunction,
            &visitor);
    ClicIndex& index = visitor.usrToReferences;

    // OK, now write the index to a compressed file
    std::ofstream fout(indexFilename);
    boost::iostreams::filtering_stream<boost::iostreams::output> zout;
    zout.push(boost::iostreams::gzip_compressor());
    zout.push(fout);
    printIndex(zout, index);

    // Now open the database and add the index to it
    ClicDb db(dbFilename);

    BOOST_FOREACH(const ClicIndex::value_type& it, index) {
        const std::string& usr = it.first;
        db.addMultiple(usr, it.second);
    }

    return 0;
}
Esempio n. 10
0
int main(int argc, char *argv[])
{
  auto index = clang_createIndex(0, 0);
  auto options = clang_defaultEditingTranslationUnitOptions();
  char const *args[] = { "-x", "c++", "-std=c++11" };
  auto arg_count = sizeof( args ) / sizeof( *args );
  filename = argv[1];
  
  CXUnsavedFile *unsaved_files = NULL;
  auto unsaved_file_count = 0;
  
  tu = clang_parseTranslationUnit(index, filename.c_str(), args, arg_count,
				  unsaved_files, unsaved_file_count,
				  options );
  
  if ( !tu ) {
    std::cout << "Translation Unit Parse Failed!\n";
    return -1;
  }

  std::stringstream ss( argv[2] );
  int line, col;

  ss >> line;
  ss.get();
  ss >> col;
  std::cout << "Hello " << line << ":" << col << "\n";

  auto file = clang_getFile( tu, filename.c_str() );
  auto location = clang_getLocation( tu, file, line, col );

  
  clang_visitChildren( clang_getTranslationUnitCursor( tu ), visitor,
		       reinterpret_cast<CXClientData>(0) );
  
  auto cursor = clang_getCursor( tu, location );
  auto refcursor = clang_getCursorReferenced( cursor );
  auto rrefcursor = clang_getCursorReferenced( refcursor );
  auto arf = clang_getTypeKindSpelling( clang_getCursorType( cursor ).kind );
  auto foo = clang_getCanonicalCursor( cursor );
  auto semparent = clang_getCursorSemanticParent( cursor );
  auto lexparent = clang_getCursorLexicalParent( cursor );

  std::cout << cursor << "\n";
  std::cout << refcursor << "\n";
  std::cout << rrefcursor << "\n";
  std::cout << clang_getCString(arf) << "\n";
  std::cout << foo << "\n";
  std::cout << "Parent: " << semparent << "\n";
  std::cout << "LexParent: " << lexparent << "\n";
  
  //clang_visitChildren( semparent, visitor, reinterpret_cast<CXClientData>(0) );
  clang_disposeString( arf );

  return 0;
}
Esempio n. 11
0
static inline CXTranslationUnit CLANG_PARSE(const CXIndex &idx, const char *filename, char **args, int args_size, CXUnsavedFile *unsaved_file)
{
	int unsaved_file_num = 0;
	if (unsaved_file) unsaved_file_num = 1;
	return clang_parseTranslationUnit(idx, filename, args, args_size,
									  unsaved_file, unsaved_file_num,
									  clang_defaultEditingTranslationUnitOptions()|
									  CXTranslationUnit_PrecompiledPreamble|
									  CXTranslationUnit_CXXPrecompiledPreamble|
									  CXTranslationUnit_CacheCompletionResults);
}
CXTranslationUnit ClangWorkerThread::DoCreateTU(CXIndex index, ClangThreadRequest* task, bool reparse)
{
    wxFileName fn(task->GetFileName());
    DoSetStatusMsg(wxString::Format(wxT("clang: parsing file %s..."), fn.GetFullName().c_str()));

    FileExtManager::FileType type = FileExtManager::GetType(task->GetFileName());
    int argc(0);
    char** argv = MakeCommandLine(task, argc, type);

    for(int i = 0; i < argc; i++) {
        CL_DEBUG(wxT("Command Line Argument: %s"), wxString(argv[i], wxConvUTF8).c_str());
    }

    std::string c_filename = task->GetFileName().mb_str(wxConvUTF8).data();
    CL_DEBUG(wxT("Calling clang_parseTranslationUnit..."));

    // First time, need to create it
    unsigned flags;
    if(reparse) {
        flags = CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble |
                CXTranslationUnit_Incomplete | CXTranslationUnit_DetailedPreprocessingRecord |
                CXTranslationUnit_CXXChainedPCH;
    } else {
        flags = CXTranslationUnit_Incomplete | 
#if HAS_LIBCLANG_BRIEFCOMMENTS
		CXTranslationUnit_SkipFunctionBodies |
#endif
                CXTranslationUnit_DetailedPreprocessingRecord;
    }

    CXTranslationUnit TU = clang_parseTranslationUnit(index, c_filename.c_str(), argv, argc, NULL, 0, flags);

    CL_DEBUG(wxT("Calling clang_parseTranslationUnit... done"));
    ClangUtils::FreeArgv(argv, argc);
    DoSetStatusMsg(wxString::Format(wxT("clang: parsing file %s...done"), fn.GetFullName().c_str()));
    if(TU && reparse) {
        CL_DEBUG(wxT("Calling clang_reparseTranslationUnit..."));
        if(clang_reparseTranslationUnit(TU, 0, NULL, clang_defaultReparseOptions(TU)) == 0) {
            CL_DEBUG(wxT("Calling clang_reparseTranslationUnit... done"));
            return TU;

        } else {
            CL_DEBUG(wxT("An error occured during reparsing of the TU for file %s. TU: %p"),
                     task->GetFileName().c_str(),
                     (void*)TU);

            // The only thing that left to be done here, is to dispose the TU
            clang_disposeTranslationUnit(TU);
            PostEvent(wxEVT_CLANG_TU_CREATE_ERROR, task->GetFileName());
            return NULL;
        }
    }
    return TU;
}
Esempio n. 13
0
int main(int argc, char * argv[])
{
  CXIndex index = clang_createIndex(0, 0);
  CXTranslationUnit txUnit = clang_parseTranslationUnit(index, 0, (const char * const *) argv, argc, 0, 0, CXTranslationUnit_None);

  CXCursor cur = clang_getTranslationUnitCursor(txUnit);
  clang_visitChildren(cur, visitor, NULL);

  clang_disposeTranslationUnit(txUnit);
  clang_disposeIndex(index);
  return 0;
}
CXTranslationUnit completion_parseTranslationUnit(completion_Session *session)
{
    struct CXUnsavedFile unsaved_files = __get_CXUnsavedFile(session);
    session->cx_tu = 
        clang_parseTranslationUnit(
            session->cx_index, session->src_filename, 
            (const char * const *) session->cmdline_args, session->num_args, 
            &unsaved_files, 1,
            session->ParseOptions);

    return session->cx_tu;
}
Esempio n. 15
0
int main(int argc, const char* const argv[]){
  if (argc < 2) {
    printf("Usage: %s header.h\n", argv[0]);
    printf("Standard clang arguments (-I, -D, etc.) may be used\n");
    exit(1);
  }
  unsigned i;

  char filename[] = "ffigen.tmp.XXXXXX";
  int fd = mkstemp(filename);
  FILE* file = fdopen(fd, "w");
  fprintf(file, "#define _SIZE_T\n");
  fprintf(file, "#define _PTRDIFF_T\n");
  fprintf(file, "typedef __SIZE_TYPE__ size_t;\n");
  fprintf(file, "typedef __PTRDIFF_TYPE__ ptrdiff_t;\n");
  fprintf(file, "#include <%s>\n", argv[1]);
  fclose(file);

  int clang_argc = argc + 1;
  const char** clang_argv = malloc(sizeof(char*) * clang_argc);
  clang_argv[0] = "-x";
  clang_argv[1] = "c";
  clang_argv[2] = filename;
  for (i=3; i < clang_argc; i++) {
    clang_argv[i] = argv[i-1];
  }

  CXIndex Index = clang_createIndex(0, 0);
  TU = clang_parseTranslationUnit(Index, 0, clang_argv, clang_argc,
                                  0, 0, CXTranslationUnit_DetailedPreprocessingRecord);
  json_t* json = json_object();
  clang_visitChildren(clang_getTranslationUnitCursor(TU), visit_program, (CXClientData)json);


  json_dumpf(json, stdout, JSON_INDENT(2) | JSON_PRESERVE_ORDER);
  printf("\n");
  json_decref(json);


  for (i=0; i<clang_getNumDiagnostics(TU); i++) {
    putstring(clang_formatDiagnostic(clang_getDiagnostic(TU, i), clang_defaultDiagnosticDisplayOptions()));
  }


  clang_disposeTranslationUnit(TU);
  clang_disposeIndex(Index);
  free(clang_argv);
  unlink(filename);

  return 0;
}
Esempio n. 16
0
void TestCases::ClangTest() {
#ifdef ENABLE_CLANG_COMPLETION
  std::cout << "checking to see if libclang/libclang.dll works" << std::endl;

  int argc = 1;
  char* argv[] = {"--version"};

  CXIndex index = clang_createIndex(0, 0);
  CXTranslationUnit tu = clang_parseTranslationUnit(index, 0, argv, argc, 0, 0,
                                                    CXTranslationUnit_None);
  clang_disposeTranslationUnit(tu);
  clang_disposeIndex(index);
#endif
}
Esempio n. 17
0
int main(int argc, char *argv[])
{
    CXIndex Index = clang_createIndex(0, 0);
    CXTranslationUnit TU = clang_parseTranslationUnit(Index, 0,
                           (const char**)argv, argc,
                           0, 0, CXTranslationUnit_None);


    struct self whole;

    whole.


    clang_disposeTranslationUnit(TU);
    clang_disposeIndex(Index);
    return 0;
}
Esempio n. 18
0
void parseTranslationUnit(const Path &sourceFile, const List<String> &args,
                          CXTranslationUnit &unit, CXIndex index, String &clangLine,
                          uint32_t fileId, DependencyMap *dependencies,
                          CXUnsavedFile *unsaved, int unsavedCount)

{
    clangLine = "clang ";

    int idx = 0;
    const List<String> &defaultArguments = Server::instance()->options().defaultArguments;
    List<const char*> clangArgs(args.size() + defaultArguments.size(), 0);

    const List<String> *lists[] = { &args, &defaultArguments };
    for (int i=0; i<2; ++i) {
        const int count = lists[i]->size();
        for (int j=0; j<count; ++j) {
            String arg = lists[i]->at(j);
            if (arg.isEmpty())
                continue;
            if (dependencies && arg == "-include" && j + 1 < count) {
                const uint32_t fileId = Location::fileId(lists[i]->at(j + 1));
                if (fileId) {
                    (*dependencies)[fileId].insert(fileId);
                }
            }

            clangArgs[idx++] = lists[i]->at(j).constData();
            arg.replace("\"", "\\\"");
            clangLine += arg;
            clangLine += ' ';
        }
    }

    clangLine += sourceFile;

    StopWatch sw;
    unsigned int flags = CXTranslationUnit_DetailedPreprocessingRecord;
    if (Server::instance()->options().completionCacheSize)
        flags |= CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults;

    unit = clang_parseTranslationUnit(index, sourceFile.constData(),
                                      clangArgs.data(), idx, unsaved, unsavedCount, flags);
    // error() << sourceFile << sw.elapsed();
}
Esempio n. 19
0
    bool parse( int argc, const char **argv,
		CXUnsavedFile *unsaved_files = nullptr,
		unsigned int unsaved_file_count = 0 )
    {
	orig_argc = argc;
	orig_argv = argv;
	for ( auto i = 0; i < argc; ++i )
	    std::cout << argv[i] << " ";
	std::cout << "\n";
    
	unit = clang_parseTranslationUnit( index,
					   filename.c_str(),
					   argv,
					   argc,
					   unsaved_files,
					   unsaved_file_count,
					   options );
	return valid = (unit != NULL);
    }
Esempio n. 20
0
void Tokenizer::parse(OovStringRef fileName, OovStringRef buffer, size_t bufLen,
        char const * const clang_args[], size_t num_clang_args)
    {
    CLangAutoLock lock(mCLangLock, __LINE__, this);
    try
        {
        if(!mSourceFile)
            {
            // The clang_defaultCodeCompleteOptions() options are not for the parse
            // function, they are for the clang_codeCompleteAt func.
            unsigned options = clang_defaultEditingTranslationUnitOptions();
            // This is required to allow go to definition to work with #include.
            options |= CXTranslationUnit_DetailedPreprocessingRecord;

            mSourceFilename = fileName;
            mContextIndex = clang_createIndex(1, 1);
            mTransUnit = clang_parseTranslationUnit(mContextIndex, fileName,
                clang_args, static_cast<int>(num_clang_args), 0, 0, options);
            }
        else
            {
            static CXUnsavedFile file;
            file.Filename = mSourceFilename.c_str();
            file.Contents = buffer;
            file.Length = bufLen;

            unsigned options = clang_defaultReparseOptions(mTransUnit);
            int stat = clang_reparseTranslationUnit(mTransUnit, 1, &file, options);
            if(stat != 0)
                {
                clang_disposeTranslationUnit(mTransUnit);
                mTransUnit = nullptr;
                }
            }
        mSourceFile = clang_getFile(mTransUnit, fileName);
        }
    catch(...)
        {
        DUMP_PARSE_INT("Tokenizer::parse - CRASHED", 0);
        }
    }
Esempio n. 21
0
translation_unit& index::parse_translation_unit(const std::vector<std::string>& args, const std::vector<unsaved_file>& unsaved)
{
    auto argv = convert_args(args);
    auto unsaved_files = convert_unsaved_files(unsaved);
    unsigned options = CXTranslationUnit_DetailedPreprocessingRecord | 
                        CXTranslationUnit_CacheCompletionResults;
    
    auto tu = clang_parseTranslationUnit(idx, nullptr, argv.data(), argv.size(), unsaved_files.data(), unsaved_files.size(), options);
    if(!tu)
        throw error("unable to parse tu");

    // Have to reparse to cache completion results.
    int err = clang_reparseTranslationUnit(tu, unsaved_files.size(), unsaved_files.data(), clang_defaultReparseOptions(tu));
    if(err)
    {
        clang_disposeTranslationUnit(tu);
        throw error("unable to reparse tu");
    }
    
    tus.emplace_back(tu);
    return tus.back();
}
Esempio n. 22
0
int main(int argc, char *argv[]) {
  CXIndex index = clang_createIndex(0, 1);
  CXTranslationUnit tu = clang_parseTranslationUnit(index, "ast_clang.m", NULL, 0, NULL, 0, 
                                                    CXTranslationUnit_None);

  clang_visitChildrenWithBlock(clang_getTranslationUnitCursor(tu), ^enum CXChildVisitResult (CXCursor cursor, CXCursor parent) {
    enum CXCursorKind cursor_kind = clang_getCursorKind(cursor);
    switch(cursor_kind) {
      case CXCursor_ObjCInterfaceDecl:{
        CXString cxname = clang_getCursorSpelling(cursor);
        printf("class: %s\n", clang_getCString(cxname));
        clang_disposeString(cxname);
      } break;
      case CXCursor_ObjCPropertyDecl:{
        CXString cxname = clang_getCursorSpelling(cursor);
        printf(" -> %s\n", clang_getCString(cxname));
        clang_disposeString(cxname);
      } break;
      default:{}break;
    }
    return CXChildVisit_Recurse;
  });
Esempio n. 23
0
int main(int argc, char **argv)
{
    if (argc < 2)
        return 1;
    CXIndex index = clang_createIndex(1, 1);
    const char * const *args = 0;
    if (argc > 2)
        args = (const char *const *)&argv[2];

    CXTranslationUnit unit = clang_parseTranslationUnit(index, argv[1], args, argc - 2,
                                                        0, 0, clang_defaultEditingTranslationUnitOptions());
    if (unit) {
        int indent = 0;
        clang_visitChildren(clang_getTranslationUnitCursor(unit), visit, &indent);

        const unsigned int diagnosticCount = clang_getNumDiagnostics(unit);
        unsigned int i;
        for (i=0; i<diagnosticCount; ++i) {
            CXDiagnostic diagnostic = clang_getDiagnostic(unit, i);
            const unsigned int diagnosticOptions = (CXDiagnostic_DisplaySourceLocation|
                                                CXDiagnostic_DisplayColumn|
                                                CXDiagnostic_DisplaySourceRanges|
                                                CXDiagnostic_DisplayOption|
                                                CXDiagnostic_DisplayCategoryId|
                                                CXDiagnostic_DisplayCategoryName);
            CXString diagnosticText = clang_formatDiagnostic(diagnostic, diagnosticOptions);
            const char *cstr = clang_getCString(diagnosticText);
            if (cstr)
                printf("%s\n", cstr);
            clang_disposeString(diagnosticText);
        }
        clang_disposeTranslationUnit(unit);
    }
    clang_disposeIndex(index);
    return 0;
}
Esempio n. 24
0
bool IndexerJob::parse(int build)
{
    CXIndex &index = mUnits[build].first;
    if (!index)
        index = clang_createIndex(0, 1);
    if (!index) {
        abort();
        return false;
    }
    const List<String> args = mSourceInformation.builds.at(build).args;
    const List<String> &defaultArguments = Server::instance()->options().defaultArguments;
    CXTranslationUnit &unit = mUnits[build].second;
    assert(!unit);
    mClangLines.append(String());
    String &clangLine = mClangLines[build];

    clangLine = Server::instance()->clangPath();
    clangLine += ' ';

    int idx = 0;
    List<const char*> clangArgs(args.size() + defaultArguments.size(), 0);

    const List<String> *lists[] = { &args, &defaultArguments };
    for (int i=0; i<2; ++i) {
        const int count = lists[i]->size();
        for (int j=0; j<count; ++j) {
            String arg = lists[i]->at(j);
            if (arg.isEmpty())
                continue;
            if (arg == "-include" && j + 1 < count) {
                const uint32_t fileId = Location::fileId(lists[i]->at(j + 1));
                if (fileId) {
                    mData->dependencies[fileId].insert(mFileId);
                }
            }

            clangArgs[idx++] = lists[i]->at(j).constData();
            arg.replace("\"", "\\\"");
            clangLine += arg;
            clangLine += ' ';
        }
    }

    clangLine += mSourceInformation.sourceFile;

    unit = clang_parseTranslationUnit(index, mSourceInformation.sourceFile.constData(),
                                      clangArgs.data(), idx, 0, 0,
                                      CXTranslationUnit_Incomplete | CXTranslationUnit_DetailedPreprocessingRecord);

    warning() << "loading unit " << clangLine << " " << (unit != 0);
    if (unit) {
        return !isAborted();
    }

    error() << "got failure" << clangLine;
    const String preprocessorOnly = RTags::filterPreprocessor(mSourceInformation.sourceFile);
    if (!preprocessorOnly.isEmpty()) {
        CXUnsavedFile unsaved = { mSourceInformation.sourceFile.constData(), preprocessorOnly.constData(),
                                  static_cast<unsigned long>(preprocessorOnly.size()) };
        unit = clang_parseTranslationUnit(index, mSourceInformation.sourceFile.constData(),
                                          clangArgs.data(), idx, &unsaved, 1,
                                          CXTranslationUnit_Incomplete | CXTranslationUnit_DetailedPreprocessingRecord);
    }
    if (unit) {
        clang_getInclusions(unit, IndexerJob::inclusionVisitor, this);
        clang_disposeTranslationUnit(unit);
        unit = 0;
    } else {
        mData->dependencies[mFileId].insert(mFileId);
    }
    return !isAborted();
}
Esempio n. 25
0
TextEdit::TextEdit(QWidget *parent): QTextEdit(parent)
{

    this->setFont(QFont("Monaco", 10));
    this->setTabStopWidth(fontMetrics().width("\t")/2);
    connect(this,SIGNAL(cursorPositionChanged()),this,SLOT(slotCursorPositionChanged()));

    QFile file("/tmp/a.m");
    file.open(QIODevice::ReadOnly|QIODevice::Text);
    QByteArray data = file.readAll();
    QTextStream in(&data);
    QString decodedStr = in.readAll();
    setPlainText(decodedStr);
    file.close();
    cx_index = clang_createIndex(0,0);
    struct CXUnsavedFile unsaved_file;
    unsaved_file.Filename = "/tmp/a.m";
    unsaved_file.Contents = (char*)calloc(sizeof(char), 4096);
    unsaved_file.Length = this->toPlainText().length();
    char **cmd_args =  (char**)calloc(sizeof(char*), 6);
    int i = 0;
    for(i ; i <6; i++) {
    cmd_args[i] = (char*)calloc(sizeof(char), 1000 + 1);
    strcpy(cmd_args[i], "-cc1");
    strcpy(cmd_args[i], "-fsyntax-only");
    strcpy(cmd_args[i], "-code-completion-macros");
    strcpy(cmd_args[i], "-code-completion-patterns");
    strcpy(cmd_args[i], "-x objective-c");
    strcpy(cmd_args[i], "-I/usr/share/iPhoneOS5.0.sdk/usr/include");
    }

    cx_tu = clang_parseTranslationUnit(cx_index, "/tmp/a.m" , cmd_args, 6, &unsaved_file, 1, CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_Incomplete);
    if(!cx_tu)
        qDebug()<<"cx_tu";

    //connect(this,SIGNAL(textChanged()), this,SLOT(slotReparse()));



    completionList = new QListWidget(this);
    completionList->setSelectionMode( QAbstractItemView::SingleSelection );
    completionList->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
    completionList->hide();
    completionList->setSortingEnabled( true );
    completionList->setSelectionMode( QAbstractItemView::SingleSelection );
    QPalette palette;
    palette.setBrush(QPalette::Active, QPalette::Base, Qt::white);
    completionList->setPalette(palette);

    m_formatFunction.setForeground(Qt::black);
    m_formatSingleLineComment.setForeground(Qt::red);
    m_formatKeyword.setForeground(Qt::blue);
    m_formatUserKeyword.setForeground(Qt::darkBlue);
    m_formatOperator.setForeground(Qt::black);
    m_formatNumber.setForeground(Qt::darkMagenta);
    m_formatEscapeChar.setForeground(Qt::darkBlue);
    m_formatMacro.setForeground(Qt::darkGreen);
    m_formatMultiLineComment.setForeground(Qt::red);
    m_formatString.setForeground(Qt::darkCyan);

    //connect(m_completionList, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(slotWordCompletion(QListWidgetItem *)) );
}
Esempio n. 26
0
CXTranslationUnit TUManager::parse(const std::string &              filename,
                                   const std::vector<std::string> & flags)
{
  CXTranslationUnit tu = translationUnits_[filename];

  if (! tu)
    {
      // FIXME: needed ?
      // Note: the -cc1 argument indicates the compiler front-end, and
      // not the driver, should be run. The compiler front-end has
      // several additional Clang specific features which are not
      // exposed through the GCC compatible driver interface.
      // from: http://clang.llvm.org/get_started.html
      // const_cast<std::vector<std::string> &>(flags).push_back("-cc1");

      std::size_t   nbArgs = flags.size();
      const char  **argv   = 0;

      if (nbArgs > 0)
        {
          argv         = new const char *[nbArgs + 1];
          argv[nbArgs] = 0;

          for (std::size_t i = 0; i < nbArgs; ++i)
            argv[i] = flags[i].c_str();
        }

      tu = clang_parseTranslationUnit(index_,
                                      filename.c_str(),
                                      argv, nbArgs,
                                      0, 0,
                                      clang_defaultEditingTranslationUnitOptions()
                                      | CXTranslationUnit_PrecompiledPreamble
                                      | CXTranslationUnit_CacheCompletionResults);
      delete [] argv;
      translationUnits_[filename] = tu;
    }

  if (! tu)
    {
      std::clog << "parsing \"" << filename << "\" failed." << std::endl;
      return 0;
    }

  // NOTE: Even at the first time the translation unit is reparsed,
  // because without this the completion is erroneous.

  // From the clang mailing list:
  // From: Douglas Gregor <*****@*****.**>
  // Subject: Re: Clang indexing library performance
  // Newsgroups: gmane.comp.compilers.clang.devel
  // ...
  // You want to use the "default editing options" when parsing the
  // translation unit
  //    clang_defaultEditingTranslationUnitOptions()
  // and then reparse at least once. That will enable the various
  // code-completion optimizations that should bring this time down
  // significantly.
  if (clang_reparseTranslationUnit(tu, 0, 0, clang_defaultReparseOptions(tu)))
    {
      // a 'fatal' error occur (even a diagnostic is impossible)
      clang_disposeTranslationUnit(tu);
      translationUnits_[filename] = 0;
    }

  return tu;
}
Esempio n. 27
0
void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
{
  static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
  static QStrList &includePath = Config_getList(INCLUDE_PATH);
  static QStrList clangOptions = Config_getList(CLANG_OPTIONS);
  static QCString clangCompileDatabase = Config_getList(CLANG_COMPILATION_DATABASE_PATH);
  if (!clangAssistedParsing) return;
  //printf("ClangParser::start(%s)\n",fileName);
  p->fileName = fileName;
  p->index    = clang_createIndex(0, 0);
  p->curLine  = 1;
  p->curToken = 0;
  QDictIterator<void> di(Doxygen::inputPaths);
  int argc=0;
  std::string error;
  // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
  // this only needs to be loaded once, and could be refactored to a higher level function
  static std::unique_ptr<clang::tooling::CompilationDatabase> db =
      clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error);
  int clang_option_len = 0;
  std::vector<clang::tooling::CompileCommand> command;
  if (strcmp(clangCompileDatabase, "0") != 0) {
      if (db == nullptr) {
          // user specified a path, but DB file was not found
          err("%s using clang compilation database path of: \"%s\"\n", error.c_str(),
              clangCompileDatabase.data());
      } else {
          // check if the file we are parsing is in the DB
          command = db->getCompileCommands(fileName);
          if (!command.empty() ) {
              // it's possible to have multiple entries for the same file, so use the last entry
              clang_option_len = command[command.size()-1].CommandLine.size();
          }
      }
  }
  char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()+clang_option_len));
  if (!command.empty() ) {
      std::vector<std::string> options = command[command.size()-1].CommandLine;
      // copy each compiler option used from the database. Skip the first which is compiler exe.
      for (auto option = options.begin()+1; option != options.end(); option++) {
          argv[argc++] = strdup(option->c_str());
      }
      // this extra addition to argv is accounted for as we are skipping the first entry in
      argv[argc++]=strdup("-w"); // finally, turn off warnings.
  } else {
  // add include paths for input files
  for (di.toFirst();di.current();++di,++argc)
  {
    QCString inc = QCString("-I")+di.currentKey();
    argv[argc]=strdup(inc.data());
    //printf("argv[%d]=%s\n",argc,argv[argc]);
  }
  // add external include paths
  for (uint i=0;i<includePath.count();i++)
  {
    QCString inc = QCString("-I")+includePath.at(i);
    argv[argc++]=strdup(inc.data());
  }
  // user specified options
  for (uint i=0;i<clangOptions.count();i++)
  {
    argv[argc++]=strdup(clangOptions.at(i));
  }
  // extra options
  argv[argc++]=strdup("-ferror-limit=0");
  argv[argc++]=strdup("-x");

  // Since we can be presented with a .h file that can contain C/C++ or
  // Objective C code and we need to configure the parser before knowing this,
  // we use the source file to detected the language. Detection will fail if you
  // pass a bunch of .h files containing ObjC code, and no sources :-(
  SrcLangExt lang = getLanguageFromFileName(fileName);
  if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp)
  {
    QCString fn = fileName;
    if (p->detectedLang==ClangParser::Private::Detected_Cpp && 
        (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" ||
         fn.right(3).lower()==".cc" || fn.right(2).lower()==".c"))
    { // fall back to C/C++ once we see an extension that indicates this
      p->detectedLang = ClangParser::Private::Detected_Cpp;
    }
    else if (fn.right(3).lower()==".mm") // switch to Objective C++
    {
      p->detectedLang = ClangParser::Private::Detected_ObjCpp;
    }
    else if (fn.right(2).lower()==".m") // switch to Objective C
    {
      p->detectedLang = ClangParser::Private::Detected_ObjC;
    }
  }
  switch(p->detectedLang)
  {
    case ClangParser::Private::Detected_Cpp: 
      argv[argc++]=strdup("c++"); 
      break;
    case ClangParser::Private::Detected_ObjC: 
      argv[argc++]=strdup("objective-c"); 
      break;
    case ClangParser::Private::Detected_ObjCpp: 
      argv[argc++]=strdup("objective-c++"); 
      break;
  }

  // provide the input and and its dependencies as unsaved files so we can
  // pass the filtered versions
  argv[argc++]=strdup(fileName);
  }
  static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
  //printf("source %s ----------\n%s\n-------------\n\n",
  //    fileName,p->source.data());
  uint numUnsavedFiles = filesInTranslationUnit.count()+1;
  p->numFiles = numUnsavedFiles;
  p->sources = new QCString[numUnsavedFiles];
  p->ufs     = new CXUnsavedFile[numUnsavedFiles];
  p->sources[0]      = detab(fileToString(fileName,filterSourceFiles,TRUE));
  p->ufs[0].Filename = strdup(fileName);
  p->ufs[0].Contents = p->sources[0].data();
  p->ufs[0].Length   = p->sources[0].length();
  QStrListIterator it(filesInTranslationUnit);
  uint i=1;
  for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++)
  {
    p->fileMapping.insert(it.current(),new uint(i));
    p->sources[i]      = detab(fileToString(it.current(),filterSourceFiles,TRUE));
    p->ufs[i].Filename = strdup(it.current());
    p->ufs[i].Contents = p->sources[i].data();
    p->ufs[i].Length   = p->sources[i].length();
  }

  // let libclang do the actual parsing
  p->tu = clang_parseTranslationUnit(p->index, 0,
                                     argv, argc, p->ufs, numUnsavedFiles, 
                                     CXTranslationUnit_DetailedPreprocessingRecord);
  // free arguments
  for (int i=0;i<argc;++i)
  {
    free(argv[i]);
  }
  free(argv);

  if (p->tu)
  {
    // filter out any includes not found by the clang parser
    determineInputFilesInSameTu(filesInTranslationUnit);

    // show any warnings that the compiler produced
    for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) 
    {
      CXDiagnostic diag = clang_getDiagnostic(p->tu, i); 
      CXString string = clang_formatDiagnostic(diag,
          clang_defaultDiagnosticDisplayOptions()); 
      err("%s [clang]\n",clang_getCString(string));
      clang_disposeString(string);
      clang_disposeDiagnostic(diag);
    }

    // create a source range for the given file
    QFileInfo fi(fileName);
    CXFile f = clang_getFile(p->tu, fileName);
    CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
    CXSourceLocation fileEnd   = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length);
    CXSourceRange    fileRange = clang_getRange(fileBegin, fileEnd);

    // produce a token stream for the file
    clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);

    // produce cursors for each token in the stream
    p->cursors=new CXCursor[p->numTokens];
    clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
  }
  else
  {
    p->tokens    = 0;
    p->numTokens = 0;
    p->cursors   = 0;
    err("clang: Failed to parse translation unit %s\n",fileName);
  }
}
Esempio n. 28
0
void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
{
  static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
  static QStrList &includePath = Config_getList("INCLUDE_PATH");
  static QStrList clangOptions = Config_getList("CLANG_OPTIONS");
  if (!clangAssistedParsing) return;
  //printf("ClangParser::start(%s)\n",fileName);
  p->fileName = fileName;
  p->index    = clang_createIndex(0, 0);
  p->curLine  = 1;
  p->curToken = 0;
  char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()));
  QDictIterator<void> di(Doxygen::inputPaths);
  int argc=0;
  // add include paths for input files
  for (di.toFirst();di.current();++di,++argc)
  {
    QCString inc = QCString("-I")+di.currentKey();
    argv[argc]=strdup(inc.data());
    //printf("argv[%d]=%s\n",argc,argv[argc]);
  }
  // add external include paths
  for (uint i=0;i<includePath.count();i++)
  {
    QCString inc = QCString("-I")+includePath.at(i);
    argv[argc++]=strdup(inc.data());
  }
  // user specified options
  for (uint i=0;i<clangOptions.count();i++)
  {
    argv[argc++]=strdup(clangOptions.at(i));
  }
  // extra options
  argv[argc++]=strdup("-ferror-limit=0");
  argv[argc++]=strdup("-x");

  // Since we can be presented with a .h file that can contain C/C++ or
  // Objective C code and we need to configure the parser before knowing this,
  // we use the source file to detected the language. Detection will fail if you
  // pass a bunch of .h files containing ObjC code, and no sources :-(
  SrcLangExt lang = getLanguageFromFileName(fileName);
  if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp)
  {
    QCString fn = fileName;
    if (p->detectedLang==ClangParser::Private::Detected_Cpp && 
        (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" ||
         fn.right(3).lower()==".cc" || fn.right(2).lower()==".c"))
    { // fall back to C/C++ once we see an extension that indicates this
      p->detectedLang = ClangParser::Private::Detected_Cpp;
    }
    else if (fn.right(3).lower()==".mm") // switch to Objective C++
    {
      p->detectedLang = ClangParser::Private::Detected_ObjCpp;
    }
    else if (fn.right(2).lower()==".m") // switch to Objective C
    {
      p->detectedLang = ClangParser::Private::Detected_ObjC;
    }
  }
  switch(p->detectedLang)
  {
    case ClangParser::Private::Detected_Cpp: 
      argv[argc++]=strdup("c++"); 
      break;
    case ClangParser::Private::Detected_ObjC: 
      argv[argc++]=strdup("objective-c"); 
      break;
    case ClangParser::Private::Detected_ObjCpp: 
      argv[argc++]=strdup("objective-c++"); 
      break;
  }

  // provide the input and and its dependencies as unsaved files so we can
  // pass the filtered versions
  argv[argc++]=strdup(fileName);
  static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
  //printf("source %s ----------\n%s\n-------------\n\n",
  //    fileName,p->source.data());
  uint numUnsavedFiles = filesInTranslationUnit.count()+1;
  p->numFiles = numUnsavedFiles;
  p->sources = new QCString[numUnsavedFiles];
  p->ufs     = new CXUnsavedFile[numUnsavedFiles];
  p->sources[0]      = detab(fileToString(fileName,filterSourceFiles,TRUE));
  p->ufs[0].Filename = strdup(fileName);
  p->ufs[0].Contents = p->sources[0].data();
  p->ufs[0].Length   = p->sources[0].length();
  QStrListIterator it(filesInTranslationUnit);
  uint i=1;
  for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++)
  {
    p->fileMapping.insert(it.current(),new uint(i));
    p->sources[i]      = detab(fileToString(it.current(),filterSourceFiles,TRUE));
    p->ufs[i].Filename = strdup(it.current());
    p->ufs[i].Contents = p->sources[i].data();
    p->ufs[i].Length   = p->sources[i].length();
  }

  // let libclang do the actual parsing
  p->tu = clang_parseTranslationUnit(p->index, 0,
                                     argv, argc, p->ufs, numUnsavedFiles, 
                                     CXTranslationUnit_DetailedPreprocessingRecord);
  // free arguments
  for (int i=0;i<argc;++i)
  {
    free(argv[i]);
  }
  free(argv);

  if (p->tu)
  {
    // filter out any includes not found by the clang parser
    determineInputFilesInSameTu(filesInTranslationUnit);

    // show any warnings that the compiler produced
    for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) 
    {
      CXDiagnostic diag = clang_getDiagnostic(p->tu, i); 
      CXString string = clang_formatDiagnostic(diag,
          clang_defaultDiagnosticDisplayOptions()); 
      err("%s [clang]\n",clang_getCString(string));
      clang_disposeString(string);
      clang_disposeDiagnostic(diag);
    }

    // create a source range for the given file
    QFileInfo fi(fileName);
    CXFile f = clang_getFile(p->tu, fileName);
    CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
    CXSourceLocation fileEnd   = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length);
    CXSourceRange    fileRange = clang_getRange(fileBegin, fileEnd);

    // produce a token stream for the file
    clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);

    // produce cursors for each token in the stream
    p->cursors=new CXCursor[p->numTokens];
    clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
  }
  else
  {
    p->tokens    = 0;
    p->numTokens = 0;
    p->cursors   = 0;
    err("clang: Failed to parse translation unit %s\n",fileName);
  }
}
Esempio n. 29
0
static void process_ac(int sock)
{
	tpl_node *tn;
	struct msg_ac msg;
	wordexp_t flags;

	tn = msg_ac_node(&msg);
	tpl_load(tn, TPL_FD, sock);
	tpl_unpack(tn, 0);
	tpl_free(tn);

	struct CXUnsavedFile unsaved = {
		msg.filename,
		msg.buffer.addr,
		msg.buffer.sz
	};

	change_dir(msg.filename);
	try_load_dotccode(&flags);

	str_t *partial = extract_partial(&msg);

	if (partial)
		msg.col -= partial->len;

	if (needs_reparsing(&flags, msg.filename)) {
		if (clang_tu)
			clang_disposeTranslationUnit(clang_tu);

		clang_tu = clang_parseTranslationUnit(clang_index, msg.filename,
						      (char const * const *)flags.we_wordv,
						      flags.we_wordc,
						      &unsaved, 1,
						      clang_defaultEditingTranslationUnitOptions());
		if (last_filename)
			free(last_filename);
		if (last_wordexp.we_wordv)
			wordfree(&last_wordexp);
		last_filename = strdup(msg.filename);
		last_wordexp = flags;
	}

	// diag
	/*
	for (int i = 0, n = clang_getNumDiagnostics(clang_tu); i != n; ++i) {
		CXDiagnostic diag = clang_getDiagnostic(clang_tu, i);
		CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
		fprintf(stderr, "%s\n", clang_getCString(string));
		clang_disposeString(string);
		clang_disposeDiagnostic(diag);
	}
	*/

	CXCodeCompleteResults *results;
	results = clang_codeCompleteAt(clang_tu, msg.filename, msg.line, msg.col,
				       &unsaved, 1,
				       CXCodeComplete_IncludeMacros);
	free_msg_ac(&msg);

	// diag
	/*
	for (int i = 0, n = clang_codeCompleteGetNumDiagnostics(results); i != n; ++i) {
		CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i);
		CXString string = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
		fprintf(stderr, "%s\n", clang_getCString(string));
		clang_disposeString(string);
		clang_disposeDiagnostic(diag);
	}
	*/

	struct msg_ac_response msg_r = { (partial) ? partial->len : 0, 0, 0 };

	if (results) {
		struct make_ac_ctx ctx;
		str_t *fmt;

		init_make_ac_ctx(&ctx);
		msg_r.proposals_n = filter_out_cc_results(results->Results,
							  results->NumResults,
							  partial, &fmt);
		sort_cc_results(results->Results, msg_r.proposals_n);
		if (msg_r.proposals_n > MAX_AC_RESULTS)
			msg_r.proposals_n = MAX_AC_RESULTS;
		msg_r.proposals = malloc(sizeof(struct ac_proposal) *
					 msg_r.proposals_n);

		int cur = 0;
		for (int i = 0; i < msg_r.proposals_n; ++i) {
			int added;
			added = make_ac_proposal(&ctx,
						 &msg_r.proposals[cur],
						 &results->Results[i],
						 fmt);
			if (added)
				cur++;
		}
		msg_r.proposals_n = cur;
		free_make_ac_ctx(&ctx);
		str_free(fmt);
	}

	if (partial)

		str_free(partial);
	clang_disposeCodeCompleteResults(results);

	msg_ac_response_send(&msg_r, sock);
	free_msg_ac_response(&msg_r);
}