1 //===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file provides some common utility functions for processing 11 /// Lambda related AST Constructs. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_AST_ASTLAMBDA_H 16 #define LLVM_CLANG_AST_ASTLAMBDA_H 17 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/DeclTemplate.h" 20 21 namespace clang { 22 inline StringRef getLambdaStaticInvokerName() { 23 return "__invoke"; 24 } 25 // This function returns true if M is a specialization, a template, 26 // or a non-generic lambda call operator. 27 inline bool isLambdaCallOperator(const CXXMethodDecl *MD) { 28 const CXXRecordDecl *LambdaClass = MD->getParent(); 29 if (!LambdaClass || !LambdaClass->isLambda()) return false; 30 return MD->getOverloadedOperator() == OO_Call; 31 } 32 33 inline bool isLambdaCallOperator(const DeclContext *DC) { 34 if (!DC || !isa<CXXMethodDecl>(DC)) return false; 35 return isLambdaCallOperator(cast<CXXMethodDecl>(DC)); 36 } 37 38 inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) { 39 if (!MD) return false; 40 const CXXRecordDecl *LambdaClass = MD->getParent(); 41 if (LambdaClass && LambdaClass->isGenericLambda()) 42 return isLambdaCallOperator(MD) && 43 MD->isFunctionTemplateSpecialization(); 44 return false; 45 } 46 47 inline bool isLambdaConversionOperator(CXXConversionDecl *C) { 48 return C ? C->getParent()->isLambda() : false; 49 } 50 51 inline bool isLambdaConversionOperator(Decl *D) { 52 if (!D) return false; 53 if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) 54 return isLambdaConversionOperator(Conv); 55 if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D)) 56 if (CXXConversionDecl *Conv = 57 dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl())) 58 return isLambdaConversionOperator(Conv); 59 return false; 60 } 61 62 inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) { 63 return isGenericLambdaCallOperatorSpecialization( 64 dyn_cast<CXXMethodDecl>(DC)); 65 } 66 67 inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization( 68 const DeclContext *DC) { 69 const auto *MD = dyn_cast<CXXMethodDecl>(DC); 70 if (!MD) return false; 71 const CXXRecordDecl *LambdaClass = MD->getParent(); 72 if (LambdaClass && LambdaClass->isGenericLambda()) 73 return (isLambdaCallOperator(MD) || MD->isLambdaStaticInvoker()) && 74 MD->isFunctionTemplateSpecialization(); 75 return false; 76 } 77 78 // This returns the parent DeclContext ensuring that the correct 79 // parent DeclContext is returned for Lambdas 80 inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) { 81 if (isLambdaCallOperator(DC)) 82 return DC->getParent()->getParent(); 83 else 84 return DC->getParent(); 85 } 86 87 } // clang 88 89 #endif 90