Managing memory from the C interface better

This commit is contained in:
Strahinja Val Markovic 2013-01-22 19:40:05 -08:00
parent 970b2fb56c
commit ee919417af
6 changed files with 55 additions and 31 deletions

View File

@ -234,7 +234,7 @@ TODO, STILL WIP
TODO: compile flags, include paths, ycm_clang_options, CompilationDatabase
support, how the search system works (subsequence match), extending the semantic
engine for other langs
engine for other langs, using ListToggle
Options
-------

View File

@ -165,21 +165,21 @@ std::vector< CompletionData > ToCompletionDataVector(
}
Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic ) {
Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap ) {
Diagnostic diagnostic;
if ( !cxdiagnostic )
if ( !diagnostic_wrap )
return diagnostic;
diagnostic.kind_ = DiagnosticSeverityToType(
clang_getDiagnosticSeverity( cxdiagnostic ) );
clang_getDiagnosticSeverity( diagnostic_wrap.get() ) );
// If this is an "ignored" diagnostic, there's no point in continuing since we
// won't display those to the user
if ( diagnostic.kind_ == 'I' )
return diagnostic;
CXSourceLocation location = clang_getDiagnosticLocation( cxdiagnostic );
CXSourceLocation location = clang_getDiagnosticLocation( diagnostic_wrap.get() );
CXFile file;
uint unused_offset;
clang_getSpellingLocation( location,
@ -190,10 +190,9 @@ Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic ) {
diagnostic.filename_ = CXStringToString( clang_getFileName( file ) );
diagnostic.text_ = CXStringToString(
clang_getDiagnosticSpelling( cxdiagnostic ) );
diagnostic.long_formatted_text_ = FullDiagnosticText( cxdiagnostic );
clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
diagnostic.long_formatted_text_ = FullDiagnosticText( diagnostic_wrap.get() );
clang_disposeDiagnostic( cxdiagnostic );
return diagnostic;
}

View File

@ -24,9 +24,14 @@
#include <vector>
#include <clang-c/Index.h>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_pointer.hpp>
namespace YouCompleteMe {
typedef boost::shared_ptr<
boost::remove_pointer< CXDiagnostic >::type > DiagnosticWrap;
std::string CXStringToString( CXString text );
std::vector< CompletionData > ToCompletionDataVector(
@ -35,7 +40,7 @@ std::vector< CompletionData > ToCompletionDataVector(
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
const std::vector< UnsavedFile > &unsaved_files );
Diagnostic CXDiagnosticToDiagnostic( CXDiagnostic cxdiagnostic );
Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap );
} // namespace YouCompleteMe

View File

@ -19,7 +19,16 @@
#include "ClangUtils.h"
#include "standard.h"
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_pointer.hpp>
using boost::shared_ptr;
using boost::shared_ptr;
using boost::remove_pointer;
namespace YouCompleteMe {
typedef shared_ptr<
remove_pointer< CXCompileCommands >::type > CompileCommandsWrap;
CompilationDatabase::CompilationDatabase(
const std::string &path_to_directory )
@ -49,21 +58,20 @@ std::vector< std::string > CompilationDatabase::FlagsForFile(
if ( !is_loaded_ )
return flags;
CXCompileCommands commands =
CompileCommandsWrap commands(
clang_CompilationDatabase_getCompileCommands(
compilation_database_,
path_to_file.c_str() );
path_to_file.c_str() ), clang_CompileCommands_dispose );
uint num_commands = clang_CompileCommands_getSize( commands );
uint num_commands = clang_CompileCommands_getSize( commands.get() );
if ( num_commands < 1 ) {
clang_CompileCommands_dispose( commands );
return flags;
}
// We always pick the first command offered
CXCompileCommand command = clang_CompileCommands_getCommand(
commands,
commands.get(),
0 );
uint num_flags = clang_CompileCommand_getNumArgs( command );
@ -74,7 +82,6 @@ std::vector< std::string > CompilationDatabase::FlagsForFile(
clang_CompileCommand_getArg( command, i ) ) );
}
clang_CompileCommands_dispose( commands );
return flags;
}
@ -86,27 +93,25 @@ std::string CompilationDatabase::CompileCommandWorkingDirectoryForFile(
if ( !is_loaded_ )
return path_to_directory;
CXCompileCommands commands =
CompileCommandsWrap commands(
clang_CompilationDatabase_getCompileCommands(
compilation_database_,
path_to_file.c_str() );
path_to_file.c_str() ), clang_CompileCommands_dispose );
uint num_commands = clang_CompileCommands_getSize( commands );
uint num_commands = clang_CompileCommands_getSize( commands.get() );
if ( num_commands < 1 ) {
clang_CompileCommands_dispose( commands );
return path_to_directory;
}
// We always pick the first command offered
CXCompileCommand command = clang_CompileCommands_getCommand(
commands,
commands.get(),
0 );
path_to_directory = CXStringToString( clang_CompileCommand_getDirectory(
command ) );
clang_CompileCommands_dispose( commands );
return path_to_directory;
}

