llvm / llvm/llvm-project

some trivial code leads to "error: cannot import unsupported AST node ExplicitInstantiation" in libc++

Open
#219,802 9 comments 0 reactions 0 assignees View on GitHub
clang:frontend
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

**Summary**:
- this problem appeared in `LLVM 23.1.0` and for the same code `LLVM 22.1.8` works without any problem
- upon such error **the CTU analysis stops**
- this error **kills the useful CTU analysis capability for the majority of the TUs in many projects I tried :(**

Here are some minimal code and commands which uses the released compiler from [https://github.com/llvm/llvm-project/releases/download/llvmorg-23.1.0/LLVM-23.1.0-Linux-X64.tar.xz](https://github.com/llvm/llvm-project/releases/download/llvmorg-23.1.0/LLVM-23.1.0-Linux-X64.tar.xz) to demonstrate the problem:

**declaration.cpp**

```c++
namespace foo {

struct bar
{
static const bool qux;
};

}
```

**definition.cpp**

```c++
#include
#include

namespace foo {

struct bar
{
static const bool qux{false};
};

struct junk
{
std::string ham;
};

}
```

**Now create the `.ast` and `.map` file from `definition.cpp`:**

```
clang++ -stdlib=libc++ -std=c++17 ./definition.cpp -emit-ast -o ./definition.ast
clang-extdef-mapping definition.ast -- >./definition.map
```

The content of the newly created `definition.map` is this:

```
18:c:@N@foo@S@bar@qux /definition.ast
```

**And then finally run the CTU analysis -with the map created from `definition.cpp`- over `declaration.cpp`:**

```
clang++ -stdlib=libc++ -std=c++17 -c ./declaration.cpp \
-Xclang -analyze \
-Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true \
-Xclang -analyzer-config -Xclang ctu-index-name=./definition.map
```

**The output of the analysis:**

```
/bin/../include/c++/v1/__locale_dir/num.h:200:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:202:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:633:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:635:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:758:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:760:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:1006:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale_dir/num.h:1008:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__ostream/basic_ostream.h:671:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__ostream/basic_ostream.h:673:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/string:2510:40: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/string:2512:40: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/string:3679:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/streambuf:428:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/streambuf:431:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale:263:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale:265:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale:1271:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale:1273:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale:1275:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/__locale:1277:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/ios:745:8: error: cannot import unsupported AST node ExplicitInstantiation
/bin/../include/c++/v1/ios:748:8: error: cannot import unsupported AST node ExplicitInstantiation
```

All the referenced lines in libc++ above are extern templates:
```
extern template class _LIBCPP_DEPRECATED_IN_CXX20
extern template class _LIBCPP_DEPRECATED_IN_CXX20
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put;
extern template _LIBCPP_EXPORTED_FROM_ABI string operator+
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get;
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get;
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put;
extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put;
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, wchar_t)
```

I suspect that the new feature announced in `LLVM 23.1.0` [https://releases.llvm.org/23.1.0/tools/clang/docs/ReleaseNotes.html](https://releases.llvm.org/23.1.0/tools/clang/docs/ReleaseNotes.html) as:

```
Added a new ExplicitInstantiationDecl AST node to represent explicit template instantiations
(e.g., template void foo(); or extern template class S;).
Previously, source location information for explicit instantiation statements was discarded after parsing.
The new node preserves the full source range including the extern and template keywords, qualifiers,
template arguments as written, and the declared type, enabling tools such as language servers and
refactoring engines to accurately map source locations back to explicit instantiation sites.
```

has an incomplete/erroneous/missing/etc. implementation in the AST importing machinery in `clang/include/clang/AST/ASTImporter.h` introduced in [https://github.com/llvm/llvm-project/issues/191442](https://github.com/llvm/llvm-project/issues/191442)

But maybe I am wrong, and the solution for this problem is far more trivial than I think.

What is the recommended course of action for this problem?

Thanks, in advance!

Contributor guide

Open the contributing guide

Research direction

Reproduce the failure with declaration.cpp, definition.cpp, the LLVM 23.1.0 commands, and the generated definition.map. Start by reading clang/include/clang/AST/ASTImporter.h and the change described in issue 191442, focusing on ExplicitInstantiation. Done means the CTU analysis imports the libc++ AST without unsupported-node errors and continues analyzing declaration.cpp.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.