[Lldb-commits] [lldb] e0219f2 - [lldb] Overwrite existing LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES

2024-04-09 Thread Cyndy Ishida via lldb-commits

Author: Cyndy Ishida
Date: 2024-04-09T19:35:55-07:00
New Revision: e0219f2d53686135b7363450b44877342a960e71

URL: 
https://github.com/llvm/llvm-project/commit/e0219f2d53686135b7363450b44877342a960e71
DIFF: 
https://github.com/llvm/llvm-project/commit/e0219f2d53686135b7363450b44877342a960e71.diff

LOG: [lldb] Overwrite existing LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES
on apple-linux

Added: 


Modified: 
lldb/cmake/caches/Apple-lldb-Linux.cmake

Removed: 




diff  --git a/lldb/cmake/caches/Apple-lldb-Linux.cmake 
b/lldb/cmake/caches/Apple-lldb-Linux.cmake
index 9258f01e2ec26a..bfa660d8654b7b 100644
--- a/lldb/cmake/caches/Apple-lldb-Linux.cmake
+++ b/lldb/cmake/caches/Apple-lldb-Linux.cmake
@@ -1,5 +1,5 @@
 include(${CMAKE_CURRENT_LIST_DIR}/Apple-lldb-base.cmake)
-set(LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES ON CACHE BOOL "")
+set(LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES ON CACHE BOOL "" FORCE)
 
 set(LLVM_DISTRIBUTION_COMPONENTS
   lldb



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][TypeSynthetic][NFC] Make SyntheticChildrenFrontend::Update() return an enum (PR #80167)

2024-04-09 Thread Jonas Devlieghere via lldb-commits

JDevlieghere wrote:

> No particular reason apart from it being scoped, which I thought we might 
> prefer for new enums. But there's no reason it couldn't be an old-school enum

If that's the case I think consistency is more important. Mind putting up a PR? 

https://github.com/llvm/llvm-project/pull/80167
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Fix error in unrecognized register name handling for "SBFrame.register" (PR #88047)

2024-04-09 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

Looks good.

https://github.com/llvm/llvm-project/pull/88047
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][ClangUserExpression][NFCI] Pass the most specific ExecutionContextScope possible into ClangExpressionParser (PR #87657)

2024-04-09 Thread Michael Buch via lldb-commits


@@ -669,15 +670,8 @@ bool ClangUserExpression::Parse(DiagnosticManager 
_manager,
   // Parse the expression
   //
 
-  Process *process = exe_ctx.GetProcessPtr();
-  ExecutionContextScope *exe_scope = process;
-
-  if (!exe_scope)
-exe_scope = exe_ctx.GetTargetPtr();
-
-  bool parse_success = TryParse(diagnostic_manager, exe_scope, exe_ctx,
-execution_policy, keep_result_in_memory,
-generate_debug_info);
+  bool parse_success = TryParse(diagnostic_manager, exe_ctx, execution_policy,
+keep_result_in_memory, generate_debug_info);

Michael137 wrote:

@clayborg ping

https://github.com/llvm/llvm-project/pull/87657
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][TypeSynthetic][NFC] Make SyntheticChildrenFrontend::Update() return an enum (PR #80167)

2024-04-09 Thread Michael Buch via lldb-commits

Michael137 wrote:

> @Michael137 I'm a little late to the party but I just noticed that 
> `ChildCacheState` is the only `enum class` in `lldb-enumerations.h`. Is that 
> intentional? Is there a reason this cannot be a old-school enum like 
> everything else in that file? I don't feel super strongly about I'd like to 
> make sure there's a reason for the inconsistency.

No particular reason apart from it being scoped, which I thought we might 
prefer for new enums. But there's no reason it couldn't be an old-school enum

https://github.com/llvm/llvm-project/pull/80167
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][libc++] Adds local_t clock data formatters. (PR #88178)

2024-04-09 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Mark de Wever (mordante)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/88178.diff


5 Files Affected:

- (modified) lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (+23) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (+33-5) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.h (+8) 
- (modified) 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/TestDataFormatterLibcxxChrono.py
 (+104) 
- (modified) 
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/chrono/main.cpp
 (+52) 


``diff
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 4a536096a066ff..5c28f6fe059e1a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1068,6 +1068,29 @@ static void 
LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
 eTypeOptionCascade,
 true);
 
+  AddCXXSummary(
+  cpp_category_sp,
+  lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider,
+  "libc++ std::chrono::local_seconds summary provider",
+  "^std::__[[:alnum:]]+::chrono::time_point<"
+  "std::__[[:alnum:]]+::chrono::local_t, "
+  "std::__[[:alnum:]]+::chrono::duration "
+  "> >$",
+  eTypeOptionHideChildren | eTypeOptionHideValue | eTypeOptionCascade,
+  true);
+  AddCXXSummary(cpp_category_sp,
+lldb_private::formatters::LibcxxChronoLocalDaysSummaryProvider,
+"libc++ std::chrono::local_seconds summary provider",
+"^std::__[[:alnum:]]+::chrono::time_point<"
+"std::__[[:alnum:]]+::chrono::local_t, "
+"std::__[[:alnum:]]+::chrono::duration "
+"> >$",
+eTypeOptionHideChildren | eTypeOptionHideValue |
+eTypeOptionCascade,
+true);
+
   // Chrono calendar types
 
   cpp_category_sp->AddTypeSummary(
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index d2d50152c07cf8..e160fd07639395 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -1087,8 +1087,10 @@ bool 
lldb_private::formatters::LibcxxWStringViewSummaryProvider(
 dataobj, size);
 }
 
-bool lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
-ValueObject , Stream , const TypeSummaryOptions ) {
+static bool
+LibcxxChronoTimePointSecondsSummaryProvider(ValueObject , Stream 
,
+const TypeSummaryOptions ,
+const char *fmt) {
   ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
   if (!ptr_sp)
 return false;
@@ -1112,7 +1114,7 @@ bool 
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
   else {
 std::array str;
 std::size_t size =
-std::strftime(str.data(), str.size(), "%FT%H:%M:%SZ", 
gmtime());
+std::strftime(str.data(), str.size(), fmt, gmtime());
 if (size == 0)
   return false;
 
@@ -1123,8 +1125,22 @@ bool 
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
   return true;
 }
 
-bool lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
+bool lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
 ValueObject , Stream , const TypeSummaryOptions ) {
+  return LibcxxChronoTimePointSecondsSummaryProvider(valobj, stream, options,
+ "%FT%H:%M:%SZ");
+}
+
+bool lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider(
+ValueObject , Stream , const TypeSummaryOptions ) {
+  return LibcxxChronoTimePointSecondsSummaryProvider(valobj, stream, options,
+ "%FT%H:%M:%S");
+}
+
+static bool
+LibcxxChronoTimepointDaysSummaryProvider(ValueObject , Stream ,
+ const TypeSummaryOptions ,
+ const char *fmt) {
   ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
   if (!ptr_sp)
 return false;
@@ -1148,7 +1164,7 @@ bool 
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
 
 std::array str;
 std::size_t size =
-std::strftime(str.data(), str.size(), "%FZ", gmtime());
+std::strftime(str.data(), str.size(), fmt, gmtime());
 if (size == 0)
   return false;
 
@@ -1158,6 +1174,18 @@ bool 
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
   return true;
 }
 
+bool lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
+ValueObject , Stream , const TypeSummaryOptions ) {
+  return 

[Lldb-commits] [lldb] [lldb][libc++] Adds local_t clock data formatters. (PR #88178)

2024-04-09 Thread Mark de Wever via lldb-commits

https://github.com/mordante created 
https://github.com/llvm/llvm-project/pull/88178

None

>From 656ee030e38be24732dd78f96204ce12fe40e788 Mon Sep 17 00:00:00 2001
From: Mark de Wever 
Date: Tue, 19 Mar 2024 20:31:41 +0100
Subject: [PATCH] [lldb][libc++] Adds local_t clock data formatters.

---
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  |  23 
 .../Plugins/Language/CPlusPlus/LibCxx.cpp |  38 ++-
 .../Plugins/Language/CPlusPlus/LibCxx.h   |   8 ++
 .../chrono/TestDataFormatterLibcxxChrono.py   | 104 ++
 .../data-formatter-stl/libcxx/chrono/main.cpp |  52 +
 5 files changed, 220 insertions(+), 5 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 4a536096a066ff..5c28f6fe059e1a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1068,6 +1068,29 @@ static void 
LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
 eTypeOptionCascade,
 true);
 
+  AddCXXSummary(
+  cpp_category_sp,
+  lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider,
+  "libc++ std::chrono::local_seconds summary provider",
+  "^std::__[[:alnum:]]+::chrono::time_point<"
+  "std::__[[:alnum:]]+::chrono::local_t, "
+  "std::__[[:alnum:]]+::chrono::duration "
+  "> >$",
+  eTypeOptionHideChildren | eTypeOptionHideValue | eTypeOptionCascade,
+  true);
+  AddCXXSummary(cpp_category_sp,
+lldb_private::formatters::LibcxxChronoLocalDaysSummaryProvider,
+"libc++ std::chrono::local_seconds summary provider",
+"^std::__[[:alnum:]]+::chrono::time_point<"
+"std::__[[:alnum:]]+::chrono::local_t, "
+"std::__[[:alnum:]]+::chrono::duration "
+"> >$",
+eTypeOptionHideChildren | eTypeOptionHideValue |
+eTypeOptionCascade,
+true);
+
   // Chrono calendar types
 
   cpp_category_sp->AddTypeSummary(
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index d2d50152c07cf8..e160fd07639395 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -1087,8 +1087,10 @@ bool 
lldb_private::formatters::LibcxxWStringViewSummaryProvider(
 dataobj, size);
 }
 
-bool lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
-ValueObject , Stream , const TypeSummaryOptions ) {
+static bool
+LibcxxChronoTimePointSecondsSummaryProvider(ValueObject , Stream 
,
+const TypeSummaryOptions ,
+const char *fmt) {
   ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
   if (!ptr_sp)
 return false;
@@ -1112,7 +1114,7 @@ bool 
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
   else {
 std::array str;
 std::size_t size =
-std::strftime(str.data(), str.size(), "%FT%H:%M:%SZ", 
gmtime());
+std::strftime(str.data(), str.size(), fmt, gmtime());
 if (size == 0)
   return false;
 
@@ -1123,8 +1125,22 @@ bool 
lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
   return true;
 }
 
-bool lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
+bool lldb_private::formatters::LibcxxChronoSysSecondsSummaryProvider(
 ValueObject , Stream , const TypeSummaryOptions ) {
+  return LibcxxChronoTimePointSecondsSummaryProvider(valobj, stream, options,
+ "%FT%H:%M:%SZ");
+}
+
+bool lldb_private::formatters::LibcxxChronoLocalSecondsSummaryProvider(
+ValueObject , Stream , const TypeSummaryOptions ) {
+  return LibcxxChronoTimePointSecondsSummaryProvider(valobj, stream, options,
+ "%FT%H:%M:%S");
+}
+
+static bool
+LibcxxChronoTimepointDaysSummaryProvider(ValueObject , Stream ,
+ const TypeSummaryOptions ,
+ const char *fmt) {
   ValueObjectSP ptr_sp = valobj.GetChildMemberWithName("__d_");
   if (!ptr_sp)
 return false;
@@ -1148,7 +1164,7 @@ bool 
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
 
 std::array str;
 std::size_t size =
-std::strftime(str.data(), str.size(), "%FZ", gmtime());
+std::strftime(str.data(), str.size(), fmt, gmtime());
 if (size == 0)
   return false;
 
@@ -1158,6 +1174,18 @@ bool 
lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
   return true;
 }
 
+bool lldb_private::formatters::LibcxxChronoSysDaysSummaryProvider(
+ValueObject , Stream , const TypeSummaryOptions ) {
+  return 

[Lldb-commits] [lldb] Fix error in unrecognized register name handling for "SBFrame.register" (PR #88047)

2024-04-09 Thread via lldb-commits

https://github.com/jimingham edited 
https://github.com/llvm/llvm-project/pull/88047
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix dead lock in TypeCategoryMap.cpp (PR #87540)

2024-04-09 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/87540
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix dead lock in TypeCategoryMap.cpp (PR #87540)

2024-04-09 Thread Vincent Belliard via lldb-commits


@@ -25,19 +25,25 @@ TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
 }
 
 void TypeCategoryMap::Add(KeyType name, const TypeCategoryImplSP ) {
-  std::lock_guard guard(m_map_mutex);
-  m_map[name] = entry;
+  {
+std::lock_guard guard(m_map_mutex);
+m_map[name] = entry;
+  }
+  // The lock is now released for the eventual call to Changed.

v-bulle wrote:

done

https://github.com/llvm/llvm-project/pull/87540
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix dead lock in TypeCategoryMap.cpp (PR #87540)

2024-04-09 Thread Vincent Belliard via lldb-commits

https://github.com/v-bulle updated 
https://github.com/llvm/llvm-project/pull/87540

>From 5234f6873d894dd80b2c1fef40fd18e4b722a2c9 Mon Sep 17 00:00:00 2001
From: Vincent Belliard 
Date: Wed, 3 Apr 2024 11:31:06 -0700
Subject: [PATCH 1/3] [lldb] fix dead lock in TypeCategoryMap.cpp

FormatManager::GetCategoryForLanguage and
FormatManager::GetCategory(can_create = true) can be called concurently
and they both take the TypeCategory::m_map_mutex and the
FormatManager::m_language_categories_mutex but in reverse order.

Without the patch, we can have a dead lock.
---
 .../source/DataFormatters/TypeCategoryMap.cpp | 28 +++
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/lldb/source/DataFormatters/TypeCategoryMap.cpp 
b/lldb/source/DataFormatters/TypeCategoryMap.cpp
index fd76bab95826af..0d1f55fff473d1 100644
--- a/lldb/source/DataFormatters/TypeCategoryMap.cpp
+++ b/lldb/source/DataFormatters/TypeCategoryMap.cpp
@@ -25,19 +25,23 @@ TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
 }
 
 void TypeCategoryMap::Add(KeyType name, const TypeCategoryImplSP ) {
-  std::lock_guard guard(m_map_mutex);
-  m_map[name] = entry;
+  {
+std::lock_guard guard(m_map_mutex);
+m_map[name] = entry;
+  }
   if (listener)
 listener->Changed();
 }
 
 bool TypeCategoryMap::Delete(KeyType name) {
-  std::lock_guard guard(m_map_mutex);
-  MapIterator iter = m_map.find(name);
-  if (iter == m_map.end())
-return false;
-  m_map.erase(name);
-  Disable(name);
+  {
+std::lock_guard guard(m_map_mutex);
+MapIterator iter = m_map.find(name);
+if (iter == m_map.end())
+  return false;
+m_map.erase(name);
+Disable(name);
+  }
   if (listener)
 listener->Changed();
   return true;
@@ -123,9 +127,11 @@ void TypeCategoryMap::DisableAllCategories() {
 }
 
 void TypeCategoryMap::Clear() {
-  std::lock_guard guard(m_map_mutex);
-  m_map.clear();
-  m_active_categories.clear();
+  {
+std::lock_guard guard(m_map_mutex);
+m_map.clear();
+m_active_categories.clear();
+  }
   if (listener)
 listener->Changed();
 }

>From 7305de06ab0425631fdf554cd1ad0498ac9fc7ed Mon Sep 17 00:00:00 2001
From: Vincent Belliard 
Date: Thu, 4 Apr 2024 15:20:59 -0700
Subject: [PATCH 2/3] Adds comments

---
 lldb/source/DataFormatters/TypeCategoryMap.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/source/DataFormatters/TypeCategoryMap.cpp 
b/lldb/source/DataFormatters/TypeCategoryMap.cpp
index 0d1f55fff473d1..ecbdcde98d07d3 100644
--- a/lldb/source/DataFormatters/TypeCategoryMap.cpp
+++ b/lldb/source/DataFormatters/TypeCategoryMap.cpp
@@ -29,6 +29,7 @@ void TypeCategoryMap::Add(KeyType name, const 
TypeCategoryImplSP ) {
 std::lock_guard guard(m_map_mutex);
 m_map[name] = entry;
   }
+  // The lock is now released for the eventual call to Changed.
   if (listener)
 listener->Changed();
 }
@@ -42,6 +43,7 @@ bool TypeCategoryMap::Delete(KeyType name) {
 m_map.erase(name);
 Disable(name);
   }
+  // The lock is now released for the eventual call to Changed.
   if (listener)
 listener->Changed();
   return true;
@@ -132,6 +134,7 @@ void TypeCategoryMap::Clear() {
 m_map.clear();
 m_active_categories.clear();
   }
+  // The lock is now released for the eventual call to Changed.
   if (listener)
 listener->Changed();
 }

>From bb51c8944ccecac2af5d9527a61718e1d1e85d4b Mon Sep 17 00:00:00 2001
From: Vincent Belliard 
Date: Tue, 9 Apr 2024 08:33:36 -0700
Subject: [PATCH 3/3] Modify comment

---
 lldb/source/DataFormatters/TypeCategoryMap.cpp | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/lldb/source/DataFormatters/TypeCategoryMap.cpp 
b/lldb/source/DataFormatters/TypeCategoryMap.cpp
index ecbdcde98d07d3..ce2cf369b5be53 100644
--- a/lldb/source/DataFormatters/TypeCategoryMap.cpp
+++ b/lldb/source/DataFormatters/TypeCategoryMap.cpp
@@ -29,7 +29,10 @@ void TypeCategoryMap::Add(KeyType name, const 
TypeCategoryImplSP ) {
 std::lock_guard guard(m_map_mutex);
 m_map[name] = entry;
   }
-  // The lock is now released for the eventual call to Changed.
+  // Release the mutex to avoid a potential deadlock between
+  // TypeCategoryMap::m_map_mutex and
+  // FormatManager::m_language_categories_mutex which can be acquired in
+  // reverse order when calling FormatManager::Changed.
   if (listener)
 listener->Changed();
 }
@@ -43,7 +46,10 @@ bool TypeCategoryMap::Delete(KeyType name) {
 m_map.erase(name);
 Disable(name);
   }
-  // The lock is now released for the eventual call to Changed.
+  // Release the mutex to avoid a potential deadlock between
+  // TypeCategoryMap::m_map_mutex and
+  // FormatManager::m_language_categories_mutex which can be acquired in
+  // reverse order when calling FormatManager::Changed.
   if (listener)
 listener->Changed();
   return true;
@@ -134,7 +140,10 @@ void TypeCategoryMap::Clear() {
 m_map.clear();
 m_active_categories.clear();
   }
-