コード例 #1
0
ファイル: clang_utils.cpp プロジェクト: AndrianDTR/codelite
bool ClangUtils::GetCursorAt(CXTranslationUnit &unit, const wxString &filename, int line, int col, CXCursor &cur)
{
	CXFile file1;
	CXCursor cursor;
	CXSourceLocation loc;
	file1  = clang_getFile    (unit, filename.mb_str(wxConvUTF8).data());
	loc    = clang_getLocation(unit, file1, line, col);
	cursor = clang_getCursor  (unit, loc);
	
	if(clang_isInvalid(cursor.kind))
		return false;

	if(cursor.kind == CXCursor_MemberRef     ||
	   cursor.kind == CXCursor_MemberRefExpr ||
	   cursor.kind == CXCursor_TypeRef       ||
	   cursor.kind == CXCursor_DeclRefExpr   ||
	   cursor.kind == CXCursor_TemplateRef   ||
	   cursor.kind == CXCursor_NamespaceRef  
	)
	{
		cursor = clang_getCursorReferenced(cursor);
	}
	cur = cursor;
	return true;
}
コード例 #2
0
void
Html_File::write_html(void) {
  cur_line_ = 1;
  cur_column_ = 1;

  CXFile file = clang_getFile(tu_file_->tu(), source_filename_.c_str());
  CXSourceRange range
    = clang_getRange(clang_getLocationForOffset(tu_file_->tu(), file, 0),
                     clang_getLocationForOffset(tu_file_->tu(),
                                                file, tu_file_->length()));

  CXToken *tokens;
  unsigned num;
  clang_tokenize(tu_file_->tu(), range, &tokens, &num);

  FILE* f = fopen(html_filename_.c_str(), "w");
  if (f) {
    write_header(f);

    for (unsigned i = 0; i < num; ++i)
      write_comment_split(f, file, tokens[i]);

    fprintf(f, "</pre></div></div></body></html>");
    fclose(f);
  }
  else
    std::cerr << "error: could not create file: " << html_filename_.c_str() << "\n";

  clang_disposeTokens(tu_file_->tu(), tokens, num);
}
コード例 #3
0
ファイル: clangparser.cpp プロジェクト: bithium/doxygen
void ClangParser::switchToFile(const char *fileName)
{
  if (p->tu)
  {
    delete[] p->cursors;
    clang_disposeTokens(p->tu,p->tokens,p->numTokens);
    p->tokens    = 0;
    p->numTokens = 0;
    p->cursors   = 0;

    QFileInfo fi(fileName);
    CXFile f = clang_getFile(p->tu, fileName);
    uint *pIndex=p->fileMapping.find(fileName);
    if (pIndex && *pIndex<p->numFiles)
    {
      uint i=*pIndex;
      //printf("switchToFile %s: len=%ld\n",fileName,p->ufs[i].Length);
      CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
      CXSourceLocation fileEnd   = clang_getLocationForOffset(p->tu, f, p->ufs[i].Length);
      CXSourceRange    fileRange = clang_getRange(fileBegin, fileEnd);

      clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);
      p->cursors=new CXCursor[p->numTokens];
      clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);

      p->curLine  = 1;
      p->curToken = 0;
    }
    else
    {
      err("clang: Failed to find input file %s in mapping\n",fileName);
    }
  }
}
void filter_already_existing_methods(CXTranslationUnit code_translation_unit,gchar *filename, gchar *class_name) {
	size_t i;
	CXFile code_file;
	CXCursor code_cursor;
	CXSourceLocation code_source_location;
	gchar *settername;
	gchar *gettername;
	struct GcharTuple tuple;
		
	code_file = clang_getFile(code_translation_unit,filename);
	code_source_location = clang_getLocation(code_translation_unit,code_file,1,1);
	code_cursor = clang_getTranslationUnitCursor(code_translation_unit);
	
	for (i=0; i < property_list.used; i++) {
		gettername = malloc((strlen(sg_method_name_getter) + 1) * sizeof(gchar));
		strncpy(gettername,sg_method_name_getter,strlen(sg_method_name_getter) + 1);
		gettername = chunked_string_replace(gettername,"$NAME",property_list.data[i].name);
		
		settername = malloc((strlen(sg_method_name_setter) + 1) * sizeof(gchar));
		strncpy(settername,sg_method_name_setter,strlen(sg_method_name_setter) + 1);
		settername = chunked_string_replace(settername,"$NAME",property_list.data[i].name);
		
		tuple.first = gettername;
		tuple.second = settername;
		tuple.class_name = class_name;
		tuple.number = i;

		clang_visitChildren(code_cursor,filterer,&tuple);
		
		free(gettername);
		gettername = NULL;
		free(settername);
		settername = NULL;
	}
}
コード例 #5
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();
}
コード例 #6
0
CXSourceLocation TranslationUnit::GetSourceLocation(
  const std::string &filename,
  int line,
  int column ) {

  // ASSUMES A LOCK IS ALREADY HELD ON clang_access_mutex_ AND THE TU IS VALID!
  CXFile file = clang_getFile( clang_translation_unit_, filename.c_str() );
  return clang_getLocation( clang_translation_unit_, file, line, column );
}
コード例 #7
0
ファイル: sniper.cpp プロジェクト: samvv/clang-faces
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;
}
コード例 #8
0
ファイル: c-index-test.c プロジェクト: albertz/clang
static int perform_file_scan(const char *ast_file, const char *source_file,
                             const char *prefix) {
  CXIndex Idx;
  CXTranslationUnit TU;
  FILE *fp;
  CXCursor prevCursor = clang_getNullCursor();
  CXFile file;
  unsigned line = 1, col = 1;
  unsigned start_line = 1, start_col = 1;

  if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
                                /* displayDiagnosics=*/1))) {
    fprintf(stderr, "Could not create Index\n");
    return 1;
  }

  if (!CreateTranslationUnit(Idx, ast_file, &TU))
    return 1;

  if ((fp = fopen(source_file, "r")) == NULL) {
    fprintf(stderr, "Could not open '%s'\n", source_file);
    return 1;
  }

  file = clang_getFile(TU, source_file);
  for (;;) {
    CXCursor cursor;
    int c = fgetc(fp);

    if (c == '\n') {
      ++line;
      col = 1;
    } else
      ++col;

    /* Check the cursor at this position, and dump the previous one if we have
     * found something new.
     */
    cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, col));
    if ((c == EOF || !clang_equalCursors(cursor, prevCursor)) &&
        prevCursor.kind != CXCursor_InvalidFile) {
      print_cursor_file_scan(prevCursor, start_line, start_col,
                             line, col, prefix);
      start_line = line;
      start_col = col;
    }
    if (c == EOF)
      break;

    prevCursor = cursor;
  }

  fclose(fp);
  return 0;
}
コード例 #9
0
CXCursor TranslationUnit::GetCursor( int line, int column ) {
  // ASSUMES A LOCK IS ALREADY HELD ON clang_access_mutex_!
  if ( !clang_translation_unit_ )
    return clang_getNullCursor();

  CXFile file = clang_getFile( clang_translation_unit_, filename_.c_str() );
  CXSourceLocation source_location = clang_getLocation(
                                       clang_translation_unit_,
                                       file,
                                       line,
                                       column );

  return clang_getCursor( clang_translation_unit_, source_location );
}
コード例 #10
0
SourceLocation::SourceLocation(CXTranslationUnit cxTranslationUnit,
                               const Utf8String &filePath,
                               uint line,
                               uint column)
    : cxSourceLocation(clang_getLocation(cxTranslationUnit,
                                         clang_getFile(cxTranslationUnit,
                                                 filePath.constData()),
                                         line,
                                         column)),
      filePath_(filePath),
      line_(line),
      column_(column)
{
}
コード例 #11
0
static IdeHighlightIndex *
ide_clang_service_build_index (IdeClangService   *self,
                               CXTranslationUnit  tu,
                               ParseRequest      *request)
{
  static const gchar *common_defines[] = {
    "NULL", "MIN", "MAX", "__LINE__", "__FILE__", NULL
  };
  IdeHighlightIndex *index;
  IndexRequest client_data;
  CXCursor cursor;
  CXFile file;
  gsize i;

  g_assert (IDE_IS_CLANG_SERVICE (self));
  g_assert (tu != NULL);
  g_assert (request != NULL);

  file = clang_getFile (tu, request->source_filename);
  if (file == NULL)
    return NULL;

  index = ide_highlight_index_new ();

  client_data.index = index;
  client_data.file = file;
  client_data.filename = request->source_filename;

  /*
   * Add some common defines so they don't get changed by clang.
   */
  for (i = 0; common_defines [i]; i++)
    ide_highlight_index_insert (index, common_defines [i], "c:common-defines");
  ide_highlight_index_insert (index, "TRUE", "c:boolean");
  ide_highlight_index_insert (index, "FALSE", "c:boolean");
  ide_highlight_index_insert (index, "g_autoptr", "c:storage-class");
  ide_highlight_index_insert (index, "g_auto", "c:storage-class");
  ide_highlight_index_insert (index, "g_autofree", "c:storage-class");

  cursor = clang_getTranslationUnitCursor (tu);
  clang_visitChildren (cursor, ide_clang_service_build_index_visitor, &client_data);

  return index;
}
コード例 #12
0
    source_range_t source_range(translation_unit const &trans_unit)
    {
      auto &tu(trans_unit.impl);

      CXFile const file{ clang_getFile(tu, trans_unit.filename.c_str()) };
      std::size_t const size{ boost::filesystem::file_size(trans_unit.filename) };

      CXSourceLocation const top(clang_getLocationForOffset(tu, file, 0));
      CXSourceLocation const bottom(clang_getLocationForOffset(tu, file, size));
      if(clang_equalLocations(top,  clang_getNullLocation()) ||
         clang_equalLocations(bottom, clang_getNullLocation()))
      { throw std::runtime_error{ "cannot retrieve location" }; }

      source_range_t const range(clang_getRange(top, bottom));
      if(clang_Range_isNull(range))
      { throw std::runtime_error{ "cannot retrieve range" }; }

      return range;
    }
