This commit is contained in:
Jacob Dufault 2017-02-16 01:35:30 -08:00
commit 5dbde940b6
33 changed files with 1319 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
.vs
Debug
x64
*.swp
*.sln
*.vcxproj
*.vcxproj.filters

54
libclangmm/CMakeLists.txt Normal file
View File

@ -0,0 +1,54 @@
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)

View File

@ -0,0 +1,45 @@
#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=to_string(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 to_string(clang_codeCompleteGetContainerUSR(cx_results));
}

View File

@ -0,0 +1,23 @@
#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_

View File

@ -0,0 +1,14 @@
#include "CompilationDatabase.h"
#include <exception>
clang::CompilationDatabase::CompilationDatabase(const std::string &project_path) {
CXCompilationDatabase_Error error;
cx_db = clang_CompilationDatabase_fromDirectory(project_path.c_str(), &error);
if(error) {
//TODO: compile_commands.json is missing, create it?
}
}
clang::CompilationDatabase::~CompilationDatabase() {
clang_CompilationDatabase_dispose(cx_db);
}

View File

@ -0,0 +1,18 @@
#ifndef COMPILATIONDATABASE_H_
#define COMPILATIONDATABASE_H_
#include <clang-c/CXCompilationDatabase.h>
#include <clang-c/Index.h>
#include <string>
namespace clang {
class CompilationDatabase {
public:
explicit CompilationDatabase(const std::string &project_path);
~CompilationDatabase();
CXCompilationDatabase cx_db;
};
}
#endif // COMPILATIONDATABASE_H_

View File

@ -0,0 +1,21 @@
#include "CompileCommand.h"
#include "CompileCommands.h"
#include "Utility.h"
std::string clang::CompileCommand::get_command() {
std::string res;
unsigned N = clang_CompileCommand_getNumArgs(cx_command);
for (unsigned i = 0; i < N; i++) {
res += to_string(clang_CompileCommand_getArg(cx_command, i));
}
return res;
}
std::vector<std::string> clang::CompileCommand::get_command_as_args() {
unsigned N = clang_CompileCommand_getNumArgs(cx_command);
std::vector<std::string> res(N);
for (unsigned i = 0; i < N; i++) {
res[i] = to_string(clang_CompileCommand_getArg(cx_command, i));
}
return res;
}

View File

@ -0,0 +1,17 @@
#ifndef COMPILECOMMAND_H_
#define COMPILECOMMAND_H_
#include <clang-c/CXCompilationDatabase.h>
#include <vector>
#include <string>
namespace clang {
class CompileCommand {
public:
CompileCommand(const CXCompileCommand& cx_command) : cx_command(cx_command) {};
std::string get_command();
std::vector<std::string> get_command_as_args();
CXCompileCommand cx_command;
};
}
#endif // COMPILECOMMAND_H_

View File

@ -0,0 +1,21 @@
#include "CompileCommands.h"
clang::CompileCommands::CompileCommands(const std::string &filename, CompilationDatabase &db) {
cx_commands =
clang_CompilationDatabase_getCompileCommands(db.cx_db, filename.c_str());
if(clang_CompileCommands_getSize(cx_commands)==0)
cx_commands = clang_CompilationDatabase_getAllCompileCommands(db.cx_db);
}
clang::CompileCommands::~CompileCommands() {
clang_CompileCommands_dispose(cx_commands);
}
std::vector<clang::CompileCommand> clang::CompileCommands::get_commands() {
unsigned N = clang_CompileCommands_getSize(cx_commands);
std::vector<CompileCommand> res;
for (unsigned i = 0; i < N; i++) {
res.emplace_back(clang_CompileCommands_getCommand(cx_commands, i));
}
return res;
}

View File

@ -0,0 +1,19 @@
#ifndef COMPILECOMMANDS_H_
#define COMPILECOMMANDS_H_
#include "CompilationDatabase.h"
#include "CompileCommand.h"
#include <clang-c/CXCompilationDatabase.h>
#include <string>
#include <vector>
namespace clang {
class CompileCommands {
public:
CompileCommands(const std::string &filename, CompilationDatabase &db);
std::vector<CompileCommand> get_commands();
~CompileCommands();
CXCompileCommands cx_commands;
};
}
#endif // COMPILECOMMANDS_H_

View File

@ -0,0 +1,28 @@
#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(to_string(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 to_string(clang_getCompletionBriefComment(cx_completion_sting));
}
clang::CompletionChunk::CompletionChunk(std::string chunk, CompletionChunkKind kind) :
chunk(chunk), kind(kind) { }

View File

