forked from OSchip/llvm-project
Itanium Mangling: Fix handling of <expr-primary> in <template-arg>.
Previously, we were emitting an extraneous X .. E in <template-arg> around an <expr-primary> if the template argument was constructed from an expression (rather than an already-evaluated literal value). In such a case, we would then e.g. emit 'XLi0EE' instead of 'Li0E'. We had one special-case for DeclRefExpr expressions, in particular, to omit them the mangled-name without the surrounding X/E. However, unfortunately, that special case also triggered for ParmVarDecl (a subtype of VarDecl), and _incorrectly_ emitted 'L_Z .. E' instead of the proper 'Xfp_E'. This change causes mangleExpression itself to be responsible for emitting X/E around non-primary expressions, which removes the special-case, and corrects both these problems. Differential Revision: https://reviews.llvm.org/D95487
This commit is contained in:
parent
9c7aeaebb3
commit
8ca33605ff
|
@ -546,8 +546,8 @@ private:
|
|||
unsigned knownArity);
|
||||
void mangleCastExpression(const Expr *E, StringRef CastEncoding);
|
||||
void mangleInitListElements(const InitListExpr *InitList);
|
||||
void mangleDeclRefExpr(const NamedDecl *D);
|
||||
void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
|
||||
void mangleExpression(const Expr *E, unsigned Arity = UnknownArity,
|
||||
bool AsTemplateArg = false);
|
||||
void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom);
|
||||
void mangleCXXDtorType(CXXDtorType T);
|
||||
|
||||
|
@ -3872,33 +3872,8 @@ void CXXNameMangler::mangleInitListElements(const InitListExpr *InitList) {
|
|||
mangleExpression(InitList->getInit(i));
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleDeclRefExpr(const NamedDecl *D) {
|
||||
switch (D->getKind()) {
|
||||
default:
|
||||
// <expr-primary> ::= L <mangled-name> E # external name
|
||||
Out << 'L';
|
||||
mangle(D);
|
||||
Out << 'E';
|
||||
break;
|
||||
|
||||
case Decl::ParmVar:
|
||||
mangleFunctionParam(cast<ParmVarDecl>(D));
|
||||
break;
|
||||
|
||||
case Decl::EnumConstant: {
|
||||
const EnumConstantDecl *ED = cast<EnumConstantDecl>(D);
|
||||
mangleIntegerLiteral(ED->getType(), ED->getInitVal());
|
||||
break;
|
||||
}
|
||||
|
||||
case Decl::NonTypeTemplateParm:
|
||||
const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);
|
||||
mangleTemplateParameter(PD->getDepth(), PD->getIndex());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
|
||||
void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
|
||||
bool AsTemplateArg) {
|
||||
// <expression> ::= <unary operator-name> <expression>
|
||||
// ::= <binary operator-name> <expression> <expression>
|
||||
// ::= <trinary operator-name> <expression> <expression> <expression>
|
||||
|
@ -3912,6 +3887,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
|
|||
// ::= at <type> # alignof (a type)
|
||||
// ::= <template-param>
|
||||
// ::= <function-param>
|
||||
// ::= fpT # 'this' expression (part of <function-param>)
|
||||
// ::= sr <type> <unqualified-name> # dependent name
|
||||
// ::= sr <type> <unqualified-name> <template-args> # dependent template-id
|
||||
// ::= ds <expression> <expression> # expr.*expr
|
||||
|
@ -3920,11 +3896,55 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
|
|||
// ::= u <source-name> <template-arg>* E # vendor extended expression
|
||||
// ::= <expr-primary>
|
||||
// <expr-primary> ::= L <type> <value number> E # integer literal
|
||||
// ::= L <type <value float> E # floating literal
|
||||
// ::= L <type> <value float> E # floating literal
|
||||
// ::= L <type> <string type> E # string literal
|
||||
// ::= L <nullptr type> E # nullptr literal "LDnE"
|
||||
// ::= L <pointer type> 0 E # null pointer template argument
|
||||
// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C99); not used by clang
|
||||
// ::= L <mangled-name> E # external name
|
||||
// ::= fpT # 'this' expression
|
||||
QualType ImplicitlyConvertedToType;
|
||||
|
||||
// A top-level expression that's not <expr-primary> needs to be wrapped in
|
||||
// X...E in a template arg.
|
||||
bool IsPrimaryExpr = true;
|
||||
auto NotPrimaryExpr = [&] {
|
||||
if (AsTemplateArg && IsPrimaryExpr)
|
||||
Out << 'X';
|
||||
IsPrimaryExpr = false;
|
||||
};
|
||||
|
||||
auto MangleDeclRefExpr = [&](const NamedDecl *D) {
|
||||
switch (D->getKind()) {
|
||||
default:
|
||||
// <expr-primary> ::= L <mangled-name> E # external name
|
||||
Out << 'L';
|
||||
mangle(D);
|
||||
Out << 'E';
|
||||
break;
|
||||
|
||||
case Decl::ParmVar:
|
||||
NotPrimaryExpr();
|
||||
mangleFunctionParam(cast<ParmVarDecl>(D));
|
||||
break;
|
||||
|
||||
case Decl::EnumConstant: {
|
||||
// <expr-primary>
|
||||
const EnumConstantDecl *ED = cast<EnumConstantDecl>(D);
|
||||
mangleIntegerLiteral(ED->getType(), ED->getInitVal());
|
||||
break;
|
||||
}
|
||||
|
||||
case Decl::NonTypeTemplateParm:
|
||||
NotPrimaryExpr();
|
||||
const NonTypeTemplateParmDecl *PD = cast<NonTypeTemplateParmDecl>(D);
|
||||
mangleTemplateParameter(PD->getDepth(), PD->getIndex());
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// 'goto recurse' is used when handling a simple "unwrapping" node which
|
||||
// produces no output, where ImplicitlyConvertedToType and AsTemplateArg need
|
||||
// to be preserved.
|
||||
recurse:
|
||||
switch (E->getStmtClass()) {
|
||||
case Expr::NoStmtClass:
|
||||
|
@ -3996,6 +4016,7 @@ recurse:
|
|||
case Expr::SourceLocExprClass:
|
||||
case Expr::BuiltinBitCastExprClass:
|
||||
{
|
||||
NotPrimaryExpr();
|
||||
if (!NullOut) {
|
||||
// As bad as this diagnostic is, it's better than crashing.
|
||||
DiagnosticsEngine &Diags = Context.getDiags();
|
||||
|
@ -4003,11 +4024,13 @@ recurse:
|
|||
"cannot yet mangle expression type %0");
|
||||
Diags.Report(E->getExprLoc(), DiagID)
|
||||
<< E->getStmtClassName() << E->getSourceRange();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Expr::CXXUuidofExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXUuidofExpr *UE = cast<CXXUuidofExpr>(E);
|
||||
// As of clang 12, uuidof uses the vendor extended expression
|
||||
// mangling. Previously, it used a special-cased nonstandard extension.
|
||||
|
@ -4027,7 +4050,7 @@ recurse:
|
|||
} else {
|
||||
Expr *UuidExp = UE->getExprOperand();
|
||||
Out << "u8__uuidofz";
|
||||
mangleExpression(UuidExp, Arity);
|
||||
mangleExpression(UuidExp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -4035,13 +4058,14 @@ recurse:
|
|||
|
||||
// Even gcc-4.5 doesn't mangle this.
|
||||
case Expr::BinaryConditionalOperatorClass: {
|
||||
NotPrimaryExpr();
|
||||
DiagnosticsEngine &Diags = Context.getDiags();
|
||||
unsigned DiagID =
|
||||
Diags.getCustomDiagID(DiagnosticsEngine::Error,
|
||||
"?: operator with omitted middle operand cannot be mangled");
|
||||
Diags.Report(E->getExprLoc(), DiagID)
|
||||
<< E->getStmtClassName() << E->getSourceRange();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
// These are used for internal purposes and cannot be meaningfully mangled.
|
||||
|
@ -4049,6 +4073,7 @@ recurse:
|
|||
llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");
|
||||
|
||||
case Expr::InitListExprClass: {
|
||||
NotPrimaryExpr();
|
||||
Out << "il";
|
||||
mangleInitListElements(cast<InitListExpr>(E));
|
||||
Out << "E";
|
||||
|
@ -4056,6 +4081,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::DesignatedInitExprClass: {
|
||||
NotPrimaryExpr();
|
||||
auto *DIE = cast<DesignatedInitExpr>(E);
|
||||
for (const auto &Designator : DIE->designators()) {
|
||||
if (Designator.isFieldDesignator()) {
|
||||
|
@ -4077,27 +4103,27 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXDefaultArgExprClass:
|
||||
mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr(), Arity);
|
||||
break;
|
||||
E = cast<CXXDefaultArgExpr>(E)->getExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::CXXDefaultInitExprClass:
|
||||
mangleExpression(cast<CXXDefaultInitExpr>(E)->getExpr(), Arity);
|
||||
break;
|
||||
E = cast<CXXDefaultInitExpr>(E)->getExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::CXXStdInitializerListExprClass:
|
||||
mangleExpression(cast<CXXStdInitializerListExpr>(E)->getSubExpr(), Arity);
|
||||
break;
|
||||
E = cast<CXXStdInitializerListExpr>(E)->getSubExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::SubstNonTypeTemplateParmExprClass:
|
||||
mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),
|
||||
Arity);
|
||||
break;
|
||||
E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement();
|
||||
goto recurse;
|
||||
|
||||
case Expr::UserDefinedLiteralClass:
|
||||
// We follow g++'s approach of mangling a UDL as a call to the literal
|
||||
// operator.
|
||||
case Expr::CXXMemberCallExprClass: // fallthrough
|
||||
case Expr::CallExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CallExpr *CE = cast<CallExpr>(E);
|
||||
|
||||
// <expression> ::= cp <simple-id> <expression>* E
|
||||
|
@ -4128,6 +4154,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXNewExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXNewExpr *New = cast<CXXNewExpr>(E);
|
||||
if (New->isGlobalNew()) Out << "gs";
|
||||
Out << (New->isArray() ? "na" : "nw");
|
||||
|
@ -4163,6 +4190,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXPseudoDestructorExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const auto *PDE = cast<CXXPseudoDestructorExpr>(E);
|
||||
if (const Expr *Base = PDE->getBase())
|
||||
mangleMemberExprBase(Base, PDE->isArrow());
|
||||
|
@ -4189,6 +4217,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::MemberExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const MemberExpr *ME = cast<MemberExpr>(E);
|
||||
mangleMemberExpr(ME->getBase(), ME->isArrow(),
|
||||
ME->getQualifier(), nullptr,
|
||||
|
@ -4199,6 +4228,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::UnresolvedMemberExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
|
||||
mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(),
|
||||
ME->isArrow(), ME->getQualifier(), nullptr,
|
||||
|
@ -4209,6 +4239,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXDependentScopeMemberExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXDependentScopeMemberExpr *ME
|
||||
= cast<CXXDependentScopeMemberExpr>(E);
|
||||
mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(),
|
||||
|
@ -4221,6 +4252,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::UnresolvedLookupExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
|
||||
mangleUnresolvedName(ULE->getQualifier(), ULE->getName(),
|
||||
ULE->getTemplateArgs(), ULE->getNumTemplateArgs(),
|
||||
|
@ -4229,6 +4261,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXUnresolvedConstructExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);
|
||||
unsigned N = CE->getNumArgs();
|
||||
|
||||
|
@ -4239,7 +4272,7 @@ recurse:
|
|||
mangleType(CE->getType());
|
||||
mangleInitListElements(IL);
|
||||
Out << "E";
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
Out << "cv";
|
||||
|
@ -4251,14 +4284,17 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXConstructExprClass: {
|
||||
// An implicit cast is silent, thus may contain <expr-primary>.
|
||||
const auto *CE = cast<CXXConstructExpr>(E);
|
||||
if (!CE->isListInitialization() || CE->isStdInitListInitialization()) {
|
||||
assert(
|
||||
CE->getNumArgs() >= 1 &&
|
||||
(CE->getNumArgs() == 1 || isa<CXXDefaultArgExpr>(CE->getArg(1))) &&
|
||||
"implicit CXXConstructExpr must have one argument");
|
||||
return mangleExpression(cast<CXXConstructExpr>(E)->getArg(0));
|
||||
E = cast<CXXConstructExpr>(E)->getArg(0);
|
||||
goto recurse;
|
||||
}
|
||||
NotPrimaryExpr();
|
||||
Out << "il";
|
||||
for (auto *E : CE->arguments())
|
||||
mangleExpression(E);
|
||||
|
@ -4267,6 +4303,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXTemporaryObjectExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const auto *CE = cast<CXXTemporaryObjectExpr>(E);
|
||||
unsigned N = CE->getNumArgs();
|
||||
bool List = CE->isListInitialization();
|
||||
|
@ -4296,17 +4333,20 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXScalarValueInitExprClass:
|
||||
NotPrimaryExpr();
|
||||
Out << "cv";
|
||||
mangleType(E->getType());
|
||||
Out << "_E";
|
||||
break;
|
||||
|
||||
case Expr::CXXNoexceptExprClass:
|
||||
NotPrimaryExpr();
|
||||
Out << "nx";
|
||||
mangleExpression(cast<CXXNoexceptExpr>(E)->getOperand());
|
||||
break;
|
||||
|
||||
case Expr::UnaryExprOrTypeTraitExprClass: {
|
||||
// Non-instantiation-dependent traits are an <expr-primary> integer literal.
|
||||
const UnaryExprOrTypeTraitExpr *SAE = cast<UnaryExprOrTypeTraitExpr>(E);
|
||||
|
||||
if (!SAE->isInstantiationDependent()) {
|
||||
|
@ -4326,6 +4366,8 @@ recurse:
|
|||
break;
|
||||
}
|
||||
|
||||
NotPrimaryExpr(); // But otherwise, they are not.
|
||||
|
||||
auto MangleAlignofSizeofArg = [&] {
|
||||
if (SAE->isArgumentType()) {
|
||||
Out << 't';
|
||||
|
@ -4380,6 +4422,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXThrowExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXThrowExpr *TE = cast<CXXThrowExpr>(E);
|
||||
// <expression> ::= tw <expression> # throw expression
|
||||
// ::= tr # rethrow
|
||||
|
@ -4393,6 +4436,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXTypeidExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXTypeidExpr *TIE = cast<CXXTypeidExpr>(E);
|
||||
// <expression> ::= ti <type> # typeid (type)
|
||||
// ::= te <expression> # typeid (expression)
|
||||
|
@ -4407,6 +4451,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXDeleteExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXDeleteExpr *DE = cast<CXXDeleteExpr>(E);
|
||||
// <expression> ::= [gs] dl <expression> # [::] delete expr
|
||||
// ::= [gs] da <expression> # [::] delete [] expr
|
||||
|
@ -4417,6 +4462,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::UnaryOperatorClass: {
|
||||
NotPrimaryExpr();
|
||||
const UnaryOperator *UO = cast<UnaryOperator>(E);
|
||||
mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
|
||||
/*Arity=*/1);
|
||||
|
@ -4425,6 +4471,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::ArraySubscriptExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(E);
|
||||
|
||||
// Array subscript is treated as a syntactically weird form of
|
||||
|
@ -4436,6 +4483,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::MatrixSubscriptExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const MatrixSubscriptExpr *ME = cast<MatrixSubscriptExpr>(E);
|
||||
Out << "ixix";
|
||||
mangleExpression(ME->getBase());
|
||||
|
@ -4446,6 +4494,7 @@ recurse:
|
|||
|
||||
case Expr::CompoundAssignOperatorClass: // fallthrough
|
||||
case Expr::BinaryOperatorClass: {
|
||||
NotPrimaryExpr();
|
||||
const BinaryOperator *BO = cast<BinaryOperator>(E);
|
||||
if (BO->getOpcode() == BO_PtrMemD)
|
||||
Out << "ds";
|
||||
|
@ -4458,6 +4507,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXRewrittenBinaryOperatorClass: {
|
||||
NotPrimaryExpr();
|
||||
// The mangled form represents the original syntax.
|
||||
CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
|
||||
cast<CXXRewrittenBinaryOperator>(E)->getDecomposedForm();
|
||||
|
@ -4469,6 +4519,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::ConditionalOperatorClass: {
|
||||
NotPrimaryExpr();
|
||||
const ConditionalOperator *CO = cast<ConditionalOperator>(E);
|
||||
mangleOperatorName(OO_Conditional, /*Arity=*/3);
|
||||
mangleExpression(CO->getCond());
|
||||
|
@ -4484,19 +4535,22 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::ObjCBridgedCastExprClass: {
|
||||
NotPrimaryExpr();
|
||||
// Mangle ownership casts as a vendor extended operator __bridge,
|
||||
// __bridge_transfer, or __bridge_retain.
|
||||
StringRef Kind = cast<ObjCBridgedCastExpr>(E)->getBridgeKindName();
|
||||
Out << "v1U" << Kind.size() << Kind;
|
||||
mangleCastExpression(E, "cv");
|
||||
break;
|
||||
}
|
||||
// Fall through to mangle the cast itself.
|
||||
LLVM_FALLTHROUGH;
|
||||
|
||||
case Expr::CStyleCastExprClass:
|
||||
NotPrimaryExpr();
|
||||
mangleCastExpression(E, "cv");
|
||||
break;
|
||||
|
||||
case Expr::CXXFunctionalCastExprClass: {
|
||||
NotPrimaryExpr();
|
||||
auto *Sub = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreImplicit();
|
||||
// FIXME: Add isImplicit to CXXConstructExpr.
|
||||
if (auto *CCE = dyn_cast<CXXConstructExpr>(Sub))
|
||||
|
@ -4516,22 +4570,28 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXStaticCastExprClass:
|
||||
NotPrimaryExpr();
|
||||
mangleCastExpression(E, "sc");
|
||||
break;
|
||||
case Expr::CXXDynamicCastExprClass:
|
||||
NotPrimaryExpr();
|
||||
mangleCastExpression(E, "dc");
|
||||
break;
|
||||
case Expr::CXXReinterpretCastExprClass:
|
||||
NotPrimaryExpr();
|
||||
mangleCastExpression(E, "rc");
|
||||
break;
|
||||
case Expr::CXXConstCastExprClass:
|
||||
NotPrimaryExpr();
|
||||
mangleCastExpression(E, "cc");
|
||||
break;
|
||||
case Expr::CXXAddrspaceCastExprClass:
|
||||
NotPrimaryExpr();
|
||||
mangleCastExpression(E, "ac");
|
||||
break;
|
||||
|
||||
case Expr::CXXOperatorCallExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);
|
||||
unsigned NumArgs = CE->getNumArgs();
|
||||
// A CXXOperatorCallExpr for OO_Arrow models only semantics, not syntax
|
||||
|
@ -4545,9 +4605,8 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::ParenExprClass:
|
||||
mangleExpression(cast<ParenExpr>(E)->getSubExpr(), Arity);
|
||||
break;
|
||||
|
||||
E = cast<ParenExpr>(E)->getSubExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::ConceptSpecializationExprClass: {
|
||||
// <expr-primary> ::= L <mangled-name> E # external name
|
||||
|
@ -4561,10 +4620,12 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::DeclRefExprClass:
|
||||
mangleDeclRefExpr(cast<DeclRefExpr>(E)->getDecl());
|
||||
// MangleDeclRefExpr helper handles primary-vs-nonprimary
|
||||
MangleDeclRefExpr(cast<DeclRefExpr>(E)->getDecl());
|
||||
break;
|
||||
|
||||
case Expr::SubstNonTypeTemplateParmPackExprClass:
|
||||
NotPrimaryExpr();
|
||||
// FIXME: not clear how to mangle this!
|
||||
// template <unsigned N...> class A {
|
||||
// template <class U...> void foo(U (&x)[N]...);
|
||||
|
@ -4573,14 +4634,16 @@ recurse:
|
|||
break;
|
||||
|
||||
case Expr::FunctionParmPackExprClass: {
|
||||
NotPrimaryExpr();
|
||||
// FIXME: not clear how to mangle this!
|
||||
const FunctionParmPackExpr *FPPE = cast<FunctionParmPackExpr>(E);
|
||||
Out << "v110_SUBSTPACK";
|
||||
mangleDeclRefExpr(FPPE->getParameterPack());
|
||||
MangleDeclRefExpr(FPPE->getParameterPack());
|
||||
break;
|
||||
}
|
||||
|
||||
case Expr::DependentScopeDeclRefExprClass: {
|
||||
NotPrimaryExpr();
|
||||
const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
|
||||
mangleUnresolvedName(DRE->getQualifier(), DRE->getDeclName(),
|
||||
DRE->getTemplateArgs(), DRE->getNumTemplateArgs(),
|
||||
|
@ -4589,24 +4652,27 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXBindTemporaryExprClass:
|
||||
mangleExpression(cast<CXXBindTemporaryExpr>(E)->getSubExpr());
|
||||
break;
|
||||
E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::ExprWithCleanupsClass:
|
||||
mangleExpression(cast<ExprWithCleanups>(E)->getSubExpr(), Arity);
|
||||
break;
|
||||
E = cast<ExprWithCleanups>(E)->getSubExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::FloatingLiteralClass: {
|
||||
// <expr-primary>
|
||||
const FloatingLiteral *FL = cast<FloatingLiteral>(E);
|
||||
mangleFloatLiteral(FL->getType(), FL->getValue());
|
||||
break;
|
||||
}
|
||||
|
||||
case Expr::FixedPointLiteralClass:
|
||||
// Currently unimplemented -- might be <expr-primary> in future?
|
||||
mangleFixedPointLiteral();
|
||||
break;
|
||||
|
||||
case Expr::CharacterLiteralClass:
|
||||
// <expr-primary>
|
||||
Out << 'L';
|
||||
mangleType(E->getType());
|
||||
Out << cast<CharacterLiteral>(E)->getValue();
|
||||
|
@ -4615,18 +4681,21 @@ recurse:
|
|||
|
||||
// FIXME. __objc_yes/__objc_no are mangled same as true/false
|
||||
case Expr::ObjCBoolLiteralExprClass:
|
||||
// <expr-primary>
|
||||
Out << "Lb";
|
||||
Out << (cast<ObjCBoolLiteralExpr>(E)->getValue() ? '1' : '0');
|
||||
Out << 'E';
|
||||
break;
|
||||
|
||||
case Expr::CXXBoolLiteralExprClass:
|
||||
// <expr-primary>
|
||||
Out << "Lb";
|
||||
Out << (cast<CXXBoolLiteralExpr>(E)->getValue() ? '1' : '0');
|
||||
Out << 'E';
|
||||
break;
|
||||
|
||||
case Expr::IntegerLiteralClass: {
|
||||
// <expr-primary>
|
||||
llvm::APSInt Value(cast<IntegerLiteral>(E)->getValue());
|
||||
if (E->getType()->isSignedIntegerType())
|
||||
Value.setIsSigned(true);
|
||||
|
@ -4635,6 +4704,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::ImaginaryLiteralClass: {
|
||||
// <expr-primary>
|
||||
const ImaginaryLiteral *IE = cast<ImaginaryLiteral>(E);
|
||||
// Mangle as if a complex literal.
|
||||
// Proposal from David Vandevoorde, 2010.06.30.
|
||||
|
@ -4658,6 +4728,7 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::StringLiteralClass: {
|
||||
// <expr-primary>
|
||||
// Revised proposal from David Vandervoorde, 2010.07.15.
|
||||
Out << 'L';
|
||||
assert(isa<ConstantArrayType>(E->getType()));
|
||||
|
@ -4667,21 +4738,25 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::GNUNullExprClass:
|
||||
// <expr-primary>
|
||||
// Mangle as if an integer literal 0.
|
||||
mangleIntegerLiteral(E->getType(), llvm::APSInt(32));
|
||||
break;
|
||||
|
||||
case Expr::CXXNullPtrLiteralExprClass: {
|
||||
// <expr-primary>
|
||||
Out << "LDnE";
|
||||
break;
|
||||
}
|
||||
|
||||
case Expr::PackExpansionExprClass:
|
||||
NotPrimaryExpr();
|
||||
Out << "sp";
|
||||
mangleExpression(cast<PackExpansionExpr>(E)->getPattern());
|
||||
break;
|
||||
|
||||
case Expr::SizeOfPackExprClass: {
|
||||
NotPrimaryExpr();
|
||||
auto *SPE = cast<SizeOfPackExpr>(E);
|
||||
if (SPE->isPartiallySubstituted()) {
|
||||
Out << "sP";
|
||||
|
@ -4706,12 +4781,12 @@ recurse:
|
|||
break;
|
||||
}
|
||||
|
||||
case Expr::MaterializeTemporaryExprClass: {
|
||||
mangleExpression(cast<MaterializeTemporaryExpr>(E)->getSubExpr());
|
||||
break;
|
||||
}
|
||||
case Expr::MaterializeTemporaryExprClass:
|
||||
E = cast<MaterializeTemporaryExpr>(E)->getSubExpr();
|
||||
goto recurse;
|
||||
|
||||
case Expr::CXXFoldExprClass: {
|
||||
NotPrimaryExpr();
|
||||
auto *FE = cast<CXXFoldExpr>(E);
|
||||
if (FE->isLeftFold())
|
||||
Out << (FE->getInit() ? "fL" : "fl");
|
||||
|
@ -4733,27 +4808,34 @@ recurse:
|
|||
}
|
||||
|
||||
case Expr::CXXThisExprClass:
|
||||
NotPrimaryExpr();
|
||||
Out << "fpT";
|
||||
break;
|
||||
|
||||
case Expr::CoawaitExprClass:
|
||||
// FIXME: Propose a non-vendor mangling.
|
||||
NotPrimaryExpr();
|
||||
Out << "v18co_await";
|
||||
mangleExpression(cast<CoawaitExpr>(E)->getOperand());
|
||||
break;
|
||||
|
||||
case Expr::DependentCoawaitExprClass:
|
||||
// FIXME: Propose a non-vendor mangling.
|
||||
NotPrimaryExpr();
|
||||
Out << "v18co_await";
|
||||
mangleExpression(cast<DependentCoawaitExpr>(E)->getOperand());
|
||||
break;
|
||||
|
||||
case Expr::CoyieldExprClass:
|
||||
// FIXME: Propose a non-vendor mangling.
|
||||
NotPrimaryExpr();
|
||||
Out << "v18co_yield";
|
||||
mangleExpression(cast<CoawaitExpr>(E)->getOperand());
|
||||
break;
|
||||
}
|
||||
|
||||
if (AsTemplateArg && !IsPrimaryExpr)
|
||||
Out << 'E';
|
||||
}
|
||||
|
||||
/// Mangle an expression which refers to a parameter variable.
|
||||
|
@ -5003,10 +5085,9 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
|
|||
Out << "Dp";
|
||||
mangleType(A.getAsTemplateOrTemplatePattern());
|
||||
break;
|
||||
case TemplateArgument::Expression: {
|
||||
case TemplateArgument::Expression:
|
||||
mangleTemplateArgExpr(A.getAsExpr());
|
||||
break;
|
||||
}
|
||||
case TemplateArgument::Integral:
|
||||
mangleIntegerLiteral(A.getIntegralType(), A.getAsIntegral());
|
||||
break;
|
||||
|
@ -5062,9 +5143,22 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
|
|||
}
|
||||
|
||||
void CXXNameMangler::mangleTemplateArgExpr(const Expr *E) {
|
||||
// It's possible to end up with a DeclRefExpr here in certain
|
||||
// dependent cases, in which case we should mangle as a
|
||||
// declaration.
|
||||
ASTContext &Ctx = Context.getASTContext();
|
||||
if (Ctx.getLangOpts().getClangABICompat() > LangOptions::ClangABI::Ver11) {
|
||||
mangleExpression(E, UnknownArity, /*AsTemplateArg=*/true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prior to Clang 12, we didn't omit the X .. E around <expr-primary>
|
||||
// correctly in cases where the template argument was
|
||||
// constructed from an expression rather than an already-evaluated
|
||||
// literal. In such a case, we would then e.g. emit 'XLi0EE' instead of
|
||||
// 'Li0E'.
|
||||
//
|
||||
// We did special-case DeclRefExpr to attempt to DTRT for that one
|
||||
// expression-kind, but while doing so, unfortunately handled ParmVarDecl
|
||||
// (subtype of VarDecl) _incorrectly_, and emitted 'L_Z .. E' instead of
|
||||
// the proper 'Xfp_E'.
|
||||
E = E->IgnoreParenImpCasts();
|
||||
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
|
||||
const ValueDecl *D = DRE->getDecl();
|
||||
|
@ -5075,7 +5169,6 @@ void CXXNameMangler::mangleTemplateArgExpr(const Expr *E) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Out << 'X';
|
||||
mangleExpression(E);
|
||||
Out << 'E';
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
// RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fclang-abi-compat=3.0 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.0 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.8 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.9 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=4.0 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=5 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=11 %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17 %s
|
||||
// RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fclang-abi-compat=latest %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,V39,V5,V12 %s
|
||||
// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fclang-abi-compat=latest %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17 %s
|
||||
// RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.0 %s -emit-llvm -o - -Wno-c++11-extensions \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.0 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.8 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.9 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=4.0 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=5 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17 %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=11 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17 %s
|
||||
// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=11 %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE12-CXX20 %s
|
||||
// RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=latest %s -emit-llvm -o - -Wno-c++11-extensions \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12 %s
|
||||
// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=latest %s -emit-llvm -o - \
|
||||
// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20 %s
|
||||
|
||||
typedef __attribute__((vector_size(8))) long long v1xi64;
|
||||
void clang39(v1xi64) {}
|
||||
|
@ -55,3 +66,68 @@ template void clang12_b<arr>();
|
|||
// CHECK: @_Z9clang12_cIXadL_Z3arrEEEvv
|
||||
template<const char (*)[6]> void clang12_c() {}
|
||||
template void clang12_c<&arr>();
|
||||
|
||||
|
||||
/// Tests for <template-arg> <expr-primary> changes in clang12:
|
||||
namespace expr_primary {
|
||||
struct A {
|
||||
template<int N> struct Int {};
|
||||
template<int& N> struct Ref {};
|
||||
};
|
||||
|
||||
/// Check various DeclRefExpr manglings
|
||||
|
||||
// PRE12: @_ZN12expr_primary5test1INS_1AEEEvNT_3IntIXLi1EEEE
|
||||
// V12: @_ZN12expr_primary5test1INS_1AEEEvNT_3IntILi1EEE
|
||||
template <typename T> void test1(typename T::template Int<1> a) {}
|
||||
template void test1<A>(typename A::template Int<1> a);
|
||||
|
||||
enum Enum { EnumVal = 4 };
|
||||
int Global;
|
||||
|
||||
// PRE12: @_ZN12expr_primary5test2INS_1AEEEvNT_3IntIXLNS_4EnumE4EEEE
|
||||
// V12: @_ZN12expr_primary5test2INS_1AEEEvNT_3IntILNS_4EnumE4EEE
|
||||
template <typename T> void test2(typename T::template Int<EnumVal> a) {}
|
||||
template void test2<A>(typename A::template Int<4> a);
|
||||
|
||||
// CHECK: @_ZN12expr_primary5test3ILi3EEEvNS_1A3IntIXT_EEE
|
||||
template <int X> void test3(typename A::template Int<X> a) {}
|
||||
template void test3<3>(A::Int<3> a);
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
// CHECK-CXX20: @_ZN12expr_primary5test4INS_1AEEEvNT_3RefIL_ZNS_6GlobalEEEE
|
||||
template <typename T> void test4(typename T::template Ref<(Global)> a) {}
|
||||
template void test4<A>(typename A::template Ref<Global> a);
|
||||
|
||||
struct B {
|
||||
struct X {
|
||||
constexpr X(double) {}
|
||||
constexpr X(int&) {}
|
||||
};
|
||||
template<X> struct Y {};
|
||||
};
|
||||
|
||||
// PRE12-CXX20: _ZN12expr_primary5test5INS_1BEEEvNT_1YIXLd3ff0000000000000EEEE
|
||||
// V12-CXX20: _ZN12expr_primary5test5INS_1BEEEvNT_1YILd3ff0000000000000EEE
|
||||
template<typename T> void test5(typename T::template Y<1.0>) { }
|
||||
template void test5<B>(typename B::Y<1.0>);
|
||||
|
||||
// PRE12-CXX20: @_ZN12expr_primary5test6INS_1BEEENT_1YIL_ZZNS_5test6EiE1bEEEi
|
||||
// V12-CXX20: @_ZN12expr_primary5test6INS_1BEEENT_1YIXfp_EEEi
|
||||
template<typename T> auto test6(int b) -> typename T::template Y<b> { return {}; }
|
||||
template auto test6<B>(int b) -> B::Y<b>;
|
||||
#endif
|
||||
|
||||
/// Verify non-dependent type-traits within a dependent template arg.
|
||||
|
||||
// PRE12: @_ZN12expr_primary5test7INS_1AEEEvNT_3IntIXLm1EEEE
|
||||
// V12: @_ZN12expr_primary5test7INS_1AEEEvNT_3IntILm1EEE
|
||||
template <class T> void test7(typename T::template Int<sizeof(char)> a) {}
|
||||
template void test7<A>(A::Int<1>);
|
||||
|
||||
// PRE12: @_ZN12expr_primary5test8ILi2EEEvu11matrix_typeIXLi1EEXT_EiE
|
||||
// V12: @_ZN12expr_primary5test8ILi2EEEvu11matrix_typeILi1EXT_EiE
|
||||
template<int N> using matrix1xN = int __attribute__((matrix_type(1, N)));
|
||||
template<int N> void test8(matrix1xN<N> a) {}
|
||||
template void test8<2>(matrix1xN<2> a);
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ namespace pr30440 {
|
|||
template<class F> void g(F);
|
||||
template<class ...A> auto h(A ...a)->decltype (g (0, g < a > (a) ...)) {
|
||||
}
|
||||
// CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIL_ZZNS_1hEDpT_E1aEEfp_EEES2_(
|
||||
// CHECK-DAG: define {{.*}} @_ZN7pr304401hIJEEEDTcl1gLi0Espcl1gIXfp_EEfp_EEEDpT_(
|
||||
|
||||
void pr30440_test () {
|
||||
h();
|
||||
|
|
|
@ -6,11 +6,11 @@ template <bool> struct S {};
|
|||
template <typename> concept C = true;
|
||||
template <typename T = int> S<C<T>> f0() { return S<C<T>>{}; }
|
||||
template S<C<int>> f0<>();
|
||||
// CHECK: @_ZN5test12f0IiEENS_1SIXL_ZNS_1CIT_EEEEEEv(
|
||||
// CHECK: @_ZN5test12f0IiEENS_1SIL_ZNS_1CIT_EEEEEv(
|
||||
}
|
||||
|
||||
template <bool> struct S {};
|
||||
template <typename> concept C = true;
|
||||
template <typename T = int> S<C<T>> f0() { return S<C<T>>{}; }
|
||||
template S<C<int>> f0<>();
|
||||
// CHECK: @_Z2f0IiE1SIXL_Z1CIT_EEEEv(
|
||||
// CHECK: @_Z2f0IiE1SIL_Z1CIT_EEEv(
|
||||
|
|
|
@ -270,7 +270,7 @@ namespace test17 {
|
|||
// Note: there is no J...E here, because we can't form a pack argument, and
|
||||
// the 5u and 6u are mangled with the original type 'j' (unsigned int) not
|
||||
// with the resolved type 'i' (signed int).
|
||||
// CHECK: define {{.*}} @_ZN6test171hILi4EJLi1ELi2ELi3EEEEvNS_1XIXspT0_EXLj5EEXT_EXLj6EEEE
|
||||
// CHECK: define {{.*}} @_ZN6test171hILi4EJLi1ELi2ELi3EEEEvNS_1XIXspT0_ELj5EXT_ELj6EEE
|
||||
template<int D, int ...C> void h(X<C..., 5u, D, 6u>) {}
|
||||
void i() { h<4, 1, 2, 3>({}); }
|
||||
|
||||
|
@ -323,7 +323,7 @@ namespace partially_dependent_template_args {
|
|||
// callee is unresolved, the rest mangle the converted argument Lj0E
|
||||
// because the callee is resolved.
|
||||
void h() {
|
||||
// CHECK: @_ZN33partially_dependent_template_args5test22g1INS0_1XEEEvDTcl1fIXLi0EEEcvT__EEE
|
||||
// CHECK: @_ZN33partially_dependent_template_args5test22g1INS0_1XEEEvDTcl1fILi0EEcvT__EEE
|
||||
g1<X>({});
|
||||
// CHECK: @_ZN33partially_dependent_template_args5test22g2IiEEvDTplclL_ZNS0_1fILj0EEEiNS0_1XEEilEEcvT__EE
|
||||
g2<int>({});
|
||||
|
|
|
@ -1123,7 +1123,7 @@ namespace test56 {
|
|||
namespace test57 {
|
||||
struct X { template <int N> int f(); } x;
|
||||
template<int N> void f(decltype(x.f<0>() + N)) {}
|
||||
// CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fIXLi0EEEET_E
|
||||
// CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fILi0EEET_E
|
||||
template void f<0>(int);
|
||||
}
|
||||
|
||||
|
|
|
@ -215,14 +215,14 @@ void test_template_deduction() {
|
|||
// CHECK-NEXT: %m4 = alloca [144 x float], align 4
|
||||
// CHECK-NEXT: %v = alloca %struct.selector.3, align 1
|
||||
// CHECK-NEXT: %undef.agg.tmp4 = alloca %struct.selector.3, align 1
|
||||
// CHECK-NEXT: call void @_Z10use_matrixIiLm12EE8selectorILi3EERu11matrix_typeIXLm10EEXT0_ET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m0)
|
||||
// CHECK-NEXT: call void @_Z10use_matrixIiLm12EE8selectorILi3EERu11matrix_typeILm10EXT0_ET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m0)
|
||||
// CHECK-NEXT: call void @_Z10use_matrixIiE8selectorILi2EERu11matrix_typeILm10ELm10ET_E([100 x i32]* nonnull align 4 dereferenceable(400) %m1)
|
||||
// CHECK-NEXT: call void @_Z10use_matrixIiLm12EE8selectorILi1EERu11matrix_typeIXT0_EXLm10EET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m2)
|
||||
// CHECK-NEXT: call void @_Z10use_matrixIiLm12EE8selectorILi1EERu11matrix_typeIXT0_ELm10ET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m2)
|
||||
// CHECK-NEXT: call void @_Z10use_matrixIiLm12ELm12EE8selectorILi0EERu11matrix_typeIXT0_EXT1_ET_E([144 x i32]* nonnull align 4 dereferenceable(576) %m3)
|
||||
// CHECK-NEXT: call void @_Z10use_matrixILm12ELm12EE8selectorILi4EERu11matrix_typeIXT_EXT0_EfE([144 x float]* nonnull align 4 dereferenceable(576) %m4)
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12EE8selectorILi3EERu11matrix_typeIXLm10EEXT0_ET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m)
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12EE8selectorILi3EERu11matrix_typeILm10EXT0_ET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m)
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %m.addr = alloca [120 x i32]*, align 8
|
||||
// CHECK-NEXT: store [120 x i32]* %m, [120 x i32]** %m.addr, align 8
|
||||
|
@ -236,7 +236,7 @@ void test_template_deduction() {
|
|||
// CHECK-NEXT: call void @llvm.trap()
|
||||
// CHECK-NEXT: unreachable
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12EE8selectorILi1EERu11matrix_typeIXT0_EXLm10EET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m)
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12EE8selectorILi1EERu11matrix_typeIXT0_ELm10ET_E([120 x i32]* nonnull align 4 dereferenceable(480) %m)
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %m.addr = alloca [120 x i32]*, align 8
|
||||
// CHECK-NEXT: store [120 x i32]* %m, [120 x i32]** %m.addr, align 8
|
||||
|
@ -277,10 +277,10 @@ void test_auto_t() {
|
|||
// CHECK-LABEL: define{{.*}} void @_Z11test_auto_tv()
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %m = alloca [130 x i32], align 4
|
||||
// CHECK-NEXT: call void @_Z3fooILm13EEvRu11matrix_typeIXT_EXLm10EEiE([130 x i32]* nonnull align 4 dereferenceable(520) %m)
|
||||
// CHECK-NEXT: call void @_Z3fooILm13EEvRu11matrix_typeIXT_ELm10EiE([130 x i32]* nonnull align 4 dereferenceable(520) %m)
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z3fooILm13EEvRu11matrix_typeIXT_EXLm10EEiE([130 x i32]* nonnull align 4 dereferenceable(520) %m)
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z3fooILm13EEvRu11matrix_typeIXT_ELm10EiE([130 x i32]* nonnull align 4 dereferenceable(520) %m)
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %m.addr = alloca [130 x i32]*, align 8
|
||||
// CHECK-NEXT: store [130 x i32]* %m, [130 x i32]** %m.addr, align 8
|
||||
|
@ -326,7 +326,7 @@ void test_use_matrix_2() {
|
|||
// CHECK-NEXT: store <40 x float> %call, <40 x float>* %0, align 4
|
||||
// CHECK-NEXT: call void @_Z12use_matrix_2ILm2ELm12EE8selectorILi0EERu11matrix_typeIXplT_Li2EEXdvT0_Li2EEiERu11matrix_typeIXT_EXT0_EfE([24 x i32]* nonnull align 4 dereferenceable(96) %m1, [24 x float]* nonnull align 4 dereferenceable(96) %m2)
|
||||
// CHECK-NEXT: call void @_Z12use_matrix_2ILm5ELm8EE8selectorILi1EERu11matrix_typeIXplT_T0_EXT0_EiERu11matrix_typeIXT_EXmiT0_T_EfE([104 x i32]* nonnull align 4 dereferenceable(416) %m3, [15 x float]* nonnull align 4 dereferenceable(60) %m4)
|
||||
// CHECK-NEXT: %call2 = call <20 x float> @_Z12use_matrix_2ILm5EEu11matrix_typeIXplT_T_EXmiT_Li3EEfERu11matrix_typeIXT_EXLm10EEiE([50 x i32]* nonnull align 4 dereferenceable(200) %m5)
|
||||
// CHECK-NEXT: %call2 = call <20 x float> @_Z12use_matrix_2ILm5EEu11matrix_typeIXplT_T_EXmiT_Li3EEfERu11matrix_typeIXT_ELm10EiE([50 x i32]* nonnull align 4 dereferenceable(200) %m5)
|
||||
// CHECK-NEXT: %1 = bitcast [20 x float]* %r4 to <20 x float>*
|
||||
// CHECK-NEXT: store <20 x float> %call2, <20 x float>* %1, align 4
|
||||
// CHECK-NEXT: call void @_Z12use_matrix_3ILm6EE8selectorILi2EERu11matrix_typeIXmiT_Li2EEXT_EiE([24 x i32]* nonnull align 4 dereferenceable(96) %m1)
|
||||
|
@ -357,7 +357,7 @@ void test_use_matrix_2() {
|
|||
// CHECK-NEXT: call void @llvm.trap()
|
||||
// CHECK-NEXT: unreachable
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr <20 x float> @_Z12use_matrix_2ILm5EEu11matrix_typeIXplT_T_EXmiT_Li3EEfERu11matrix_typeIXT_EXLm10EEiE([50 x i32]* nonnull align 4 dereferenceable(200) %m1)
|
||||
// CHECK-LABEL: define linkonce_odr <20 x float> @_Z12use_matrix_2ILm5EEu11matrix_typeIXplT_T_EXmiT_Li3EEfERu11matrix_typeIXT_ELm10EiE([50 x i32]* nonnull align 4 dereferenceable(200) %m1)
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: %m1.addr = alloca [50 x i32]*, align 8
|
||||
// CHECK-NEXT: store [50 x i32]* %m1, [50 x i32]** %m1.addr, align 8
|
||||
|
|
|
@ -60,14 +60,12 @@ int main(int argc, const char * argv[])
|
|||
// CHECK-V11: call void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofzsrT_6memberE(
|
||||
// CHECK-V12: call void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofXsrT_6memberEEE(
|
||||
// CHECK-V11: call void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofzL_ZN9HasMember6memberEEE(
|
||||
// CHECK-V12: call void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofXL_ZN9HasMember6memberEEEEE(
|
||||
// TODO: the above mangling is wrong -- the X/E shouldn't be emitted: ^ ^
|
||||
// CHECK-V12: call void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofL_ZN9HasMember6memberEEEE(
|
||||
// CHECK: define linkonce_odr void @_ZN8UUIDTestI10TestStructL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC1Ev
|
||||
// CHECK-V11: define linkonce_odr void @_Z15test_uuidofTypeI10TestStructEvDTu8__uuidoftT_E(
|
||||
// CHECK-V12: define linkonce_odr void @_Z15test_uuidofTypeI10TestStructEvDTu8__uuidofT_EE(
|
||||
// CHECK-V11: define linkonce_odr void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofzsrT_6memberE(
|
||||
// CHECK-V12: define linkonce_odr void @_Z15test_uuidofExprI9HasMemberEvDTu8__uuidofXsrT_6memberEEE(
|
||||
// CHECK-V11: define linkonce_odr void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofzL_ZN9HasMember6memberEEE(
|
||||
// CHECK-V12: define linkonce_odr void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofXL_ZN9HasMember6memberEEEEE(
|
||||
// TODO: the above mangling is wrong -- the X/E shouldn't be emitted: ^ ^
|
||||
// CHECK-V12: define linkonce_odr void @_Z16test_uuidofExpr2I10TestStructEvDTcmtlT_Eu8__uuidofL_ZN9HasMember6memberEEEE(
|
||||
// CHECK: define linkonce_odr void @_ZN8UUIDTestI10TestStructL_Z42_GUID_eafa1952_66f8_438b_8fba_af1bbae42191EEC2Ev
|
||||
|
|
Loading…
Reference in New Issue