Clang error: typename specifier refers to non-type member A in B (err_typename_nested_not_type)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: typename specifier refers to non-type member A in B
Type Error
Category Semantic Issue
Internal Id err_typename_nested_not_type
Internal Message typename specifier refers to non-type member %0 in %1
Regular Expression (?:error|fatal error)\: typename specifier refers to non\-type member (.*?) in (.*?)
First Commit 2009-03-28 333489bba35d Initial implementation of parsing, semantic analysis, and template

Description

The error is issued by the Clang compiler when attempting to use a non-type member (such as a member variable) with the typename specifier in a context where a type is expected. This occurs specifically in C++ programming when working with templates, where typename is used to indicate that the following identifier is a type that depends on a template parameter. The error message is generated because the compiler expects a type name to follow the typename specifier, but instead finds a member that is not a type, violating the expected syntax and semantic rules of C++ templates.

In C++, the typename keyword is crucial for telling the compiler that a dependent name in a template is a type. A common place to see the typename keyword is within template definitions or declarations, to specify that a nested name specifier refers to a type. The proper use of typename ensures the correct parsing and interpretation of template code. Misusing it by referring to non-type members leads to this error.

For example, within the context of templates, if attempting to define a variable or alias that uses typename to refer to a member of a type that is not itself a type (e.g., an integer member variable instead of a type definition within a class or struct), Clang will halt compilation and display this error. The error message is aimed at guiding developers to correct the misuse of typename, ensuring that it only precedes names that are indeed types, and not variables or other non-type members.

 
AI Generated

Example

In the following example, a structure named S is defined with a non-type member x, which is an integer. Another structure, T, attempts to define a member y using typename to specify that x is a type within S. However, since x is a non-type member (an integer) and not a type, this use of typename is incorrect and results in a compilation error. The Clang compiler identifies this misuse of the typename specifier and issues an error message, indicating that x cannot be treated as a type within the context of defining y in structure T.  
AI Generated


Flags -xc++

[Try out in Compiler Explorer]

Source
struct S { int x; }; // S has a non-type member x
struct T { typename S::x y; }; // Error: 'x' is a non-type member
Compiler Output
<source>:2:24: error: typename specifier refers to non-type member 'x' in 'S'
<source>:1:16: note: referenced member 'x' is declared here


Clang Internals (17.0.6)

Git Commit Message

Initial implementation of parsing, semantic analysis, and template
instantiation for C++ typename-specifiers such as

  typename T::type

The parsing of typename-specifiers is relatively easy thanks to
annotation tokens. When we see the "typename", we parse the
typename-specifier and produce a typename annotation token. There are
only a few places where we need to handle this. We currently parse the
typename-specifier form that terminates in an identifier, but not the
simple-template-id form, e.g.,

  typename T::template apply<U, V>

Parsing of nested-name-specifiers has a similar problem, since at this
point we don't have any representation of a class template
specialization whose template-name is unknown.

Semantic analysis is only partially complete, with some support for
template instantiation that works for simple examples. 

llvm-svn: 67875

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaTemplate.cpp (line 11144)

/// Build the type that describes a C++ typename specifier,
/// e.g., "typename T::type".
QualType Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo &II, SourceLocation IILoc, bool DeducedTSTContext) {
  // ...
  case LookupResult::Found:
    // ...
    DiagID = Ctx ? diag::err_typename_nested_not_type : diag::err_typename_not_type;

clang/lib/Sema/SemaTemplate.cpp (line 11150)

/// Build the type that describes a C++ typename specifier,
/// e.g., "typename T::type".
QualType Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo &II, SourceLocation IILoc, bool DeducedTSTContext) {
  // ...
  case LookupResult::FoundOverloaded:
    DiagID = Ctx ? diag::err_typename_nested_not_type : diag::err_typename_not_type;

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp

  • clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp:62:51: error: typename specifier refers to non-type member 'type' in 'D'