std::vector<diagnostic> translation_unit::diagnose() {
        // Get all the diagnostics
        uint32_t n = clang_getNumDiagnostics(mUnit);

        if (n == 0)
            return {};

        std::vector<diagnostic> ret;
        ret.reserve(n);

        for (uint32_t i = 0; i < n; ++i) {
            CXFile file;
            uint32_t row = 0, col = 0, offset = 0;

            CXDiagnostic diag = clang_getDiagnostic(mUnit, i);
            CXSourceLocation loc = clang_getDiagnosticLocation(diag);
            clang_getExpansionLocation( loc, &file, &row, &col, &offset );

            ret.push_back({
                { cx2std(clang_getFileName(file)), row, col },
                clang_getDiagnosticSeverity(diag),
                diagnostic_text(diag),
                diagnostic_summary(diag)
            });

            clang_disposeDiagnostic(diag);
        }

        return ret;
    }
Ejemplo n.º 2
0
void wci_getCursorFile(char* cuin, char* cxsout)
{
  CXCursor cu = wci_get_CXCursor(cuin);
  CXSourceLocation loc = clang_getCursorLocation( cu );
  CXFile cxfile;
  clang_getExpansionLocation(loc, &cxfile, 0, 0, 0);
  wci_save_CXString(clang_getFileName(cxfile), cxsout);
}
Ejemplo n.º 3
0
static void dumpDiagnostics(const CXTranslationUnit &tu) {
  std::cout << "(\n";

  std::string file;

  for (unsigned i = 0, diagnosticCount = clang_getNumDiagnostics(tu);
       i < diagnosticCount;
       ++i) {
    CXDiagnostic diagnostic = clang_getDiagnostic(tu, i);

    CXSourceLocation location = clang_getDiagnosticLocation(diagnostic);

    unsigned line, column, offset;
    if (clang_equalLocations(location, clang_getNullLocation())) {
      file.clear();
      line = 0;
      column = 0;
      offset = 0;
    } else {
      CXFile cxFile;

// clang_getInstantiationLocation() has been marked deprecated and
// is aimed to be replaced by clang_getExpansionLocation().
#if CINDEX_VERSION >= 6
      clang_getExpansionLocation(location, &cxFile, &line, &column, &offset);
#else
      clang_getInstantiationLocation(location, &cxFile, &line, &column, &offset);
#endif

      file = cxStringToStd(clang_getFileName(cxFile));
    }

    const char *severity = diagnosticSeverity(diagnostic);

    std::string message =
        cxStringToStd(clang_getDiagnosticSpelling(diagnostic));

    std::cout << '(' << support::quoted(file)    //
              << ' ' << line                     //
              << ' ' << column                   //
              << ' ' << offset                   //
              << ' ' << severity                 //
              << ' ' << support::quoted(message) //
              << ")\n";

    clang_disposeDiagnostic(diagnostic);
  }

  std::cout << ")\n";
}
Ejemplo n.º 4
0
void TokenRange::tokenize(CXTranslationUnit transUnit)
    {
    CXCursor cursor = clang_getTranslationUnitCursor(transUnit);
    CXSourceRange range = clang_getCursorExtent(cursor);

    CXToken *tokens = 0;
    unsigned int numTokens = 0;
    clang_tokenize(transUnit, range, &tokens, &numTokens);
    resize(numTokens);
    if(numTokens > 0)
        {
        for (size_t i = 0; i < numTokens-1; i++)
            {
            at(i).setKind(clang_getTokenKind(tokens[i]));
            CXSourceRange tokRange = clang_getTokenExtent(transUnit, tokens[i]);
            clang_getExpansionLocation(clang_getRangeStart(tokRange), NULL, NULL,
                NULL, &at(i).mStartOffset);
            clang_getExpansionLocation(clang_getRangeEnd(tokRange), NULL, NULL,
                NULL, &at(i).mEndOffset);
            }
        }
    clang_disposeTokens(transUnit, tokens, numTokens);
    }
    location translation_unit::definition_location_at(uint32_t row, uint32_t col) {
        CXCursor cursor = get_cursor_at(row, col);
        CXCursor ref = clang_getCursorDefinition( cursor );

        if (clang_Cursor_isNull(ref) || clang_isInvalid(clang_getCursorKind(ref)))
            return {"", 0, 0};

        CXSourceLocation loc = clang_getCursorLocation(ref);

        CXFile file;
        uint32_t nrow, ncol, offset = 0;

        clang_getExpansionLocation( loc, &file, &nrow, &ncol, &offset );
        return { cx2std(clang_getFileName(file)), nrow, ncol };
    }
