| commit | 1cb47c19f8eca4badd8fb5e1a1b1cf4aaab607b8 | [log] [tgz] |
|---|---|---|
| author | Andrey Ali Khan Bolshakov <bolsh.andrey@yandex.ru> | Thu Sep 04 18:32:12 2025 +0300 |
| committer | GitHub <noreply@github.com> | Thu Sep 04 15:32:12 2025 +0000 |
| tree | d93a81d4d8c5b14cc7c416039397fff7b334f8d3 | |
| parent | f6e8b26eab8324a60f437fdb3e88e5d5105c9845 [diff] |
[clang] Remove written template args from implicit var tpl spec (#156329)
`VarTemplateSpecializationDecl::getTemplateArgsAsWritten()` function
should return `nullptr` in the case of implicit instantiation, as its
`ClassTemplateSpecializationDecl` counterpart does, and not the
arguments written in `DeclRefExpr` referencing the specialization in the
first place. Otherwise, for such code:
```cpp
template <typename>
int VarTpl;
template <typename T>
void tplFn() {
(void)VarTpl<T>; // (1)
}
void fn() {
tplFn<char>();
}
```
Clang treats the `char` argument of the `VarTpl` specialization as if it
were written in the line marked as (1), which is misleading and hardly
makes sense.
Moreover, "template args as written" are stored inside `ExplicitInfo`
field of `VarTemplateSpecializationDecl`, but it is
[documented](https://github.com/llvm/llvm-project/blob/13357e8a12c1a45364a0c4d3137b6d21ee6ac40c/clang/include/clang/AST/DeclTemplate.h#L2653)
that it is not for implicit instantiations.
Moreover, it is assumed in `TraverseVarTemplateSpecializationDecl`
method of `RecursiveASTVisitor` that `getTemplateArgsAsWritten()`
returns `nullptr` for implicit instantiations, as it is stated in the
comment
[there](https://github.com/llvm/llvm-project/blob/13357e8a12c1a45364a0c4d3137b6d21ee6ac40c/clang/include/clang/AST/RecursiveASTVisitor.h#L2196).
That said, `setTemplateArgsAsWritten` should be called only for variable
template explicit specializations (it is [already done inside
`Sema::ActOnVarTemplateSpecialization`](https://github.com/llvm/llvm-project/blob/4c916273041ff5ed7b2af20bec787ffc42871c9f/clang/lib/Sema/SemaTemplate.cpp#L4459))
and explicit instantiations (hence `true` is passed to the new
`SetWrittenArgs` parameter of `CheckVarTemplateId` function inside
`Sema::ActOnExplicitInstantiation`, but not when handling expressions
referencing a variable template specialization).
`InstantiateVariableDefinition` function just passes the arguments from
the corresponding declaration. I'm not sure about instantiating a class
template containing a variable template explicit specialization and thus
have tried to leave the logic of the first overload of
`TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl` as it
was.Welcome to the LLVM project!
This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.
The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.
C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.
Other components include: the libc++ C++ standard library, the LLD linker, and more.
Consult the Getting Started with LLVM page for information on building and running LLVM.
For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.
Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.
The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.