@ -0,0 +1,40 @@
#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_

138
libclangmm/Cursor.cc Normal file
View File

@ -0,0 +1,138 @@
#include "Cursor.h"
#include "Utility.h"
#include <algorithm>
namespace clang {
std::string Cursor::Type::get_spelling() const {
return to_string(clang_getTypeSpelling(cx_type));
}
Cursor::Type Cursor::Type::get_result() const {
return Type(clang_getResultType(cx_type));
}
Cursor::Cursor() = default;
Cursor::Cursor(const CXCursor& other) : cx_cursor(cx_cursor) {}
bool Cursor::Type::operator==(const Cursor::Type& rhs) const {
return clang_equalTypes(cx_type, rhs.cx_type);
}
CXCursorKind Cursor::get_kind() const {
return clang_getCursorKind(cx_cursor);
}
Cursor::Type Cursor::get_type() const {
return Type(clang_getCursorType(cx_cursor));
}
SourceLocation Cursor::get_source_location() const {
return SourceLocation(clang_getCursorLocation(cx_cursor));
}
SourceRange Cursor::get_source_range() const {
return SourceRange(clang_getCursorExtent(cx_cursor));
}
std::string Cursor::get_spelling() const {
return to_string(clang_getCursorSpelling(cx_cursor));
}
std::string Cursor::get_display_name() const {
return to_string(clang_getCursorDisplayName(cx_cursor));
}
std::string Cursor::get_usr() const {
return to_string(clang_getCursorUSR(cx_cursor));
}
Cursor Cursor::get_referenced() const {
return Cursor(clang_getCursorReferenced(cx_cursor));
}
Cursor Cursor::get_canonical() const {
return Cursor(clang_getCanonicalCursor(cx_cursor));
}
Cursor Cursor::get_definition() const {
return Cursor(clang_getCursorDefinition(cx_cursor));
}
Cursor Cursor::get_semantic_parent() const {
return Cursor(clang_getCursorSemanticParent(cx_cursor));
}
std::vector<Cursor> Cursor::get_arguments() const {
auto size = clang_Cursor_getNumArguments(cx_cursor);
std::vector<Cursor> cursors(size);
for (int c = 0; c < size; ++c)
cursors.emplace_back(clang_Cursor_getArgument(cx_cursor, c));
return cursors;
}
Cursor::operator bool() const {
return !clang_Cursor_isNull(cx_cursor);
}
bool Cursor::operator==(const Cursor& rhs) const {
return clang_equalCursors(cx_cursor, rhs.cx_cursor);
}
bool Cursor::is_valid_kind() const {
CXCursor referenced = clang_getCursorReferenced(cx_cursor);
if (clang_Cursor_isNull(referenced))
return false;
CXCursorKind kind = get_kind();
return kind > CXCursor_UnexposedDecl &&
(kind < CXCursor_FirstInvalid || kind > CXCursor_LastInvalid);
}
std::string Cursor::get_type_description() const {
std::string spelling;
auto referenced = clang_getCursorReferenced(cx_cursor);
if (!clang_Cursor_isNull(referenced)) {
auto type = clang_getCursorType(referenced);
spelling = to_string(clang_getTypeSpelling(type));
#if CINDEX_VERSION_MAJOR==0 && CINDEX_VERSION_MINOR<32
const std::string auto_str = "auto";
if (spelling.size() >= 4 && std::equal(auto_str.begin(), auto_str.end(), spelling.begin())) {
auto canonical_type = clang_getCanonicalType(clang_getCursorType(cx_cursor));
auto canonical_spelling = to_string(clang_getTypeSpelling(canonical_type));
if (spelling.size() > 5 && spelling[4] == ' ' && spelling[5] == '&' && spelling != canonical_spelling)
return canonical_spelling + " &";
else
return canonical_spelling;
}
const std::string const_auto_str = "const auto";
if (spelling.size() >= 10 && std::equal(const_auto_str.begin(), const_auto_str.end(), spelling.begin())) {
auto canonical_type = clang_getCanonicalType(clang_getCursorType(cx_cursor));
auto canonical_spelling = to_string(clang_getTypeSpelling(canonical_type));
if (spelling.size() > 11 && spelling[10] == ' ' && spelling[11] == '&' && spelling != canonical_spelling)
return canonical_spelling + " &";
else
return canonical_spelling;
}
#endif
}
if (spelling.empty())
return get_spelling();
return spelling;
}
std::string Cursor::get_brief_comments() const {
Cursor referenced = get_referenced();
if (referenced)
return to_string(clang_Cursor_getBriefCommentText(referenced.cx_cursor));
return "";
}
} // namespace clang

