Jacob Dufault
8 years ago
20 changed files with 11 additions and 544 deletions
@ -1,54 +0,0 @@ |
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3 -Wall -Wextra -Wno-unused-parameter -Wno-reorder") |
|||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) |
|||
|
|||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_HOME_DIRECTORY}/cmake/Modules/") |
|||
|
|||
message("Searcing for libclang") |
|||
#LIBCLANG_FOUND System has libclang. |
|||
#LIBCLANG_INCLUDE_DIRS The libclang include directories. |
|||
#LIBCLANG_LIBRARIES The libraries needed to use libclang. |
|||
#LIBCLANG_LIBRARY_DIR The path to the directory containing libclang. |
|||
#LIBCLANG_KNOWN_LLVM_VERSIONS Known LLVM release numbers. |
|||
find_package(LibClang REQUIRED) |
|||
|
|||
set(header_files |
|||
clangmm.h |
|||
CodeCompleteResults.h |
|||
CompilationDatabase.h |
|||
CompileCommand.h |
|||
CompileCommands.h |
|||
CompletionString.h |
|||
Cursor.h |
|||
Index.h |
|||
SourceLocation.h |
|||
SourceRange.h |
|||
Token.h |
|||
Tokens.h |
|||
TranslationUnit.h |
|||
Diagnostic.h |
|||
Utility.h |
|||
) |
|||
set(cc_files |
|||
CodeCompleteResults.cc |
|||
CompilationDatabase.cc |
|||
CompileCommand.cc |
|||
CompileCommands.cc |
|||
CompletionString.cc |
|||
Cursor.cc |
|||
Index.cc |
|||
SourceLocation.cc |
|||
SourceRange.cc |
|||
Token.cc |
|||
Tokens.cc |
|||
TranslationUnit.cc |
|||
Diagnostic.cc |
|||
Utility.cc |
|||
) |
|||
|
|||
add_library(${project_name} SHARED ${header_files} ${cc_files}) |
|||
|
|||
include_directories(${LIBCLANG_INCLUDE_DIRS}) |
|||
target_link_libraries(${project_name} ${LIBCLANG_LIBRARIES}) |
|||
|
|||
install(TARGETS ${project_name} RUNTIME DESTINATION bin LIBRARY DESTINATION lib) |
|||
install(FILES ${header_files} DESTINATION include/libclangmm) |
@ -1,45 +0,0 @@ |
|||
#include "CodeCompleteResults.h" |
|||
#include "CompletionString.h" |
|||
#include <exception> |
|||
#include "Utility.h" |
|||
|
|||
clang::CodeCompleteResults::CodeCompleteResults(CXTranslationUnit &cx_tu, |
|||
const std::string &buffer, |
|||
unsigned line_num, unsigned column) { |
|||
CXUnsavedFile files[1]; |
|||
auto file_path=ToString(clang_getTranslationUnitSpelling(cx_tu)); |
|||
files[0].Filename = file_path.c_str(); |
|||
files[0].Contents = buffer.c_str(); |
|||
files[0].Length = buffer.size(); |
|||
|
|||
cx_results = clang_codeCompleteAt(cx_tu, |
|||
file_path.c_str(), |
|||
line_num, |
|||
column, |
|||
files, |
|||
1, |
|||
clang_defaultCodeCompleteOptions()|CXCodeComplete_IncludeBriefComments); |
|||
if(cx_results!=nullptr) |
|||
clang_sortCodeCompletionResults(cx_results->Results, cx_results->NumResults); |
|||
} |
|||
|
|||
clang::CodeCompleteResults::~CodeCompleteResults() { |
|||
clang_disposeCodeCompleteResults(cx_results); |
|||
} |
|||
|
|||
unsigned clang::CodeCompleteResults::size() const { |
|||
if(cx_results==nullptr) |
|||
return 0; |
|||
return cx_results->NumResults; |
|||
} |
|||
|
|||
clang::CompletionString clang::CodeCompleteResults::get(unsigned i) const { |
|||
if (i >= size()) { |
|||
throw std::invalid_argument("clang::CodeCompleteResults::get(unsigned i): i>=size()"); |
|||
} |
|||
return CompletionString(cx_results->Results[i].CompletionString); |
|||
} |
|||
|
|||
std::string clang::CodeCompleteResults::get_usr() const { |
|||
return ToString(clang_codeCompleteGetContainerUSR(cx_results)); |
|||
} |
@ -1,23 +0,0 @@ |
|||
#ifndef CODECOMPLETERESULTS_H_ |
|||
#define CODECOMPLETERESULTS_H_ |
|||
#include <clang-c/Index.h> |
|||
#include <map> |
|||
#include <string> |
|||
#include "CompletionString.h" |
|||
|
|||
namespace clang { |
|||
class CodeCompleteResults { |
|||
friend class TranslationUnit; |
|||
|
|||
CodeCompleteResults(CXTranslationUnit &cx_tu, const std::string &buffer, |
|||
unsigned line_num, unsigned column); |
|||
public: |
|||
~CodeCompleteResults(); |
|||
CompletionString get(unsigned index) const; |
|||
unsigned size() const; |
|||
std::string get_usr() const; |
|||
|
|||
CXCodeCompleteResults *cx_results; |
|||
}; |
|||
} // namespace clang
|
|||
#endif // CODECOMPLETERESULTS_H_
|
@ -1,28 +0,0 @@ |
|||
#include "CompletionString.h" |
|||
#include "Utility.h" |
|||
|
|||
clang::CompletionString:: |
|||
CompletionString(const CXCompletionString &cx_completion_sting) : cx_completion_sting(cx_completion_sting) {} |
|||
|
|||
bool clang::CompletionString::available() { |
|||
return clang_getCompletionAvailability(cx_completion_sting) == CXAvailability_Available; |
|||
} |
|||
|
|||
unsigned clang::CompletionString::get_num_chunks() { |
|||
return clang_getNumCompletionChunks(cx_completion_sting); |
|||
} |
|||
|
|||
std::vector<clang::CompletionChunk> clang::CompletionString::get_chunks() { |
|||
std::vector<CompletionChunk> res; |
|||
for (unsigned i = 0; i < get_num_chunks(); i++) { |
|||
res.emplace_back(ToString(clang_getCompletionChunkText(cx_completion_sting, i)), static_cast<CompletionChunkKind> (clang_getCompletionChunkKind(cx_completion_sting, i))); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
std::string clang::CompletionString::get_brief_comments() { |
|||
return ToString(clang_getCompletionBriefComment(cx_completion_sting)); |
|||
} |
|||
|
|||
clang::CompletionChunk::CompletionChunk(std::string chunk, CompletionChunkKind kind) : |
|||
chunk(chunk), kind(kind) { } |
@ -1,40 +0,0 @@ |
|||
#ifndef COMPLETIONSTRING_H_ |
|||
#define COMPLETIONSTRING_H_ |
|||
#include <clang-c/Index.h> |
|||
#include <string> |
|||
#include <vector> |
|||
|
|||
namespace clang { |
|||
enum CompletionChunkKind { |
|||
CompletionChunk_Optional, CompletionChunk_TypedText, |
|||
CompletionChunk_Text, CompletionChunk_Placeholder, |
|||
CompletionChunk_Informative, CompletionChunk_CurrentParameter, |
|||
CompletionChunk_LeftParen, CompletionChunk_RightParen, |
|||
CompletionChunk_LeftBracket, CompletionChunk_RightBracket, |
|||
CompletionChunk_LeftBrace, CompletionChunk_RightBrace, |
|||
CompletionChunk_LeftAngle, CompletionChunk_RightAngle, |
|||
CompletionChunk_Comma, CompletionChunk_ResultType, |
|||
CompletionChunk_Colon, CompletionChunk_SemiColon, |
|||
CompletionChunk_Equal, CompletionChunk_HorizontalSpace, |
|||
CompletionChunk_VerticalSpace |
|||
}; |
|||
|
|||
class CompletionChunk { |
|||
public: |
|||
CompletionChunk(std::string chunk, CompletionChunkKind kind); |
|||
std::string chunk; |
|||
CompletionChunkKind kind; |
|||
}; |
|||
|
|||
class CompletionString { |
|||
public: |
|||
explicit CompletionString(const CXCompletionString &cx_completion_sting); |
|||
bool available(); |
|||
std::vector<CompletionChunk> get_chunks(); |
|||
std::string get_brief_comments(); |
|||
unsigned get_num_chunks(); |
|||
|
|||
CXCompletionString cx_completion_sting; |
|||
}; |
|||
} // namespace clang
|
|||
#endif // COMPLETIONSTRING_H_
|
@ -1,44 +0,0 @@ |
|||
#if false |
|||
#include "Diagnostic.h" |
|||
#include "SourceLocation.h" |
|||
#include "Tokens.h" |
|||
#include "Utility.h" |
|||
|
|||
clang::Diagnostic::Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic) { |
|||
severity=clang_getDiagnosticSeverity(cx_diagnostic); |
|||
severity_spelling=get_severity_spelling(severity); |
|||
spelling=ToString(clang_getDiagnosticSpelling(cx_diagnostic)); |
|||
|
|||
SourceLocation start_location(clang_getDiagnosticLocation(cx_diagnostic)); |
|||
path=start_location.get_path(); |
|||
auto start_offset=start_location.get_offset(); |
|||
Tokens tokens(cx_tu, SourceRange(start_location, start_location)); |
|||
if(tokens.size()==1) |
|||
offsets={start_offset, tokens.begin()->offsets.second}; |
|||
|
|||
unsigned num_fix_its=clang_getDiagnosticNumFixIts(cx_diagnostic); |
|||
for(unsigned c=0;c<num_fix_its;c++) { |
|||
CXSourceRange fix_it_range; |
|||
auto source=ToString(clang_getDiagnosticFixIt(cx_diagnostic, c, &fix_it_range)); |
|||
fix_its.emplace_back(source, SourceRange(fix_it_range).get_offsets()); |
|||
} |
|||
} |
|||
|
|||
const std::string clang::Diagnostic::get_severity_spelling(unsigned severity) { |
|||
switch(severity) { |
|||
case CXDiagnostic_Ignored: |
|||
return "Ignored"; |
|||
case CXDiagnostic_Note: |
|||
return "Note"; |
|||
case CXDiagnostic_Warning: |
|||
return "Warning"; |
|||
case CXDiagnostic_Error: |
|||
return "Error"; |
|||
case CXDiagnostic_Fatal: |
|||
return "Fatal"; |
|||
default: |
|||
return ""; |
|||
} |
|||
} |
|||
|
|||
#endif |
@ -1,34 +0,0 @@ |
|||
#if false |
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <vector> |
|||
#include <clang-c/Index.h> |
|||
#include "SourceRange.h" |
|||
|
|||
namespace clang { |
|||
|
|||
class Diagnostic { |
|||
public: |
|||
friend class TranslationUnit; |
|||
Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic); |
|||
//class FixIt {
|
|||
//public:
|
|||
// FixIt(const std::string &source, const std::pair<clang::Offset, clang::Offset> &offsets) :
|
|||
// source(source), offsets(offsets) {}
|
|||
// std::string source;
|
|||
// std::pair<clang::Offset, clang::Offset> offsets;
|
|||
//};
|
|||
|
|||
static const std::string get_severity_spelling(unsigned severity); |
|||
|
|||
unsigned severity; |
|||
std::string severity_spelling; |
|||
std::string spelling; |
|||
std::string path; |
|||
std::pair<clang::Offset, clang::Offset> offsets; |
|||
std::vector<FixIt> fix_its; |
|||
}; |
|||
|
|||
} |
|||
#endif |
@ -1,12 +0,0 @@ |
|||
#include "SourceRange.h" |
|||
|
|||
/*
|
|||
clang::SourceRange::SourceRange(clang::SourceLocation &start, clang::SourceLocation &end) { |
|||
cx_range = clang_getRange(start.cx_location, end.cx_location); |
|||
} |
|||
|
|||
std::pair<clang::Offset, clang::Offset> clang::SourceRange::get_offsets() { |
|||
SourceLocation start(clang_getRangeStart(cx_range)), end(clang_getRangeEnd(cx_range)); |
|||
return {start.get_offset(), end.get_offset()}; |
|||
} |
|||
*/ |
@ -1,18 +0,0 @@ |
|||
#ifndef SOURCERANGE_H_ |
|||
#define SOURCERANGE_H_ |
|||
#include <clang-c/Index.h> |
|||
#include <string> |
|||
#include <utility> |
|||
|
|||
namespace clang { |
|||
class SourceRange { |
|||
public: |
|||
/*
|
|||
SourceRange(const CXSourceRange& cx_range) : cx_range(cx_range) {} |
|||
SourceRange(SourceLocation &start, SourceLocation &end); |
|||
std::pair<clang::Offset, clang::Offset> get_offsets(); |
|||
CXSourceRange cx_range; |
|||
*/ |
|||
}; |
|||
} // namespace clang
|
|||
#endif // SOURCERANGE_H_
|
@ -1,49 +0,0 @@ |
|||
#if false |
|||
#include "Token.h" |
|||
#include "Utility.h" |
|||
|
|||
// // // // //
|
|||
// Token //
|
|||
// // // // //
|
|||
|
|||
// returns gets an source location for this token objekt
|
|||
// based on the translationunit given
|
|||
clang::SourceLocation clang::Token::get_source_location() const { |
|||
return SourceLocation(clang_getTokenLocation(cx_tu, cx_token)); |
|||
} |
|||
|
|||
// returns a sourcerange that covers this token
|
|||
clang::SourceRange clang::Token::get_source_range() const { |
|||
return SourceRange(clang_getTokenExtent(cx_tu, cx_token)); |
|||
} |
|||
// returns a string description of this tokens kind
|
|||
std::string clang::Token::get_spelling() const { |
|||
return ToString(clang_getTokenSpelling(cx_tu, cx_token)); |
|||
} |
|||
|
|||
clang::Token::Kind clang::Token::get_kind() const { |
|||
return static_cast<Kind>(clang_getTokenKind(cx_token)); |
|||
} |
|||
|
|||
bool clang::Token::is_identifier() const { |
|||
auto token_kind=get_kind(); |
|||
auto cursor=get_cursor(); |
|||
if(token_kind==clang::Token::Kind::Identifier && cursor.is_valid_kind()) |
|||
return true; |
|||
else if(token_kind==clang::Token::Kind::Keyword && cursor.is_valid_kind()) { |
|||
auto spelling=get_spelling(); |
|||
if(spelling=="operator" || (spelling=="bool" && get_cursor().get_spelling()=="operator bool")) |
|||
return true; |
|||
} |
|||
else if(token_kind==clang::Token::Kind::Punctuation && cursor.is_valid_kind()) { |
|||
auto referenced=get_cursor().get_referenced(); |
|||
if(referenced) { |
|||
auto referenced_kind=referenced.get_kind(); |
|||
if(referenced_kind== CXCursor_FunctionDecl || referenced_kind==CXCursor_CXXMethod || referenced_kind==CXCursor_Constructor) |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
#endif |
@ -1,41 +0,0 @@ |
|||
#if false |
|||
#ifndef TOKEN_H_ |
|||
#define TOKEN_H_ |
|||
#include <clang-c/Index.h> |
|||
#include "SourceLocation.h" |
|||
#include "SourceRange.h" |
|||
#include "Cursor.h" |
|||
#include <string> |
|||
|
|||
namespace clang { |
|||
class Token { |
|||
friend class Tokens; |
|||
public: |
|||
enum Kind { |
|||
Punctuation, |
|||
Keyword, |
|||
Identifier, |
|||
Literal, |
|||
Comment |
|||
}; |
|||
private: |
|||
Token(CXTranslationUnit &cx_tu, CXToken &cx_token, CXCursor &cx_cursor): |
|||
cx_tu(cx_tu), cx_token(cx_token), cx_cursor(cx_cursor), offsets(get_source_range().get_offsets()) {}; |
|||
public: |
|||
Kind get_kind() const; |
|||
std::string get_spelling() const; |
|||
SourceLocation get_source_location() const; |
|||
SourceRange get_source_range() const; |
|||
clang::Cursor get_cursor() const {return clang::Cursor(cx_cursor);} |
|||
|
|||
bool is_identifier() const; |
|||
|
|||
CXTranslationUnit &cx_tu; |
|||
CXToken& cx_token; |
|||
CXCursor& cx_cursor; |
|||
std::pair<clang::Offset, clang::Offset> offsets; |
|||
}; |
|||
} // namespace clang
|
|||
#endif // TOKEN_H_
|
|||
|
|||
#endif |
@ -1,39 +0,0 @@ |
|||
#if false |
|||
#include "Tokens.h" |
|||
#include "Utility.h" |
|||
|
|||
clang::Tokens::Tokens(CXTranslationUnit &cx_tu, const SourceRange &range): cx_tu(cx_tu) { |
|||
clang_tokenize(cx_tu, range.cx_range, &cx_tokens, &num_tokens); |
|||
cx_cursors.resize(num_tokens); |
|||
clang_annotateTokens(cx_tu, cx_tokens, num_tokens, cx_cursors.data()); |
|||
for (unsigned i = 0; i < num_tokens; i++) { |
|||
if(cx_cursors[i].kind==CXCursor_DeclRefExpr) { //Temporary fix to a libclang bug
|
|||
auto real_cursor=clang_getCursor(cx_tu, clang_getTokenLocation(cx_tu, cx_tokens[i])); |
|||
cx_cursors[i]=real_cursor; |
|||
} |
|||
emplace_back(Token(cx_tu, cx_tokens[i], cx_cursors[i])); |
|||
} |
|||
} |
|||
|
|||
clang::Tokens::~Tokens() { |
|||
clang_disposeTokens(cx_tu, cx_tokens, size()); |
|||
} |
|||
|
|||
//This works across TranslationUnits! However, to get rename refactoring to work,
|
|||
//one have to open all the files that might include a similar token
|
|||
//Similar tokens defined as tokens with equal referenced cursors.
|
|||
std::vector<std::pair<clang::Offset, clang::Offset> > clang::Tokens::get_similar_token_offsets(CXCursorKind kind, |
|||
const std::string &spelling, |
|||
const std::string &usr) { |
|||
std::vector<std::pair<Offset, Offset> > offsets; |
|||
for(auto &token: *this) { |
|||
if(token.is_identifier()) { |
|||
auto referenced=token.get_cursor().get_referenced(); |
|||
if(referenced && kind==referenced.get_kind() && spelling==token.get_spelling() && usr==referenced.get_usr()) |
|||
offsets.emplace_back(token.offsets); |
|||
} |
|||
} |
|||
return offsets; |
|||
} |
|||
|
|||
#endif |
@ -1,29 +0,0 @@ |
|||
#if false |
|||
#ifndef TOKENS_H_ |
|||
#define TOKENS_H_ |
|||
#include <clang-c/Index.h> |
|||
#include "SourceRange.h" |
|||
#include "Token.h" |
|||
#include <unordered_map> |
|||
#include <vector> |
|||
|
|||
namespace clang { |
|||
class Tokens : public std::vector<clang::Token> { |
|||
friend class TranslationUnit; |
|||
friend class Diagnostic; |
|||
Tokens(CXTranslationUnit &cx_tu, const SourceRange &range); |
|||
public: |
|||
~Tokens(); |
|||
std::vector<std::pair<clang::Offset, clang::Offset> > get_similar_token_offsets(CXCursorKind kind, |
|||
const std::string &spelling, |
|||
const std::string &usr); |
|||
private: |
|||
CXToken *cx_tokens; |
|||
unsigned num_tokens; |
|||
std::vector<CXCursor> cx_cursors; |
|||
CXTranslationUnit& cx_tu; |
|||
}; |
|||
} // namespace clang
|
|||
#endif // TOKENS_H_
|
|||
|
|||
#endif |
@ -1,13 +0,0 @@ |
|||
#ifndef CLANGMM_H_ |
|||
#define CLANGMM_H_ |
|||
#include "TranslationUnit.h" |
|||
#include "SourceRange.h" |
|||
#include "Token.h" |
|||
#include "Tokens.h" |
|||
#include "CodeCompleteResults.h" |
|||
#include "CompletionString.h" |
|||
#include "Index.h" |
|||
#include "Cursor.h" |
|||
#include "Diagnostic.h" |
|||
#include "Utility.h" |
|||
#endif // CLANGMM_H_
|
Loading…
Reference in new issue