Skip to content

Commit c4a3157

Browse files
committed
Add mangling for type trait expressions.
libc++ uses type traits directly in constraints in some places, and constraints now appear in manglings. There's a defined mangling for these traits in the ABI already, so we should use it. Fixes #67031.
1 parent 33f6161 commit c4a3157

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4640,7 +4640,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
46404640
case Expr::ShuffleVectorExprClass:
46414641
case Expr::ConvertVectorExprClass:
46424642
case Expr::StmtExprClass:
4643-
case Expr::TypeTraitExprClass:
46444643
case Expr::ArrayTypeTraitExprClass:
46454644
case Expr::ExpressionTraitExprClass:
46464645
case Expr::VAArgExprClass:
@@ -4992,6 +4991,10 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
49924991
// If the result of the operator is implicitly converted to a known
49934992
// integer type, that type is used for the literal; otherwise, the type
49944993
// of std::size_t or std::ptrdiff_t is used.
4994+
//
4995+
// FIXME: We still include the operand in the profile in this case. This
4996+
// can lead to mangling collisions between function templates that we
4997+
// consider to be different.
49954998
QualType T = (ImplicitlyConvertedToType.isNull() ||
49964999
!ImplicitlyConvertedToType->isIntegerType())? SAE->getType()
49975000
: ImplicitlyConvertedToType;
@@ -5054,6 +5057,20 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
50545057
break;
50555058
}
50565059

5060+
case Expr::TypeTraitExprClass: {
5061+
// <expression> ::= u <source-name> <template-arg>* E # vendor extension
5062+
const TypeTraitExpr *TTE = cast<TypeTraitExpr>(E);
5063+
NotPrimaryExpr();
5064+
Out << 'u';
5065+
llvm::StringRef Spelling = getTraitSpelling(TTE->getTrait());
5066+
Out << Spelling.size() << Spelling;
5067+
for (TypeSourceInfo *TSI : TTE->getArgs()) {
5068+
mangleType(TSI->getType());
5069+
}
5070+
Out << 'E';
5071+
break;
5072+
}
5073+
50575074
case Expr::CXXThrowExprClass: {
50585075
NotPrimaryExpr();
50595076
const CXXThrowExpr *TE = cast<CXXThrowExpr>(E);

clang/test/CodeGenCXX/mangle-exprs.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,13 @@ namespace null {
389389
// CHECK-LABEL: define {{.*}} @_ZN4null8gnu_nullILPv0EEEvPN9enable_ifIXeqT_Ll0EEvE4typeE
390390
template void gnu_null<nullptr>(void *);
391391
}
392+
393+
namespace type_trait {
394+
template<typename T> void f(decltype(__is_trivially_copyable(T))) {}
395+
// CHECK-LABEL: define {{.*}} @_ZN10type_trait1fIiEEvDTu23__is_trivially_copyableT_EE
396+
template void f<int>(bool);
397+
398+
template<typename T> void g(decltype(__is_trivially_copyable(int) + T())) {}
399+
// CHECK-LABEL: define {{.*}} @_ZN10type_trait1gIiEEvDTplu23__is_trivially_copyableiEcvT__EE
400+
template void g<int>(int);
401+
}

0 commit comments

Comments
 (0)