Ejemplo n.º 6
0
// FIXME:  change this to just printing comments, and call write_token()
//         directly from write_html() for non-comments.
void
Html_File::write_comment_split(FILE* f, CXFile file, CXToken tok) {
  unsigned line;
  unsigned column;
  unsigned offset;

  CXSourceLocation loc = clang_getTokenLocation(tu_file_->tu(), tok);
  clang_getExpansionLocation(loc, &file, &line, &column, &offset);

  CXTokenKind kind = clang_getTokenKind(tok);
  CXString s = clang_getTokenSpelling(tu_file_->tu(), tok);

  std::string sub = clang_getCString(s);
  clang_disposeString(s);

  // actually split up multi-line comments and send one at
  // a time -- that way each line gets line numbers.
  if (kind == CXToken_Comment || kind == CXToken_Literal) {
    std::string str = sub.c_str();
    if (kind == CXToken_Comment)
      str = fix(sub.c_str());
    size_t i;
    size_t begin = 0;
    for (i = 0; i < str.length(); ++i) {
      if (str[i] == '\n') {
        sub = str.substr(begin, i-begin);
        if (begin)
          line++; column = 1;
        begin = i + 1;
        write_token(f, file, tok, sub.c_str(), line, column);
      }
    }
    if (begin) {
      line++;
      column = 1;
    }
    sub = str.substr(begin, i-begin);
  }
  write_token(f, file, tok, sub.c_str(), line, column);
}
Ejemplo n.º 7
0
void
Html_File::write_token(FILE* f,
                       CXFile file,
                       CXToken tok,
                       const char* str,
                       unsigned line,
                       unsigned column)
{
  static bool preprocessor = false;
  static bool include = false;

  CXSourceLocation tloc = clang_getTokenLocation(tu_file_->tu(), tok);
  CXCursor c = clang_getCursor(tu_file_->tu(), tloc);

  if (cur_line_ <= line) cur_column_ = 1;

  for (; cur_line_ <= line; ++cur_line_)
    fprintf (f, "\n<a name=\"l%05i\"></a>%05i", cur_line_, cur_line_);

  for (; cur_column_ <= column; ++cur_column_)
    fprintf (f , " ");

  switch (clang_getTokenKind(tok)) {
  case (CXToken_Punctuation):
    if (str[0] == '#')
      preprocessor = true;
    fprintf(f, "%s", str);
    break;
  case (CXToken_Keyword):
    fprintf(f, "<span class=\"keyword\">%s</span>", str);
    break;
  case (CXToken_Comment):
    fprintf(f, "<span class=\"comment\">%s</span>", str);
    break;
  case (CXToken_Literal): {
    //include = false; // disable include links for now
    if (include) {
      include = false;
      // found an include file
      std::string t;
      const char* p = str;
      while (*p) {
        if (*p != '"')
          t += *p;
        ++p;
      }

      // first, use this file's path, then all the include paths
      bool found_include = false;
      char path[PATH_MAX];
      std::string includefile = realpath(dirname(tu_file_->source_filename()), path);
      includefile += "/" + t;
      struct stat st;
      if (stat(includefile.c_str(), &st) == 0) {
        found_include = true;
      } else {
        for (std::vector<std::string>::const_iterator i = includes_.begin(),
               e = includes_.end(); i != e; ++i) {
          includefile = realpath((*i).c_str(), path);
          includefile += "/" + t;
          if (stat(includefile.c_str(), &st) == 0) {
            found_include = true;
            break;
          }
        }
      }
      if (found_include) {
        if (files_.find(includefile) != files_.end()) {
          t = make_filename(includefile, html_dir_, prefix_, ".html", false);
          fprintf(f, "<a class=\"code\" href=\"%s\" title="">%s</a>",
                  t.c_str(), str);
          break;
        }
        std::map<std::string, Definition>::iterator i = defmap_.find(includefile);
        if (i != defmap_.end()) {
          t = i->second.file.c_str();
          fprintf(f, "<a class=\"code\" href=\"%s\" title="">%s</a>",
                  t.c_str(), str);
          break;
        }
      }
    }
    // not an include or include not found
    std::string s = fix(str);
    fprintf(f, "%s",  s.c_str() );
    break;
  }
  case (CXToken_Identifier): {
    if (preprocessor) {
      preprocessor = false;
      if (strcmp(str, "include") == 0)
        include = true;
      fprintf(f, "<span class=\"code\">%s</span>", str);
      break;
    }

    if (clang_isUnexposed(c.kind)) {
      fprintf(f, "<span class=\"code\">%s</span>", str);
      fprintf(f, "<!-- origin line: %i : %s : kind = %i -->",
              __LINE__, str, c.kind);
      break;
    }

    // Calling clang_getCursorDefinition() does not work properly
    // for template classes, i.e., it will find the method
    // declaration, not the definition, if they differ.  However,
    // once you have the declaration's location, you can use it
    // get that cursor, and find the definition that way.
    CXSourceLocation decloc =
      clang_getCursorLocation(clang_getCursorDefinition(c));
    CXCursor cref =
      clang_getCursorDefinition(clang_getCursor(tu_file_->tu(),
                                                decloc));

    if (clang_isUnexposed(cref.kind)) {
      fprintf(f, "<span class=\"code\">%s</span>", str);
          fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                  __LINE__, str, cref.kind);
      break;
    }

    std::string rfile;
    std::string html_dir;
    unsigned refl = line;
    bool found = false;

    if (!clang_Cursor_isNull(cref) && cref.kind != CXCursor_Namespace) {
      CXSourceLocation refloc = clang_getCursorLocation(cref);
      if (!clang_equalLocations(tloc, refloc)) {
        CXFile cxfile;
        unsigned col;
        unsigned off;
        clang_getExpansionLocation(refloc, &cxfile, &refl, &col, &off);
        if (cxfile == file) {
          found = true;
          fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                  __LINE__, str, cref.kind);
        }
        else {
          CXString cxfn = clang_getFileName(cxfile);
          const char* fn = clang_getCString(cxfn);
          if (fn) {
            if (files_.find(fn) != files_.end()) {
              rfile = fn;
              found = true;
              fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                      __LINE__, str, cref.kind);
            }
          }
          clang_disposeString(cxfn);
        }
      }
    }
    else if (!clang_isDeclaration(c.kind) && c.kind != CXCursor_Namespace) {
      CXCursor ref = clang_getCursorReferenced(c);
      if (ref.kind != CXCursor_Namespace) {
        std::string fsn = munge_fullyscopedname(fullyScopedName(ref));
        if (fsn.empty()) {
            fprintf(f, "<!-- origin line: %i : (fsn empty) %s : kind = %i -->",
                    __LINE__, str, c.kind);
        } else {
          std::map<std::string, Definition>::iterator r = defmap_.find(fsn);
          if (r != defmap_.end()) {
            found = true;
            fprintf(f, "<!-- origin line: %i : %s : kind = %i -->",
                    __LINE__, fsn.c_str(), c.kind);
            rfile = r->second.file.c_str();
            html_dir = r->second.html_path.c_str();
            refl = r->second.line;
          }
        }
      }
    }

    // since we are linking to lines, no need to link to same line
    if (found && (!rfile.empty() || refl != line)) {
      if (!rfile.empty())
        rfile = make_filename(rfile, html_dir, prefix_, ".html", !html_dir.empty());
      fprintf(f, "<a class=\"code\" href=\"%s#l%05i\" title="">%s</a>",
              rfile.c_str(), refl , str);
      break;
    }
    fprintf(f, "<span class=\"code\">%s</span>", str);
    break;
  }
  }
  cur_column_ += strlen(str);
}
Ejemplo n.º 8
0
void source_location::expansion_location(CXFile *file, unsigned *line, unsigned *column, unsigned *offset) const
{
    clang_getExpansionLocation(loc, file, line, column, offset);
}