From ee919417af610d93bd60425a751bda4cb6dd542c Mon Sep 17 00:00:00 2001 From: Strahinja Val Markovic Date: Tue, 22 Jan 2013 19:40:05 -0800 Subject: [PATCH] Managing memory from the C interface better --- README.md | 2 +- cpp/ycm/ClangCompleter/ClangUtils.cpp | 13 ++++---- cpp/ycm/ClangCompleter/ClangUtils.h | 7 +++- .../ClangCompleter/CompilationDatabase.cpp | 29 +++++++++------- cpp/ycm/ClangCompleter/TranslationUnit.cpp | 33 +++++++++++++------ cpp/ycm/ClangCompleter/TranslationUnit.h | 2 ++ 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 0f1bce0f..972df4a3 100644 --- a/README.md +++ b/README.md @@ -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 ------- diff --git a/cpp/ycm/ClangCompleter/ClangUtils.cpp b/cpp/ycm/ClangCompleter/ClangUtils.cpp index dee09e52..d5f83a4b 100644 --- a/cpp/ycm/ClangCompleter/ClangUtils.cpp +++ b/cpp/ycm/ClangCompleter/ClangUtils.cpp @@ -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; } diff --git a/cpp/ycm/ClangCompleter/ClangUtils.h b/cpp/ycm/ClangCompleter/ClangUtils.h index 7c9057a8..5eb6fbd1 100644 --- a/cpp/ycm/ClangCompleter/ClangUtils.h +++ b/cpp/ycm/ClangCompleter/ClangUtils.h @@ -24,9 +24,14 @@ #include #include +#include +#include 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 diff --git a/cpp/ycm/ClangCompleter/CompilationDatabase.cpp b/cpp/ycm/ClangCompleter/CompilationDatabase.cpp index 394b0631..080657c1 100644 --- a/cpp/ycm/ClangCompleter/CompilationDatabase.cpp +++ b/cpp/ycm/ClangCompleter/CompilationDatabase.cpp @@ -19,7 +19,16 @@ #include "ClangUtils.h" #include "standard.h" +#include +#include + +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; } diff --git a/cpp/ycm/ClangCompleter/TranslationUnit.cpp b/cpp/ycm/ClangCompleter/TranslationUnit.cpp index 9d8710a0..6e48507e 100644 --- a/cpp/ycm/ClangCompleter/TranslationUnit.cpp +++ b/cpp/ycm/ClangCompleter/TranslationUnit.cpp @@ -22,14 +22,20 @@ #include "ClangUtils.h" #include -#include +#include +#include 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 ); diff --git a/cpp/ycm/ClangCompleter/TranslationUnit.h b/cpp/ycm/ClangCompleter/TranslationUnit.h index f96f3247..8d0834d8 100644 --- a/cpp/ycm/ClangCompleter/TranslationUnit.h +++ b/cpp/ycm/ClangCompleter/TranslationUnit.h @@ -49,6 +49,8 @@ public: ~TranslationUnit(); + void Destroy(); + std::vector< Diagnostic > LatestDiagnostics(); bool IsCurrentlyUpdating() const;