[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 5 03:31:38 PST 2024


================
@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
     if (const Decl *LCD = Rec->getLambdaContextDecl())
       return Response::ChangeDecl(LCD);
+    // Attempt to retrieve the template arguments for a using alias declaration.
+    // This is necessary for constraint checking, since we always keep
+    // constraints relative to the primary template.
+    if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+      for (auto &CSC : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+        if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+                            TypeAliasTemplateInstantiation)
+          continue;
+        auto *TATD = cast<TypeAliasTemplateDecl>(CSC.Entity),
+             *CurrentTATD = TATD;
+        FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+        // Retrieve the 'primary' template for a lambda call operator. It's
+        // unfortunate that we only have the mappings of call operators rather
+        // than lambda classes.
+        while (true) {
+          auto *FTD = dyn_cast_if_present<FunctionTemplateDecl>(
+              LambdaCallOperator->getDescribedTemplate());
+          if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+            LambdaCallOperator =
+                FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+          } else if (auto *Prev = cast<CXXMethodDecl>(LambdaCallOperator)
+                                      ->getInstantiatedFromMemberFunction())
+            LambdaCallOperator = Prev;
+          else
+            break;
+        }
----------------
cor3ntin wrote:

```suggestion
          if (auto *FTD = dyn_cast_if_present<FunctionTemplateDecl>(
              LambdaCallOperator->getDescribedTemplate(); FTD && FTD->getInstantiatedFromMemberTemplate()) {
            LambdaCallOperator =
                FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
          } else if (auto *Prev = cast<CXXMethodDecl>(LambdaCallOperator)
                                      ->getInstantiatedFromMemberFunction())
            LambdaCallOperator = Prev;
          else
            break;
        }
```

https://github.com/llvm/llvm-project/pull/82310


More information about the cfe-commits mailing list