bool TranslationUnit::LocationIsInSystemHeader( const Location &location ) {
  unique_lock< mutex > lock( clang_access_mutex_ );

  if ( !clang_translation_unit_ || !location.IsValid() ) {
    return false;
  }

  return clang_Location_isInSystemHeader(
    GetSourceLocation( location.filename_,
                       location.line_number_,
                       location.column_number_ ) );
}
TEST_F( TranslationUnitTest, GoToDefinitionFails ) {
  TranslationUnit unit( PathToTestFile( "goto.cpp" ).string(),
                        std::vector< UnsavedFile >(),
                        std::vector< std::string >(),
                        clang_index_ );

  Location location = unit.GetDefinitionLocation(
                        19,
                        3,
                        std::vector< UnsavedFile >() );

  EXPECT_FALSE( location.IsValid() );
}
TEST_F( TranslationUnitTest, GoToDefinitionFails ) {
  fs::path path_to_testdata = fs::current_path() / fs::path( "testdata" );
  fs::path test_file = path_to_testdata / fs::path( "goto.cpp" );

  TranslationUnit unit( test_file.string(),
                        std::vector< UnsavedFile >(),
                        std::vector< std::string >(),
                        clang_index_ );

  Location location = unit.GetDefinitionLocation(
                        17,
                        3,
                        std::vector< UnsavedFile >() );

  EXPECT_FALSE( location.IsValid() );
}
Location TranslationUnit::GetDefinitionOrDeclarationLocation(
  const std::string &filename,
  int line,
  int column,
  const std::vector< UnsavedFile > &unsaved_files,
  bool reparse ) {
  if ( reparse ) {
    Reparse( unsaved_files );
  }

  unique_lock< mutex > lock( clang_access_mutex_ );

  if ( !clang_translation_unit_ ) {
    return Location();
  }

  CXCursor cursor = GetCursor( filename, line, column );

  if ( !CursorIsValid( cursor ) ) {
    return Location();
  }

  // Return the definition or the declaration of a symbol under the cursor
  // according to the following logic:
  //  - if the cursor is already on the definition, return the location of the
  //    declaration;
  //  - otherwise, search for the definition and return its location;
  //  - if no definition is found, return the location of the declaration.
  if ( clang_isCursorDefinition( cursor ) ) {
    return GetDeclarationLocationForCursor( cursor );
  }

  Location location = GetDefinitionLocationForCursor( cursor );

  if ( location.IsValid() ) {
    return location;
  }

  return GetDeclarationLocationForCursor( cursor );
}