Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:28

0001 //===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file provides some common utility functions for processing
0011 /// Lambda related AST Constructs.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CLANG_AST_ASTLAMBDA_H
0016 #define LLVM_CLANG_AST_ASTLAMBDA_H
0017 
0018 #include "clang/AST/DeclCXX.h"
0019 #include "clang/AST/DeclTemplate.h"
0020 #include "llvm/Support/Casting.h"
0021 
0022 namespace clang {
0023 inline StringRef getLambdaStaticInvokerName() {
0024   return "__invoke";
0025 }
0026 // This function returns true if M is a specialization, a template,
0027 // or a non-generic lambda call operator.
0028 inline bool isLambdaCallOperator(const CXXMethodDecl *MD) {
0029   const CXXRecordDecl *LambdaClass = MD->getParent();
0030   if (!LambdaClass || !LambdaClass->isLambda()) return false;
0031   return MD->getOverloadedOperator() == OO_Call;
0032 }
0033 
0034 inline bool isLambdaCallOperator(const DeclContext *DC) {
0035   if (!DC || !isa<CXXMethodDecl>(DC)) return false;
0036   return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
0037 }
0038 
0039 inline bool isLambdaMethod(const DeclContext *DC) {
0040   if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(DC))
0041     return MD->getParent()->isLambda();
0042   return false;
0043 }
0044 
0045 inline bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC) {
0046   return isLambdaCallOperator(DC) &&
0047          cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
0048 }
0049 
0050 inline bool isLambdaCallWithImplicitObjectParameter(const DeclContext *DC) {
0051   return isLambdaCallOperator(DC) &&
0052          // FIXME: Checking for a null type is not great
0053          // but lambdas with invalid captures or whose closure parameter list
0054          // have not fully been parsed may have a call operator whose type is
0055          // null.
0056          !cast<CXXMethodDecl>(DC)->getType().isNull() &&
0057          !cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
0058 }
0059 
0060 inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
0061   if (!MD) return false;
0062   const CXXRecordDecl *LambdaClass = MD->getParent();
0063   if (LambdaClass && LambdaClass->isGenericLambda())
0064     return isLambdaCallOperator(MD) &&
0065                     MD->isFunctionTemplateSpecialization();
0066   return false;
0067 }
0068 
0069 inline bool isLambdaConversionOperator(CXXConversionDecl *C) {
0070   return C ? C->getParent()->isLambda() : false;
0071 }
0072 
0073 inline bool isLambdaConversionOperator(Decl *D) {
0074   if (!D) return false;
0075   if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D))
0076     return isLambdaConversionOperator(Conv);
0077   if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D))
0078     if (CXXConversionDecl *Conv =
0079         dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl()))
0080       return isLambdaConversionOperator(Conv);
0081   return false;
0082 }
0083 
0084 inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
0085   return isGenericLambdaCallOperatorSpecialization(
0086                                           dyn_cast<CXXMethodDecl>(DC));
0087 }
0088 
0089 inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(
0090     const DeclContext *DC) {
0091   const auto *MD = dyn_cast<CXXMethodDecl>(DC);
0092   if (!MD) return false;
0093   const CXXRecordDecl *LambdaClass = MD->getParent();
0094   if (LambdaClass && LambdaClass->isGenericLambda())
0095     return (isLambdaCallOperator(MD) || MD->isLambdaStaticInvoker()) &&
0096                     MD->isFunctionTemplateSpecialization();
0097   return false;
0098 }
0099 
0100 // This returns the parent DeclContext ensuring that the correct
0101 // parent DeclContext is returned for Lambdas
0102 inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
0103   if (isLambdaCallOperator(DC))
0104     return DC->getParent()->getParent();
0105   else
0106     return DC->getParent();
0107 }
0108 
0109 } // clang
0110 
0111 #endif