View File

@ -22,14 +22,20 @@
#include "ClangUtils.h"
#include <clang-c/Index.h>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_pointer.hpp>
using boost::unique_lock;
using boost::mutex;
using boost::try_to_lock_t;
using boost::shared_ptr;
using boost::remove_pointer;
namespace YouCompleteMe {
typedef shared_ptr<
remove_pointer< CXCodeCompleteResults >::type > CodeCompleteResultsWrap;
TranslationUnit::TranslationUnit(
const std::string &filename,
const std::vector< UnsavedFile > &unsaved_files,
@ -66,8 +72,14 @@ TranslationUnit::TranslationUnit(
TranslationUnit::~TranslationUnit() {
if ( clang_translation_unit_ )
Destroy();
}
void TranslationUnit::Destroy() {
if ( clang_translation_unit_ ) {
clang_disposeTranslationUnit( clang_translation_unit_ );
clang_translation_unit_ = NULL;
}
}
@ -127,17 +139,18 @@ std::vector< CompletionData > TranslationUnit::CandidatesForLocation(
// in the open-source world don't realize this (I checked). Some don't even
// call reparse*, but parse* which is even less efficient.
CXCodeCompleteResults *results =
CodeCompleteResultsWrap results(
clang_codeCompleteAt( clang_translation_unit_,
filename_.c_str(),
line,
column,
&cxunsaved_files[ 0 ],
cxunsaved_files.size(),
clang_defaultCodeCompleteOptions() );
clang_defaultCodeCompleteOptions() ),
clang_disposeCodeCompleteResults );
std::vector< CompletionData > candidates = ToCompletionDataVector( results );
clang_disposeCodeCompleteResults( results );
std::vector< CompletionData > candidates = ToCompletionDataVector(
results.get() );
return candidates;
}
@ -159,8 +172,7 @@ void TranslationUnit::Reparse(
clang_defaultEditingTranslationUnitOptions() );
if ( failure ) {
clang_disposeTranslationUnit( clang_translation_unit_ );
clang_translation_unit_ = NULL;
Destroy();
boost_throw( ClangParseError() );
}
@ -178,8 +190,9 @@ void TranslationUnit::UpdateLatestDiagnostics() {
for ( uint i = 0; i < num_diagnostics; ++i ) {
Diagnostic diagnostic =
CXDiagnosticToDiagnostic(
clang_getDiagnostic( clang_translation_unit_, i ) );
DiagnosticWrapToDiagnostic(
DiagnosticWrap( clang_getDiagnostic( clang_translation_unit_, i ),
clang_disposeDiagnostic ) );
if ( diagnostic.kind_ != 'I' )
latest_diagnostics_.push_back( diagnostic );

View File

@ -49,6 +49,8 @@ public:
~TranslationUnit();
void Destroy();
std::vector< Diagnostic > LatestDiagnostics();
bool IsCurrentlyUpdating() const;