Browse Source

Added diagnostics.

merge-requests/37/head
eidheim 11 years ago
parent
commit
f313af410c
  1. 1
      src/CMakeLists.txt
  2. 20
      src/Diagnostic.h
  3. 2
      src/SourceLocation.h
  4. 35
      src/TranslationUnit.cc
  5. 3
      src/TranslationUnit.h
  6. 1
      src/clangmm.h
  7. 3
      tests/CMakeLists.txt
  8. 32
      tests/Diagnostics_Test.cc

1
src/CMakeLists.txt

@ -25,6 +25,7 @@ set(header_files
Token.h
Tokens.h
TranslationUnit.h
Diagnostic.h
)
set(cc_files
CodeCompleteResults.cc

20
src/Diagnostic.h

@ -0,0 +1,20 @@
#ifndef DIAGNOSTICS_H_
#define DIAGNOSTICS_H_
#include "TranslationUnit.h"
namespace clang {
class Diagnostic {
public:
class LocationData {
public:
unsigned line, column, offset;
};
unsigned severity;
std::string spelling;
std::string path;
LocationData start_location, end_location;
};
}
#endif // DIAGNOSTICS_H_

2
src/SourceLocation.h

@ -21,6 +21,8 @@ namespace clang {
const std::string &filepath,
int offset);
SourceLocation(CXSourceLocation location) {location_=location;}
explicit SourceLocation(Cursor *cursor);
void get_location_info(std::string* path,

35
src/TranslationUnit.cc

@ -1,4 +1,6 @@
#include "TranslationUnit.h"
#include "SourceLocation.h"
#include "Tokens.h"
clang::TranslationUnit::
~TranslationUnit() {
@ -87,3 +89,36 @@ ReparseTranslationUnit(const std::string &file_path,
unsigned clang::TranslationUnit::DefaultFlags() {
return CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_Incomplete;
}
std::vector<clang::Diagnostic> clang::TranslationUnit::get_diagnostics() {
std::vector<clang::Diagnostic> diagnostics;
for(unsigned c=0;c<clang_getNumDiagnostics(tu_);c++) {
CXDiagnostic clang_diagnostic=clang_getDiagnostic(tu_, c);
diagnostics.emplace_back();
auto& diagnostic=diagnostics.back();
diagnostic.severity=clang_getDiagnosticSeverity(clang_diagnostic);
diagnostic.spelling=clang_getCString(clang_getDiagnosticSpelling(clang_diagnostic));
SourceLocation location(clang_getDiagnosticLocation(clang_diagnostic));
std::string path;
unsigned line, column, offset;
location.get_location_info(&path, &line, &column, &offset);
diagnostic.path=path;
diagnostic.start_location.line=line;
diagnostic.start_location.column=column;
diagnostic.start_location.offset=offset;
clang::SourceRange range(&location, &location);
clang::Tokens tokens(this, &range);
if(tokens.tokens().size()==1) {
auto& token=tokens.tokens()[0];
clang::SourceRange range=token.get_source_range(this);
clang::SourceLocation end_location(&range, false);
end_location.get_location_info(NULL, &line, &column, &offset);
diagnostic.end_location.line=line;
diagnostic.end_location.column=column;
diagnostic.end_location.offset=offset;
}
}
return diagnostics;
}

3
src/TranslationUnit.h

@ -6,6 +6,7 @@
#include <map>
#include <memory>
#include "Index.h"
#include "Diagnostic.h"
namespace clang {
class Token;
@ -34,6 +35,8 @@ namespace clang {
&buffers,
unsigned flags=DefaultFlags());
static unsigned DefaultFlags();
std::vector<Diagnostic> get_diagnostics();
private:
friend Token;
friend Tokens;

1
src/clangmm.h

@ -12,4 +12,5 @@
#include "CompletionString.h"
#include "Index.h"
#include "Cursor.h"
#include "Diagnostic.h"
#endif // CLANGMM_H_

3
tests/CMakeLists.txt

@ -1,6 +1,6 @@
set(project_tests ${project_name}_tests)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_HOME_DIRECTORY}/cmake/Modules/")
@ -23,6 +23,7 @@ add_executable(${project_tests}
Cursor_H_Test.cc
Token_H_Test.cc
SourceLocation_H_Test.cc
Diagnostics_Test.cc
)
include_directories(${LIBCLANG_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} "${CMAKE_SOURCE_DIR}/src")

32
tests/Diagnostics_Test.cc

@ -0,0 +1,32 @@
#include <boost/test/unit_test.hpp>
#include "clangmm.h"
#include <iostream>
#include <fstream>
using namespace std;
BOOST_AUTO_TEST_CASE(diagnostics_test) {
std::string path("./case/main_error.cpp");
clang::Index index(0, 0);
std::map<std::string, std::string> map_buffers;
ifstream ifs(path, ifstream::in);
stringstream ss;
ss << ifs.rdbuf();
map_buffers["./case/main_error.cpp"]=ss.str();
std::vector<std::string> args;
clang::TranslationUnit tu(&index, path, args, map_buffers);
auto diagnostics=tu.get_diagnostics();
BOOST_CHECK(diagnostics.size()==1);
BOOST_CHECK(diagnostics[0].spelling=="use of undeclared identifier 'undeclared_variable'");
BOOST_CHECK(diagnostics[0].path=="./case/main_error.cpp");
BOOST_CHECK(diagnostics[0].severity==3);
BOOST_CHECK(diagnostics[0].start_location.line==5);
BOOST_CHECK(diagnostics[0].end_location.line==5);
BOOST_CHECK(diagnostics[0].start_location.column==16);
BOOST_CHECK(diagnostics[0].end_location.column==35);
}
Loading…
Cancel
Save