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 TODO: compile flags, include paths, ycm_clang_options, CompilationDatabase
support, how the search system works (subsequence match), extending the semantic support, how the search system works (subsequence match), extending the semantic
engine for other langs engine for other langs, using ListToggle
Options Options
------- -------

View File

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

View File

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

View File

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

View File

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

View File

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