コード例 #13
0
ファイル: tokenizer.hpp プロジェクト: PKUbuntu/libclang-vim
    CXSourceRange get_range_whole_file() const
    {
        size_t const file_size = get_file_size(file_name.c_str());
        CXFile const file = clang_getFile(translation_unit, file_name.c_str());

        auto const file_begin = clang_getLocationForOffset(translation_unit, file, 0);
        auto const file_end = clang_getLocationForOffset(translation_unit, file, file_size);

        if(is_null_location(file_begin) || is_null_location(file_end)) {
            return clang_getNullRange();
        }

        auto const file_range = clang_getRange(file_begin, file_end);
        if(clang_Range_isNull(file_range)) {
            return clang_getNullRange();
        }

        return file_range;
    }
コード例 #14
0
ファイル: sniper.cpp プロジェクト: samvv/clang-faces
CXChildVisitResult visitor( CXCursor cursor, CXCursor parent, CXClientData d )
{
  auto range = clang_getCursorExtent( cursor );
  auto space = reinterpret_cast<int>( d );
  if ( space > 0 )
    std::cout << std::setw( space ) << " ";
  std::cout << cursor << " " << range << "\n";
  space += 2;

  auto location = clang_getCursorLocation( cursor );
  CXFile thisfile;
  clang_getSpellingLocation( location, &thisfile, NULL, NULL, NULL );

  if ( cursor.kind != CXCursor_InclusionDirective &&
       clang_getFile( tu, filename.c_str() ) == thisfile )
    clang_visitChildren( cursor, visitor, reinterpret_cast<CXClientData>(space) );
  
  return CXChildVisit_Continue;
}
コード例 #15
0
ファイル: Highlighter.cpp プロジェクト: animatedb/oovaide
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);
        }
    }
