|
@@ -335,7 +335,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
|
|
|
case StaticDataMember:
|
|
|
// -- the initializers of nonspecialized static members of template classes
|
|
|
if (!IsInNonspecializedTemplate)
|
|
|
- return std::make_tuple(nullptr, nullptr);
|
|
|
+ return std::make_tuple(nullptr, ManglingContextDecl);
|
|
|
// Fall through to get the current context.
|
|
|
LLVM_FALLTHROUGH;
|
|
|
|
|
@@ -356,14 +356,15 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
|
|
|
llvm_unreachable("unexpected context");
|
|
|
}
|
|
|
|
|
|
-CXXMethodDecl *Sema::startLambdaDefinition(
|
|
|
- CXXRecordDecl *Class, SourceRange IntroducerRange,
|
|
|
- TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc,
|
|
|
- ArrayRef<ParmVarDecl *> Params, ConstexprSpecKind ConstexprKind,
|
|
|
- Optional<std::pair<unsigned, Decl *>> Mangling) {
|
|
|
+CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
|
|
|
+ SourceRange IntroducerRange,
|
|
|
+ TypeSourceInfo *MethodTypeInfo,
|
|
|
+ SourceLocation EndLoc,
|
|
|
+ ArrayRef<ParmVarDecl *> Params,
|
|
|
+ ConstexprSpecKind ConstexprKind) {
|
|
|
QualType MethodType = MethodTypeInfo->getType();
|
|
|
TemplateParameterList *TemplateParams =
|
|
|
- getGenericLambdaTemplateParameterList(getCurLambda(), *this);
|
|
|
+ getGenericLambdaTemplateParameterList(getCurLambda(), *this);
|
|
|
// If a lambda appears in a dependent context or is a generic lambda (has
|
|
|
// template parameters) and has an 'auto' return type, deduce it to a
|
|
|
// dependent type.
|
|
@@ -425,20 +426,55 @@ CXXMethodDecl *Sema::startLambdaDefinition(
|
|
|
P->setOwningFunction(Method);
|
|
|
}
|
|
|
|
|
|
+ return Method;
|
|
|
+}
|
|
|
+
|
|
|
+void Sema::handleLambdaNumbering(
|
|
|
+ CXXRecordDecl *Class, CXXMethodDecl *Method,
|
|
|
+ Optional<std::tuple<unsigned, bool, Decl *>> Mangling) {
|
|
|
if (Mangling) {
|
|
|
- Class->setLambdaMangling(Mangling->first, Mangling->second);
|
|
|
- } else {
|
|
|
- MangleNumberingContext *MCtx;
|
|
|
+ unsigned ManglingNumber;
|
|
|
+ bool HasKnownInternalLinkage;
|
|
|
Decl *ManglingContextDecl;
|
|
|
- std::tie(MCtx, ManglingContextDecl) =
|
|
|
- getCurrentMangleNumberContext(Class->getDeclContext());
|
|
|
- if (MCtx) {
|
|
|
- unsigned ManglingNumber = MCtx->getManglingNumber(Method);
|
|
|
- Class->setLambdaMangling(ManglingNumber, ManglingContextDecl);
|
|
|
- }
|
|
|
+ std::tie(ManglingNumber, HasKnownInternalLinkage, ManglingContextDecl) =
|
|
|
+ Mangling.getValue();
|
|
|
+ Class->setLambdaMangling(ManglingNumber, ManglingContextDecl,
|
|
|
+ HasKnownInternalLinkage);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- return Method;
|
|
|
+ auto getMangleNumberingContext =
|
|
|
+ [this](CXXRecordDecl *Class, Decl *ManglingContextDecl) -> MangleNumberingContext * {
|
|
|
+ // Get mangle numbering context if there's any extra decl context.
|
|
|
+ if (ManglingContextDecl)
|
|
|
+ return &Context.getManglingNumberContext(
|
|
|
+ ASTContext::NeedExtraManglingDecl, ManglingContextDecl);
|
|
|
+ // Otherwise, from that lambda's decl context.
|
|
|
+ auto DC = Class->getDeclContext();
|
|
|
+ while (auto *CD = dyn_cast<CapturedDecl>(DC))
|
|
|
+ DC = CD->getParent();
|
|
|
+ return &Context.getManglingNumberContext(DC);
|
|
|
+ };
|
|
|
+
|
|
|
+ MangleNumberingContext *MCtx;
|
|
|
+ Decl *ManglingContextDecl;
|
|
|
+ std::tie(MCtx, ManglingContextDecl) =
|
|
|
+ getCurrentMangleNumberContext(Class->getDeclContext());
|
|
|
+ bool HasKnownInternalLinkage = false;
|
|
|
+ if (!MCtx && getLangOpts().CUDA) {
|
|
|
+ // Force lambda numbering in CUDA/HIP as we need to name lambdas following
|
|
|
+ // ODR. Both device- and host-compilation need to have a consistent naming
|
|
|
+ // on kernel functions. As lambdas are potential part of these `__global__`
|
|
|
+ // function names, they needs numbering following ODR.
|
|
|
+ MCtx = getMangleNumberingContext(Class, ManglingContextDecl);
|
|
|
+ assert(MCtx && "Retrieving mangle numbering context failed!");
|
|
|
+ HasKnownInternalLinkage = true;
|
|
|
+ }
|
|
|
+ if (MCtx) {
|
|
|
+ unsigned ManglingNumber = MCtx->getManglingNumber(Method);
|
|
|
+ Class->setLambdaMangling(ManglingNumber, ManglingContextDecl,
|
|
|
+ HasKnownInternalLinkage);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void Sema::buildLambdaScope(LambdaScopeInfo *LSI,
|
|
@@ -951,6 +987,9 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|
|
if (getLangOpts().CUDA)
|
|
|
CUDASetLambdaAttrs(Method);
|
|
|
|
|
|
+ // Number the lambda for linkage purposes if necessary.
|
|
|
+ handleLambdaNumbering(Class, Method);
|
|
|
+
|
|
|
// Introduce the function call operator as the current declaration context.
|
|
|
PushDeclContext(CurScope, Method);
|
|
|
|