Как отобразить имя типа параметра шаблона в natvis? - PullRequest
0 голосов
/ 31 января 2019

Я хочу расширить визуализатор natvis для (C ++) шаблонного класса.Есть ли способ отобразить имя типа первого параметра шаблона?

Было бы здорово, если бы boost::variant<int,bool> v; v=1; отображал 1 (int) или что-то в этом роде

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Если вы хотите показать $T1 в виде строки, оберните его ".Например, для

<DisplayString>{*($T1*)storage_.data_.buf} {"$T1"}</DisplayString>

в вашем случае вы увидите 1 "int"

0 голосов
/ 02 февраля 2019

На мой взгляд, лучшим решением является использование стандарта C ++ 17 std::variant.MSVC поставляется с natvis для этого типа, так что у вас есть хорошее представление о сохраненном значении.

Вот код natvis, который я только что написал и протестировал:

  <Type Name="boost::variant&lt;*&gt;">
    <DisplayString Condition="which_==0">{*($T1*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==1" Optional="true">{*($T2*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==2" Optional="true">{*($T3*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==3" Optional="true">{*($T4*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==4" Optional="true">{*($T5*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==5" Optional="true">{*($T6*)storage_.data_.buf}</DisplayString>
    <DisplayString Condition="which_==6" Optional="true">{*($T7*)storage_.data_.buf}</DisplayString>
    <Expand>
      <Item Name="which">which_</Item>
      <Item Name="value0" Condition="which_==0">*($T1*)storage_.data_.buf</Item>
      <Item Name="value1" Condition="which_==1" Optional="true">*($T2*)storage_.data_.buf</Item>
      <Item Name="value2" Condition="which_==2" Optional="true">*($T3*)storage_.data_.buf</Item>
      <Item Name="value3" Condition="which_==3" Optional="true">*($T4*)storage_.data_.buf</Item>
      <Item Name="value4" Condition="which_==4" Optional="true">*($T5*)storage_.data_.buf</Item>
      <Item Name="value5" Condition="which_==5" Optional="true">*($T6*)storage_.data_.buf</Item>
      <Item Name="value6" Condition="which_==6" Optional="true">*($T7*)storage_.data_.buf</Item>
    </Expand>
  </Type>

Это работаетдля любого boost::variant<type_or_types>.

Он имеет DisplayString, который принимает член варианта storage_ и извлекает буфер buf.Затем адрес буфера преобразуется в указатель на тип, который был предоставлен std::variant.Как вы можете видеть в моем коде which_ основан на нуле, тогда как параметры шаблона основаны на 1.Меня интересует не адрес, а значение, поэтому я добавляю * перед значением.

Я также добавил раздел Expand, чтобы вы могли расширить вариант.Это позволяет мне показать which_ и снова показать значение - на этот раз столбец Type покажет правильный тип, как вы можете видеть на моем снимке экрана (для самого варианта тип отображается как boost::variant<…>, и яне знаю, как добавить имя типа в DisplayString).

Обратите внимание, что Optional="true" требуется, потому что в противном случае мы получим ошибку синтаксического анализа в случаях, когда передано менее 7 параметров типа (как в boost::variant<int,bool> и natvis не имеет $T7.

Если вам нужно больше параметров шаблона, вы можете легко расширить код.

Если вы хотите, чтобы DisplayString такжепоказывает индекс (как явное значение или закодировано в имя value…), вы можете легко изменить его соответственно, как в

<DisplayString Condition="which_==0">{{which={which_} value0={*($T1*)storage_.data_.buf}}}</DisplayString>

Последнее, но не менее важное, обратите внимание, что я не очень много тестировал и чтоЯ не стал вдаваться в подробности boost::variant. Я увидел, что в storage_ есть члены, предполагающие наличие некоторого выравнивания на месте. Поэтому может быть недостаточно просто использовать storage_.data_.buf. Возможно, потребуется настроить tуказатель в зависимости от используемого выравнивания.

View in Debugger

...