diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 8e3ad4c266737..534a92d2cb870 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -969,7 +969,7 @@ void CXXNameMangler::mangleUnscopedTemplateName( assert(!AdditionalAbiTags && "template template param cannot have abi tags"); mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); - } else if (isa(ND)) { + } else if (isa(ND) || isa(ND)) { mangleUnscopedName(ND, AdditionalAbiTags); } else { mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); @@ -1890,7 +1890,7 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); } else { manglePrefix(getEffectiveDeclContext(ND), NoFunction); - if (isa(ND)) + if (isa(ND) || isa(ND)) mangleUnqualifiedName(ND, nullptr); else mangleUnqualifiedName(ND->getTemplatedDecl(), nullptr); @@ -3658,7 +3658,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::ConvertVectorExprClass: case Expr::StmtExprClass: case Expr::TypeTraitExprClass: - case Expr::ConceptSpecializationExprClass: case Expr::ArrayTypeTraitExprClass: case Expr::ExpressionTraitExprClass: case Expr::VAArgExprClass: @@ -4168,6 +4167,18 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { mangleExpression(cast(E)->getSubExpr(), Arity); break; + + case Expr::ConceptSpecializationExprClass: { + // ::= L E # external name + Out << "L_Z"; + auto *CSE = cast(E); + mangleTemplateName(CSE->getNamedConcept(), + CSE->getTemplateArguments().data(), + CSE->getTemplateArguments().size()); + Out << 'E'; + break; + } + case Expr::DeclRefExprClass: mangleDeclRefExpr(cast(E)->getDecl()); break; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 2871511466105..09cc525837c0d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4302,7 +4302,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, TemplateKWLoc, TemplateArgs); } - if (R.getAsSingle() && !AnyDependentArguments()) { + if (R.getAsSingle()) { return CheckConceptTemplateId(SS, TemplateKWLoc, R.getLookupNameInfo().getBeginLoc(), R.getFoundDecl(), diff --git a/clang/test/CodeGenCXX/mangle-concept.cpp b/clang/test/CodeGenCXX/mangle-concept.cpp new file mode 100644 index 0000000000000..7e9fb1b15e1ab --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-concept.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++2a -fconcepts-ts -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s +// expected-no-diagnostics + +namespace test1 { +template struct S {}; +template concept C = true; +template S> f0() { return S>{}; } +template S> f0<>(); +// CHECK: @_ZN5test12f0IiEENS_1SIXL_ZNS_1CIT_EEEEEEv( +} + +template struct S {}; +template concept C = true; +template S> f0() { return S>{}; } +template S> f0<>(); +// CHECK: @_Z2f0IiE1SIXL_Z1CIT_EEEEv(