51
libclangmm/Cursor.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef CURSOR_H_
#define CURSOR_H_
#include <string>
#include <vector>
#include <clang-c/Index.h>
#include "SourceLocation.h"
#include "SourceRange.h"
namespace clang {
class Cursor {
public:
class Type {
public:
Type(const CXType &cx_type) : cx_type(cx_type) {}
std::string get_spelling() const;
Type get_result() const;
bool operator==(const Cursor::Type& rhs) const;
CXType cx_type;
};
Cursor();
explicit Cursor(const CXCursor& cx_cursor);
CXCursorKind get_kind() const;
Type get_type() const;
SourceLocation get_source_location() const;
SourceRange get_source_range() const;
std::string get_spelling() const;
std::string get_display_name() const;
std::string get_usr() const;
Cursor get_referenced() const;
Cursor get_canonical() const;
Cursor get_definition() const;
Cursor get_semantic_parent() const;
std::vector<Cursor> get_arguments() const;
operator bool() const;
bool operator==(const Cursor& rhs) const;
bool is_valid_kind() const;
std::string get_type_description() const;
std::string get_brief_comments() const;
CXCursor cx_cursor = clang_getNullCursor();
};
} // namespace clang
#endif // CURSOR_H_

41
libclangmm/Diagnostic.cc Normal file
View File

@ -0,0 +1,41 @@
#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=to_string(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=to_string(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 "";
}
}

32
libclangmm/Diagnostic.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef DIAGNOSTIC_H_
#define DIAGNOSTIC_H_
#include <string>
#include <vector>
#include <clang-c/Index.h>
#include "SourceRange.h"
namespace clang {
class Diagnostic {
friend class TranslationUnit;
Diagnostic(CXTranslationUnit& cx_tu, CXDiagnostic& cx_diagnostic);
public:
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 // DIAGNOSTIC_H_

9
libclangmm/Index.cc Normal file
View File

@ -0,0 +1,9 @@
#include "Index.h"
clang::Index::Index(int excludeDeclarationsFromPCH, int displayDiagnostics) {
cx_index = clang_createIndex(excludeDeclarationsFromPCH, displayDiagnostics);
}
clang::Index::~Index() {
clang_disposeIndex(cx_index);
}

13
libclangmm/Index.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef INDEX_H_
#define INDEX_H_
#include <clang-c/Index.h>
namespace clang {
class Index {
public:
Index(int excludeDeclarationsFromPCH, int displayDiagnostics);
~Index();
CXIndex cx_index;
};
} // namespace clang
#endif // INDEX_H_

View File

@ -0,0 +1,39 @@
#include "SourceLocation.h"
#include "Utility.h"
namespace clang {
SourceLocation::SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset) {
CXFile file = clang_getFile(tu, filepath.c_str());
cx_location = clang_getLocationForOffset(tu, file, offset);
}
SourceLocation::SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned line, unsigned column) {
CXFile file = clang_getFile(tu, filepath.c_str());
cx_location = clang_getLocation(tu, file, line, column);
}
std::string SourceLocation::get_path() {
std::string path;
get_data(&path, nullptr, nullptr, nullptr);
return path;
}
Offset SourceLocation::get_offset() {
unsigned line, index;
get_data(nullptr, &line, &index, nullptr);
return{ line, index };
}
void SourceLocation::get_data(std::string* path, unsigned *line, unsigned *column, unsigned *offset) {
if (path == nullptr)
clang_getExpansionLocation(cx_location, nullptr, line, column, offset);
else {
CXFile file;
clang_getExpansionLocation(cx_location, &file, line, column, offset);
if (file != nullptr) {
*path = to_string(clang_getFileName(file));
}
}
}
}

View File

@ -0,0 +1,38 @@
#ifndef SOURCELOCATION_H_
#define SOURCELOCATION_H_
#include <clang-c/Index.h>
#include <string>
namespace clang {
class Offset {
public:
Offset() {}
Offset(unsigned line, unsigned index) : line(line), index(index) {}
bool operator==(const clang::Offset &o) { return (line == o.line && index == o.index); }
bool operator!=(const clang::Offset &o) { return !(*this == o); }
unsigned line;
unsigned index; //byte index in line (not char number)
};
class SourceLocation {
friend class TranslationUnit;
SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned offset);
SourceLocation(CXTranslationUnit &tu, const std::string &filepath, unsigned line, unsigned column);
public:
SourceLocation(const CXSourceLocation& cx_location) : cx_location(cx_location) {}
public:
std::string get_path();
clang::Offset get_offset();
CXSourceLocation cx_location;
private:
void get_data(std::string *path, unsigned *line, unsigned *column, unsigned *offset);
};
} // namespace clang
#endif // SOURCELOCATION_H_