コード例 #16
0
void Irony::getType(unsigned line, unsigned col) const {
  if (activeTu_ == nullptr) {
    std::clog << "W: get-type - parse wasn't called\n";

    std::cout << "nil\n";
    return;
  }

  CXFile cxFile = clang_getFile(activeTu_, file_.c_str());
  CXSourceLocation sourceLoc = clang_getLocation(activeTu_, cxFile, line, col);
  CXCursor cursor = clang_getCursor(activeTu_, sourceLoc);

  if (clang_Cursor_isNull(cursor)) {
    // TODO: "error: no type at point"?
    std::cout << "nil";
    return;
  }

  CXType cxTypes[2];
  cxTypes[0] = clang_getCursorType(cursor);
  cxTypes[1] = clang_getCanonicalType(cxTypes[0]);

  std::cout << "(";

  for (const CXType &cxType : cxTypes) {
    CXString typeDescr = clang_getTypeSpelling(cxType);
    std::string typeStr = clang_getCString(typeDescr);
    clang_disposeString(typeDescr);

    if (typeStr.empty())
      break;

    std::cout << support::quoted(typeStr) << " ";
  }

  std::cout << ")\n";
}
コード例 #17
0
ファイル: c-index-test.c プロジェクト: albertz/clang
int perform_token_annotation(int argc, const char **argv) {
  const char *input = argv[1];
  char *filename = 0;
  unsigned line, second_line;
  unsigned column, second_column;
  CXIndex CIdx;
  CXTranslationUnit TU = 0;
  int errorCode;
  struct CXUnsavedFile *unsaved_files = 0;
  int num_unsaved_files = 0;
  CXToken *tokens;
  unsigned num_tokens;
  CXSourceRange range;
  CXSourceLocation startLoc, endLoc;
  CXFile file = 0;
  CXCursor *cursors = 0;
  unsigned i;

  input += strlen("-test-annotate-tokens=");
  if ((errorCode = parse_file_line_column(input, &filename, &line, &column,
                                          &second_line, &second_column)))
    return errorCode;

  if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files))
    return -1;

  CIdx = clang_createIndex(0, 1);
  TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
                                                 argc - num_unsaved_files - 3,
                                                 argv + num_unsaved_files + 2,
                                                 num_unsaved_files,
                                                 unsaved_files);
  if (!TU) {
    fprintf(stderr, "unable to parse input\n");
    clang_disposeIndex(CIdx);
    free(filename);
    free_remapped_files(unsaved_files, num_unsaved_files);
    return -1;
  }
  errorCode = 0;

  file = clang_getFile(TU, filename);
  if (!file) {
    fprintf(stderr, "file %s is not in this translation unit\n", filename);
    errorCode = -1;
    goto teardown;
  }

  startLoc = clang_getLocation(TU, file, line, column);
  if (clang_equalLocations(clang_getNullLocation(), startLoc)) {
    fprintf(stderr, "invalid source location %s:%d:%d\n", filename, line,
            column);
    errorCode = -1;
    goto teardown;
  }

  endLoc = clang_getLocation(TU, file, second_line, second_column);
  if (clang_equalLocations(clang_getNullLocation(), endLoc)) {
    fprintf(stderr, "invalid source location %s:%d:%d\n", filename,
            second_line, second_column);
    errorCode = -1;
    goto teardown;
  }

  range = clang_getRange(startLoc, endLoc);
  clang_tokenize(TU, range, &tokens, &num_tokens);
  cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor));
  clang_annotateTokens(TU, tokens, num_tokens, cursors);
  for (i = 0; i != num_tokens; ++i) {
    const char *kind = "<unknown>";
    CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
    CXSourceRange extent = clang_getTokenExtent(TU, tokens[i]);
    unsigned start_line, start_column, end_line, end_column;

    switch (clang_getTokenKind(tokens[i])) {
    case CXToken_Punctuation: kind = "Punctuation"; break;
    case CXToken_Keyword: kind = "Keyword"; break;
    case CXToken_Identifier: kind = "Identifier"; break;
    case CXToken_Literal: kind = "Literal"; break;
    case CXToken_Comment: kind = "Comment"; break;
    }
    clang_getInstantiationLocation(clang_getRangeStart(extent),
                                   0, &start_line, &start_column, 0);
    clang_getInstantiationLocation(clang_getRangeEnd(extent),
                                   0, &end_line, &end_column, 0);
    printf("%s: \"%s\" ", kind, clang_getCString(spelling));
    PrintExtent(stdout, start_line, start_column, end_line, end_column);
    if (!clang_isInvalid(cursors[i].kind)) {
      printf(" ");
      PrintCursor(cursors[i]);
    }
    printf("\n");
  }
  free(cursors);

 teardown:
  PrintDiagnostics(TU);
  clang_disposeTranslationUnit(TU);
  clang_disposeIndex(CIdx);
  free(filename);
  free_remapped_files(unsaved_files, num_unsaved_files);
  return errorCode;
}
コード例 #18
0
void ClangParser::start(const QString &fileName, QStringList &includeFiles)
{
   static QStringList includePath = Config::getList("include-path");    
   static QStringList clangFlags  = Config::getList("clang-flags");

   p->fileName = fileName;
   p->index    = clang_createIndex(0, 0);
   p->curLine  = 1;
   p->curToken = 0;

   char **argv = (char **)malloc(sizeof(char *) * (4 + Doxy_Globals::inputPaths.count() + includePath.count() + clangFlags.count()));
   int argc = 0;

   // add include paths for input files  
   for (auto item : Doxy_Globals::inputPaths) { 
      QString inc = "-I" + item;
      argv[argc] = strdup(inc.toUtf8());  

      ++argc;
   }

   // add external include paths
   for (uint i = 0; i < includePath.count(); i++) {  
      QString inc = "-I" + includePath.at(i);
      argv[argc++] = strdup(inc.toUtf8());  
   }

   // user specified options
   for (uint i = 0; i < clangFlags.count(); i++) {
      argv[argc++] = strdup(clangFlags.at(i).toUtf8());
   }

   // extra options
   argv[argc++] = strdup("-ferror-limit=0");
   argv[argc++] = strdup("-x");

   // Since we can be presented with an .h file that can contain C, C++, or Objective C,
   // we need to configure the parser before knowing this.
   // Use the source file to detected the language. Detection will fail if you
   // pass a bunch of .h files containing ObjC code and no source 

   SrcLangExt lang = getLanguageFromFileName(fileName);

   if (lang == SrcLangExt_ObjC || p->detectedLang != ClangParser::Private::Detected_Cpp) {
      QString fn = fileName;

      if (p->detectedLang == ClangParser::Private::Detected_Cpp &&
            (fn.right(4).toLower() == ".cpp" || fn.right(4).toLower() == ".cxx" ||
             fn.right(3).toLower() == ".cc" || fn.right(2).toLower() == ".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).toLower() == ".mm") { 
         // switch to Objective C++
         p->detectedLang = ClangParser::Private::Detected_ObjCpp;

      } else if (fn.right(2).toLower() == ".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
   static bool filterSourceFiles = Config::getBool("filter-source-files");

   argv[argc++] = strdup(fileName.toUtf8());
 
   uint numUnsavedFiles = includeFiles.count() + 1;

   p->numFiles = numUnsavedFiles;
   p->sources  = new QByteArray[numUnsavedFiles];
   p->ufs      = new CXUnsavedFile[numUnsavedFiles];

   p->sources[0]      = detab(fileToString(fileName, filterSourceFiles, true)).toUtf8();
   p->ufs[0].Filename = strdup(fileName.toUtf8());
   p->ufs[0].Contents = p->sources[0].constData();
   p->ufs[0].Length   = p->sources[0].length();

   //  
   uint i = 1;
   for (auto item : includeFiles) {       

      p->fileMapping.insert(item, i);

      p->sources[i]      = detab(fileToString(item, filterSourceFiles, true)).toUtf8();
      p->ufs[i].Filename = strdup(item.toUtf8());
      p->ufs[i].Contents = p->sources[i].constData();
      p->ufs[i].Length   = p->sources[i].length();

      i++;
   }

   // let libclang do the actual parsing
   CXErrorCode errorCode = clang_parseTranslationUnit2(p->index, 0, argv, argc, 0, 0, 
                  CXTranslationUnit_DetailedPreprocessingRecord, &(p->tu) );

   // 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
      determineInputFiles(includeFiles);

      // show any warnings the compiler produced
      uint n = clang_getNumDiagnostics(p->tu);

      for (uint i = 0; i != n; ++i) {
         CXDiagnostic diag = clang_getDiagnostic(p->tu, i);
         CXString string   = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());

         err("Clang parser warning -- %s\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.toUtf8());

      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", qPrintable(fileName));
   }
}
コード例 #19
0
void TextEdit::slotReparse()
{
    //connect(this,SIGNAL(textChanged()), this,SLOT(slotReparse()));
    QTextCursor tc = textCursor();
    tc.select(QTextCursor::WordUnderCursor);
    QString prefix = tc.selectedText();
    completionList->clear();
    qDebug()<<prefix;

    //clang_disposeTranslationUnit(cx_tu);
    struct CXUnsavedFile unsaved_file;
    unsaved_file.Filename = "/tmp/a.m";
    unsaved_file.Contents = strdup(this->toPlainText().toStdString().c_str());
    unsaved_file.Length = this->toPlainText().length();

    clang_reparseTranslationUnit(
        cx_tu, 1, &unsaved_file, CXTranslationUnit_PrecompiledPreamble);

    CXFile file = clang_getFile(cx_tu, unsaved_file.Filename);

    CXSourceLocation start = clang_getLocationForOffset(cx_tu, file, 0);
    CXSourceLocation end = clang_getLocationForOffset(cx_tu, file, this->toPlainText().length());
    CXSourceRange range= clang_getRange(start,end);
    CXToken *tokens;
    unsigned tokenCount;
    clang_tokenize(cx_tu,range, &tokens, &tokenCount);

    if (tokenCount > 0)
    {
      CXCursor *cursors = NULL;
      cursors = (CXCursor *)calloc(sizeof(CXCursor), tokenCount);
      clang_annotateTokens(cx_tu, tokens, tokenCount, cursors);

      for (unsigned i=0 ; i<tokenCount ; i++)
      {
        CXSourceRange sr = clang_getTokenExtent(cx_tu, tokens[i]);
        unsigned start, end;
        CXSourceLocation s = clang_getRangeStart(sr);
        CXSourceLocation e = clang_getRangeEnd(sr);
        clang_getInstantiationLocation(s, 0, 0, 0, &start);
        clang_getInstantiationLocation(e, 0, 0, 0, &end);
        qDebug()<<"start:"<<start<<"end:"<<end;
    /*    if(start >end) {
            int tmp = start;
            start = end;
            end = tmp;
        }
*/

        switch (cursors[i].kind)
        {
        case CXCursor_FirstRef... CXCursor_LastRef:

          break;
        case CXCursor_MacroDefinition:

          break;
        case CXCursor_MacroInstantiation:

          break;
        case CXCursor_FirstDecl...CXCursor_LastDecl:

          break;
        case CXCursor_ObjCMessageExpr:

          break;
        case CXCursor_DeclRefExpr:

          break;
        case CXCursor_PreprocessingDirective: {

        }
          break;
        default:
          break;
        }
     /*   if(cursors[i].kind == CXCursor_FunctionDecl)
            setFormat(start, end-start, m_formatSingleLineComment);*/
      }
    }
コード例 #20
0
ファイル: clang++.cpp プロジェクト: mythagel/cxxide
file translation_unit::get_file(const std::string& filename)
{
    return { clang_getFile(tu, filename.c_str()) };
}
コード例 #21
0
ファイル: clangparser.cpp プロジェクト: bithium/doxygen
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);
  }
}
コード例 #22
0
SkippedSourceRanges::SkippedSourceRanges(CXTranslationUnit cxTranslationUnit, const char *filePath)
{
    cxSkippedSourceRanges = clang_getSkippedRanges(cxTranslationUnit,
                                                   clang_getFile(cxTranslationUnit,
                                                                 filePath));
}
コード例 #23
0
File TranslationUnit::getFile(const std::string& name) const {
	return new File_(*this, clang_getFile(p->translationunit, name.c_str()));
}
コード例 #24
0
ファイル: clangparser.cpp プロジェクト: Acidburn0zzz/doxygen
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);
  }
}
コード例 #25
0
ファイル: c-index-test.c プロジェクト: albertz/clang
int inspect_cursor_at(int argc, const char **argv) {
  CXIndex CIdx;
  int errorCode;
  struct CXUnsavedFile *unsaved_files = 0;
  int num_unsaved_files = 0;
  CXTranslationUnit TU;
  CXCursor Cursor;
  CursorSourceLocation *Locations = 0;
  unsigned NumLocations = 0, Loc;

  /* Count the number of locations. */
  while (strstr(argv[NumLocations+1], "-cursor-at=") == argv[NumLocations+1])
    ++NumLocations;

  /* Parse the locations. */
  assert(NumLocations > 0 && "Unable to count locations?");
  Locations = (CursorSourceLocation *)malloc(
                                  NumLocations * sizeof(CursorSourceLocation));
  for (Loc = 0; Loc < NumLocations; ++Loc) {
    const char *input = argv[Loc + 1] + strlen("-cursor-at=");
    if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
                                            &Locations[Loc].line,
                                            &Locations[Loc].column, 0, 0)))
      return errorCode;
  }

  if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
                           &num_unsaved_files))
    return -1;

  CIdx = clang_createIndex(0, 1);
  TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
                                  argc - num_unsaved_files - 2 - NumLocations,
                                   argv + num_unsaved_files + 1 + NumLocations,
                                                 num_unsaved_files,
                                                 unsaved_files);
  if (!TU) {
    fprintf(stderr, "unable to parse input\n");
    return -1;
  }

  for (Loc = 0; Loc < NumLocations; ++Loc) {
    CXFile file = clang_getFile(TU, Locations[Loc].filename);
    if (!file)
      continue;

    Cursor = clang_getCursor(TU,
                             clang_getLocation(TU, file, Locations[Loc].line,
                                               Locations[Loc].column));
    PrintCursor(Cursor);
    printf("\n");
    free(Locations[Loc].filename);
  }

  PrintDiagnostics(TU);
  clang_disposeTranslationUnit(TU);
  clang_disposeIndex(CIdx);
  free(Locations);
  free_remapped_files(unsaved_files, num_unsaved_files);
  return 0;
}