Доступ к инициализатору stati c constexpr в LLVM C ++ 17 - PullRequest
1 голос
/ 19 февраля 2020

В плагине LLVM-9.x я хотел бы получить доступ к инициализатору (= 42), связанному с переменной Y в специализации шаблона T<42> foo:

template<int X>
class T {
  //Clang produces different ASTs on this code in C++14 and C++17
  //(in 17, there's no initializer for Y (= 42) in the specialized
  //class foo below).
  static constexpr int Y = X;
};
T<42> foo;

С clang++ -std=c++14 Я получаю AST (отрывок), который выглядит следующим образом:

> clang++ -std=c++14 -Xclang -ast-dump -fsyntax-only file.cpp
|-ClassTemplateDecl 0x563e38c10980 <test_constexpr.cpp:1:1, line:7:1> line:2:7 T
...
| | `-VarDecl 0x563e38c10c98 <line:6:3, col:28> col:24 Y 'const int' static constexpr cinit
| |   `-DeclRefExpr 0x563e38c10d00 <col:28> 'int' NonTypeTemplateParm 0x563e38c10878 'X' 'int'
| `-ClassTemplateSpecializationDecl 0x563e38c10d78 <line:1:1, line:7:1> line:2:7 class T 
...
|   |-VarDecl 0x563e38c110c8 <line:6:3, col:28> col:24 Y 'const int' static constexpr cinit
|   | `-SubstNonTypeTemplateParmExpr 0x563e38c11160 <col:28> 'int' <== MISSING in C++17 BELOW
|   |   `-IntegerLiteral 0x563e38c11140 <col:28> 'int' 42          <== MISSING in C++17 BELOW

и все работает нормально (при условии, что decl - это второй VarDecl для Y, я могу получить доступ 42 by decl->getInit()).

С clang++ -std=c++17, однако, я получаю новый AST:

> clang++ -std=c++17 -Xclang -ast-dump -fsyntax-only file.cpp
|-ClassTemplateDecl 0x56114838ff40 <test_constexpr.cpp:1:1, line:7:1> line:2:7 T
...
| | `-VarDecl 0x561148390258 <line:6:3, col:28> col:24 Y 'const int' static inline constexpr cinit
| |   `-DeclRefExpr 0x5611483902c0 <col:28> 'int' NonTypeTemplateParm 0x56114838fe38 'X' 'int'
| `-ClassTemplateSpecializationDecl 0x561148390338 <line:1:1, line:7:1> line:2:7 class T 
...
|   |-VarDecl 0x561148390688 <line:6:3, col:24> col:24 Y 'const int' static constexpr

, в котором инициализирующее выражение для Y (-IntegerLiteral 0x563e38c11140 <col:28> 'int' 42) нет дольше появляется. Включение Y подобно int z = Y в определение класса приводит к повторному появлению инициализатора.

Вопросы

  1. Должен ли я ожидать, что нет чтобы увидеть выражение инициализатора в AST выше в clang++ -std=c++17?

  2. Если так, каков наилучший способ доступа к инициализатору для Y в T<42> foo изнутри LLVM- 9.x плагин?

Спасибо! И, пожалуйста, дайте мне знать, если я пропустил соответствующую информацию - я буду рад обновить вопрос, чтобы предоставить его.

...