10
libclangmm/SourceRange.cc Normal file
View File

@ -0,0 +1,10 @@
#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()};
}

17
libclangmm/SourceRange.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SOURCERANGE_H_
#define SOURCERANGE_H_
#include <clang-c/Index.h>
#include "SourceLocation.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_

46
libclangmm/Token.cc Normal file
View File

@ -0,0 +1,46 @@
#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 to_string(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;
}

38
libclangmm/Token.h Normal file
View File

@ -0,0 +1,38 @@
#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_

36
libclangmm/Tokens.cc Normal file
View File

@ -0,0 +1,36 @@
#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;
}

26
libclangmm/Tokens.h Normal file
View File

@ -0,0 +1,26 @@
#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_

View File

@ -0,0 +1,128 @@
#include "TranslationUnit.h"
#include "SourceLocation.h"
#include "Tokens.h"
#include "Utility.h"
#include <fstream>
#include <sstream>
#include <iostream> //TODO: remove
using namespace std; //TODO: remove
clang::TranslationUnit::TranslationUnit(Index &index, const std::string &file_path,
const std::vector<std::string> &command_line_args,
const std::string &buffer, unsigned flags) {
std::vector<const char*> args;
for(auto &a: command_line_args) {
args.push_back(a.c_str());
}
CXUnsavedFile files[1];
files[0].Filename=file_path.c_str();
files[0].Contents=buffer.c_str();
files[0].Length=buffer.size();
cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(),
args.size(), files, 1, flags);
}
clang::TranslationUnit::TranslationUnit(Index &index, const std::string &file_path,
const std::vector<std::string> &command_line_args,
unsigned flags) {
std::vector<const char*> args;
for(auto &a: command_line_args) {
args.push_back(a.c_str());
}
cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(),
args.size(), nullptr, 0, flags);
}
clang::TranslationUnit::~TranslationUnit() {
clang_disposeTranslationUnit(cx_tu);
}
void clang::TranslationUnit::parse(Index &index, const std::string &file_path,
const std::vector<std::string> &command_line_args,
const std::map<std::string, std::string> &buffers, unsigned flags) {
std::vector<CXUnsavedFile> files;
for (auto &buffer : buffers) {
CXUnsavedFile file;
file.Filename = buffer.first.c_str();
file.Contents = buffer.second.c_str();
file.Length = buffer.second.size();
files.push_back(file);
}
std::vector<const char*> args;
for(auto &a: command_line_args) {
args.push_back(a.c_str());
}
cx_tu = clang_parseTranslationUnit(index.cx_index, file_path.c_str(), args.data(),
args.size(), files.data(), files.size(), flags);
}
int clang::TranslationUnit::ReparseTranslationUnit(const std::string &buffer, unsigned flags) {
CXUnsavedFile files[1];
auto file_path=to_string(clang_getTranslationUnitSpelling(cx_tu));
files[0].Filename=file_path.c_str();
files[0].Contents=buffer.c_str();
files[0].Length=buffer.size();
return clang_reparseTranslationUnit(cx_tu, 1, files, flags);
}
unsigned clang::TranslationUnit::DefaultFlags() {
auto flags=
CXTranslationUnit_CacheCompletionResults |
CXTranslationUnit_PrecompiledPreamble |
CXTranslationUnit_Incomplete |
CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
#if CINDEX_VERSION_MAJOR>0 || (CINDEX_VERSION_MAJOR==0 && CINDEX_VERSION_MINOR>=35)
flags|=CXTranslationUnit_KeepGoing;
#endif
return flags;
}
clang::CodeCompleteResults clang::TranslationUnit::get_code_completions(const std::string &buffer,
unsigned line_number, unsigned column) {
CodeCompleteResults results(cx_tu, buffer, line_number, column);
return results;
}
std::vector<clang::Diagnostic> clang::TranslationUnit::get_diagnostics() {
std::vector<Diagnostic> diagnostics;
for(unsigned c=0;c<clang_getNumDiagnostics(cx_tu);c++) {
CXDiagnostic clang_diagnostic=clang_getDiagnostic(cx_tu, c);
diagnostics.emplace_back(Diagnostic(cx_tu, clang_diagnostic));
clang_disposeDiagnostic(clang_diagnostic);
}
return diagnostics;
}
std::unique_ptr<clang::Tokens> clang::TranslationUnit::get_tokens(unsigned start_offset, unsigned end_offset) {
auto path=clang::to_string(clang_getTranslationUnitSpelling(cx_tu));
SourceLocation start_location(cx_tu, path, start_offset);
SourceLocation end_location(cx_tu, path, end_offset);
SourceRange range(start_location, end_location);
return std::unique_ptr<Tokens>(new Tokens(cx_tu, range));
}
std::unique_ptr<clang::Tokens> clang::TranslationUnit::get_tokens(unsigned start_line, unsigned start_column,
unsigned end_line, unsigned end_column) {
auto path=to_string(clang_getTranslationUnitSpelling(cx_tu));
SourceLocation start_location(cx_tu, path, start_line, start_column);
SourceLocation end_location(cx_tu, path, end_line, end_column);
SourceRange range(start_location, end_location);
return std::unique_ptr<Tokens>(new Tokens(cx_tu, range));
}
clang::Cursor clang::TranslationUnit::get_cursor(std::string path, unsigned offset) {
SourceLocation location(cx_tu, path, offset);
return Cursor(clang_getCursor(cx_tu, location.cx_location));
}
clang::Cursor clang::TranslationUnit::get_cursor(std::string path, unsigned line, unsigned column) {
SourceLocation location(cx_tu, path, line, column);
return Cursor(clang_getCursor(cx_tu, location.cx_location));
}

View File

@ -0,0 +1,54 @@
#ifndef TRANSLATIONUNIT_H_
#define TRANSLATIONUNIT_H_
#include <clang-c/Index.h>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include "Index.h"
#include "Diagnostic.h"
#include "Tokens.h"
#include "CodeCompleteResults.h"
#include "Cursor.h"
namespace clang {
class TranslationUnit {
public:
TranslationUnit(Index &index,
const std::string &file_path,
const std::vector<std::string> &command_line_args,
const std::string &buffer,
unsigned flags=DefaultFlags());
TranslationUnit(Index &index,
const std::string &file_path,
const std::vector<std::string> &command_line_args,
unsigned flags=DefaultFlags());
~TranslationUnit();
int ReparseTranslationUnit(const std::string &buffer, unsigned flags=DefaultFlags());
static unsigned DefaultFlags();
void parse(Index &index,
const std::string &file_path,
const std::vector<std::string> &command_line_args,
const std::map<std::string, std::string> &buffers,
unsigned flags=DefaultFlags());
clang::CodeCompleteResults get_code_completions(const std::string &buffer,
unsigned line_number, unsigned column);
std::vector<clang::Diagnostic> get_diagnostics();
std::unique_ptr<Tokens> get_tokens(unsigned start_offset, unsigned end_offset);
std::unique_ptr<Tokens> get_tokens(unsigned start_line, unsigned start_column,
unsigned end_line, unsigned end_column);
clang::Cursor get_cursor(std::string path, unsigned offset);
clang::Cursor get_cursor(std::string path, unsigned line, unsigned column);
CXTranslationUnit cx_tu;
};
} // namespace clang
#endif // TRANSLATIONUNIT_H_

181
libclangmm/Utility.cc Normal file
View File

@ -0,0 +1,181 @@
#include "Utility.h"
std::string clang::to_string(CXString cx_string) {
std::string string;
if(cx_string.data!=nullptr) {
string=clang_getCString(cx_string);
clang_disposeString(cx_string);
}
return string;
}
std::string clang::to_string(CXCursorKind kind) {
switch (kind) {
case CXCursor_UnexposedDecl: return "UnexposedDecl";
case CXCursor_StructDecl: return "StructDecl";
case CXCursor_UnionDecl: return "UnionDecl";
case CXCursor_ClassDecl: return "ClassDecl";
case CXCursor_EnumDecl: return "EnumDecl";
case CXCursor_FieldDecl: return "FieldDecl";
case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
case CXCursor_FunctionDecl: return "FunctionDecl";
case CXCursor_VarDecl: return "VarDecl";
case CXCursor_ParmDecl: return "ParmDecl";
case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
case CXCursor_ObjCImplementationDecl: return "ObjCImplementationDecl";
case CXCursor_ObjCCategoryImplDecl: return "ObjCCategoryImplDecl";
case CXCursor_TypedefDecl: return "TypedefDecl";
case CXCursor_CXXMethod: return "CXXMethod";
case CXCursor_Namespace: return "Namespace";
case CXCursor_LinkageSpec: return "LinkageSpec";
case CXCursor_Constructor: return "Constructor";
case CXCursor_Destructor: return "Destructor";
case CXCursor_ConversionFunction: return "ConversionFunction";
case CXCursor_TemplateTypeParameter: return "TemplateTypeParameter";
case CXCursor_NonTypeTemplateParameter: return "NonTypeTemplateParameter";
case CXCursor_TemplateTemplateParameter: return "TemplateTemplateParameter";
case CXCursor_FunctionTemplate: return "FunctionTemplate";
case CXCursor_ClassTemplate: return "ClassTemplate";
case CXCursor_ClassTemplatePartialSpecialization: return "ClassTemplatePartialSpecialization";
case CXCursor_NamespaceAlias: return "NamespaceAlias";
case CXCursor_UsingDirective: return "UsingDirective";
case CXCursor_UsingDeclaration: return "UsingDeclaration";
case CXCursor_TypeAliasDecl: return "TypeAliasDecl";
case CXCursor_ObjCSynthesizeDecl: return "ObjCSynthesizeDecl";
case CXCursor_ObjCDynamicDecl: return "ObjCDynamicDecl";
case CXCursor_CXXAccessSpecifier: return "CXXAccessSpecifier";
//case CXCursor_FirstDecl: return "FirstDecl";
//case CXCursor_LastDecl: return "LastDecl";
//case CXCursor_FirstRef: return "FirstRef";
case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
case CXCursor_ObjCClassRef: return "ObjCClassRef";
case CXCursor_TypeRef: return "TypeRef";
case CXCursor_CXXBaseSpecifier: return "CXXBaseSpecifier";
case CXCursor_TemplateRef: return "TemplateRef";
case CXCursor_NamespaceRef: return "NamespaceRef";
case CXCursor_MemberRef: return "MemberRef";
case CXCursor_LabelRef: return "LabelRef";
case CXCursor_OverloadedDeclRef: return "OverloadedDeclRef";
case CXCursor_VariableRef: return "VariableRef";
//case CXCursor_LastRef: return "LastRef";
//case CXCursor_FirstInvalid: return "FirstInvalid";
case CXCursor_InvalidFile: return "InvalidFile";
case CXCursor_NoDeclFound: return "NoDeclFound";
case CXCursor_NotImplemented: return "NotImplemented";
case CXCursor_InvalidCode: return "InvalidCode";
//case CXCursor_LastInvalid: return "LastInvalid";
//case CXCursor_FirstExpr: return "FirstExpr";
case CXCursor_UnexposedExpr: return "UnexposedExpr";
case CXCursor_DeclRefExpr: return "DeclRefExpr";
case CXCursor_MemberRefExpr: return "MemberRefExpr";
case CXCursor_CallExpr: return "CallExpr";
case CXCursor_ObjCMessageExpr: return "ObjCMessageExpr";
case CXCursor_BlockExpr: return "BlockExpr";
case CXCursor_IntegerLiteral: return "IntegerLiteral";
case CXCursor_FloatingLiteral: return "FloatingLiteral";
case CXCursor_ImaginaryLiteral: return "ImaginaryLiteral";
case CXCursor_StringLiteral: return "StringLiteral";
case CXCursor_CharacterLiteral: return "CharacterLiteral";
case CXCursor_ParenExpr: return "ParenExpr";
case CXCursor_UnaryOperator: return "UnaryOperator";
case CXCursor_ArraySubscriptExpr: return "ArraySubscriptExpr";
case CXCursor_BinaryOperator: return "BinaryOperator";
case CXCursor_CompoundAssignOperator: return "CompoundAssignOperator";
case CXCursor_ConditionalOperator: return "ConditionalOperator";
case CXCursor_CStyleCastExpr: return "CStyleCastExpr";
case CXCursor_CompoundLiteralExpr: return "CompoundLiteralExpr";
case CXCursor_InitListExpr: return "InitListExpr";
case CXCursor_AddrLabelExpr: return "AddrLabelExpr";
case CXCursor_StmtExpr: return "StmtExpr";
case CXCursor_GenericSelectionExpr: return "GenericSelectionExpr";
case CXCursor_GNUNullExpr: return "GNUNullExpr";
case CXCursor_CXXStaticCastExpr: return "CXXStaticCastExpr";
case CXCursor_CXXDynamicCastExpr: return "CXXDynamicCastExpr";
case CXCursor_CXXReinterpretCastExpr: return "CXXReinterpretCastExpr";
case CXCursor_CXXConstCastExpr: return "CXXConstCastExpr";
case CXCursor_CXXFunctionalCastExpr: return "CXXFunctionalCastExpr";
case CXCursor_CXXTypeidExpr: return "CXXTypeidExpr";
case CXCursor_CXXBoolLiteralExpr: return "CXXBoolLiteralExpr";
case CXCursor_CXXNullPtrLiteralExpr: return "CXXNullPtrLiteralExpr";
case CXCursor_CXXThisExpr: return "CXXThisExpr";
case CXCursor_CXXThrowExpr: return "CXXThrowExpr";
case CXCursor_CXXNewExpr: return "CXXNewExpr";
case CXCursor_CXXDeleteExpr: return "CXXDeleteExpr";
case CXCursor_UnaryExpr: return "UnaryExpr";
case CXCursor_ObjCStringLiteral: return "ObjCStringLiteral";
case CXCursor_ObjCEncodeExpr: return "ObjCEncodeExpr";
case CXCursor_ObjCSelectorExpr: return "ObjCSelectorExpr";
case CXCursor_ObjCProtocolExpr: return "ObjCProtocolExpr";
case CXCursor_ObjCBridgedCastExpr: return "ObjCBridgedCastExpr";
case CXCursor_PackExpansionExpr: return "PackExpansionExpr";
case CXCursor_SizeOfPackExpr: return "SizeOfPackExpr";
case CXCursor_LambdaExpr: return "LambdaExpr";
case CXCursor_ObjCBoolLiteralExpr: return "ObjCBoolLiteralExpr";
case CXCursor_ObjCSelfExpr: return "ObjCSelfExpr";
//case CXCursor_LastExpr: return "LastExpr";
//case CXCursor_FirstStmt: return "FirstStmt";
case CXCursor_UnexposedStmt: return "UnexposedStmt";
case CXCursor_LabelStmt: return "LabelStmt";
case CXCursor_CompoundStmt: return "CompoundStmt";
case CXCursor_CaseStmt: return "CaseStmt";
case CXCursor_DefaultStmt: return "DefaultStmt";
case CXCursor_IfStmt: return "IfStmt";
case CXCursor_SwitchStmt: return "SwitchStmt";
case CXCursor_WhileStmt: return "WhileStmt";
case CXCursor_DoStmt: return "DoStmt";
case CXCursor_ForStmt: return "ForStmt";
case CXCursor_GotoStmt: return "GotoStmt";
case CXCursor_IndirectGotoStmt: return "IndirectGotoStmt";
case CXCursor_ContinueStmt: return "ContinueStmt";
case CXCursor_BreakStmt: return "BreakStmt";
case CXCursor_ReturnStmt: return "ReturnStmt";
case CXCursor_GCCAsmStmt: return "GCCAsmStmt";
//case CXCursor_AsmStmt: return "AsmStmt";
case CXCursor_ObjCAtTryStmt: return "ObjCAtTryStmt";
case CXCursor_ObjCAtCatchStmt: return "ObjCAtCatchStmt";
case CXCursor_ObjCAtFinallyStmt: return "ObjCAtFinallyStmt";
case CXCursor_ObjCAtThrowStmt: return "ObjCAtThrowStmt";
case CXCursor_ObjCAtSynchronizedStmt: return "ObjCAtSynchronizedStmt";
case CXCursor_ObjCAutoreleasePoolStmt: return "ObjCAutoreleasePoolStmt";
case CXCursor_ObjCForCollectionStmt: return "ObjCForCollectionStmt";
case CXCursor_CXXCatchStmt: return "CXXCatchStmt";
case CXCursor_CXXTryStmt: return "CXXTryStmt";
case CXCursor_CXXForRangeStmt: return "CXXForRangeStmt";
case CXCursor_SEHTryStmt: return "SEHTryStmt";
case CXCursor_SEHExceptStmt: return "SEHExceptStmt";
case CXCursor_SEHFinallyStmt: return "SEHFinallyStmt";
case CXCursor_MSAsmStmt: return "MSAsmStmt";
case CXCursor_NullStmt: return "NullStmt";
case CXCursor_DeclStmt: return "DeclStmt";
case CXCursor_LastStmt: return "LastStmt";
case CXCursor_TranslationUnit: return "TranslationUnit";
//case CXCursor_FirstAttr: return "FirstAttr";
case CXCursor_UnexposedAttr: return "UnexposedAttr";
case CXCursor_IBActionAttr: return "IBActionAttr";
case CXCursor_IBOutletAttr: return "IBOutletAttr";
case CXCursor_IBOutletCollectionAttr: return "IBOutletCollectionAttr";
case CXCursor_CXXFinalAttr: return "CXXFinalAttr";
case CXCursor_CXXOverrideAttr: return "CXXOverrideAttr";
case CXCursor_AnnotateAttr: return "AnnotateAttr";
case CXCursor_AsmLabelAttr: return "AsmLabelAttr";
case CXCursor_LastAttr: return "LastAttr";
case CXCursor_PreprocessingDirective: return "PreprocessingDirective";
case CXCursor_MacroDefinition: return "MacroDefinition";
case CXCursor_MacroExpansion: return "MacroExpansion";
//case CXCursor_MacroInstantiation: return "MacroInstantiation";
case CXCursor_InclusionDirective: return "InclusionDirective";
//case CXCursor_FirstPreprocessing: return "FirstPreprocessing";
//case CXCursor_LastPreprocessing: return "LastPreprocessing";
case CXCursor_ModuleImportDecl: return "ModuleImportDecl";
//case CXCursor_FirstExtraDecl: return "FirstExtraDecl";
case CXCursor_LastExtraDecl: return "LastExtraDecl";
}
return "";
}

11
libclangmm/Utility.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef UTILITY_H_
#define UTILITY_H_
#include <clang-c/Index.h>
#include <string>
namespace clang {
std::string to_string(CXString cx_string);
std::string to_string(CXCursorKind cursor_kind);
}
#endif // UTILITY_H_

17
libclangmm/clangmm.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef CLANGMM_H_
#define CLANGMM_H_
#include "TranslationUnit.h"
#include "SourceLocation.h"
#include "SourceRange.h"
#include "Token.h"
#include "Tokens.h"
#include "CompilationDatabase.h"
#include "CompileCommands.h"
#include "CompileCommand.h"
#include "CodeCompleteResults.h"
#include "CompletionString.h"
#include "Index.h"
#include "Cursor.h"
#include "Diagnostic.h"
#include "Utility.h"
#endif // CLANGMM_H_

85
main.cpp Normal file
View File

@ -0,0 +1,85 @@
#include <iostream>
#include "libclangmm\clangmm.h"
#include "libclangmm\Utility.h"
//#include <clang-c\Index.h>
CXChildVisitResult visitPrint(CXCursor cursor0, CXCursor parent, CXClientData param) {
int* level = static_cast<int*>(param);
clang::Cursor cursor(cursor0);
for (int i = 0; i < *level; ++i)
std::cout << " ";
std::cout << cursor.get_spelling() << " " << clang::to_string(cursor.get_kind()) << std::endl;
*level += 1;
clang_visitChildren(cursor0, &visitPrint, level);
*level -= 1;
return CXChildVisitResult::CXChildVisit_Continue;
/*
echo " ".repeat(param.level), cursor.kind, " ", getSpelling(cursor)
var visitParam : VisitPrintParam
visitParam.level = param.level + 1
visitChildren(cursor, visitPrint, addr visitParam)
return VisitResult.Continu
*/
}
int main(int argc, char** argv) {
/*
echo "Parsing ", filename
let index : libclang.CXIndex = libclang.createIndex(#[excludeDeclsFromPCH]# 0, #[displayDiagnostics]# 0)
let translationUnit : libclang.CXTranslationUnit =
libclang.parseTranslationUnit(index, filename.cstring, nil, 0, nil, 0, 0)
if translationUnit == nil :
echo "Error: cannot create translation unit for '", filename, "'"
return
let cursor = libclang.getTranslationUnitCursor(translationUnit)
var param : VisitFileParam
param.db = db
echo "=== START AST ==="
# printChildren(cursor, 0)
echo "=== DONE AST ==="
var file : File
file.path = filename
file.vars = newList[VarRef]()
file.funcs = newList[FuncRef]()
file.types = newList[TypeRef]()
visitChildren(cursor, visitFile, addr param)
libclang.disposeTranslationUnit(translationUnit)
libclang.disposeIndex(index)
*/
std::vector<std::string> args;
clang::Index index(0 /*excludeDeclarationsFromPCH*/, 0 /*displayDiagnostics*/);
clang::TranslationUnit translationUnit(index, "test.cc", args);
int level = 0;
auto cursor = clang_getTranslationUnitCursor(translationUnit.cx_tu);
clang_visitChildren(cursor, &visitPrint, &level);
/*
TranslationUnit(Index &index,
const std::string &file_path,
const std::vector<std::string> &command_line_args,
const std::string &buffer,
unsigned flags = DefaultFlags());
TranslationUnit(Index &index,
const std::string &file_path,
const std::vector<std::string> &command_line_args,
unsigned flags = DefaultFlags());
*/
std::cin.get();
}

2
test.cc Normal file
View File

@ -0,0 +1,2 @@
void bar() {}
void foo() {}