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 21namespace clang { 22inline 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. 27inline 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 33inline bool isLambdaCallOperator(const DeclContext *DC) { 34 if (!DC || !isa<CXXMethodDecl>(DC)) return false; 35 return isLambdaCallOperator(cast<CXXMethodDecl>(DC)); 36} 37 38inline 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 47inline bool isLambdaConversionOperator(CXXConversionDecl *C) { 48 return C ? C->getParent()->isLambda() : false; 49} 50 51inline 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 62inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) { 63 return isGenericLambdaCallOperatorSpecialization( 64 dyn_cast<CXXMethodDecl>(DC)); 65} 66 67inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization( 68 DeclContext *DC) { 69 CXXMethodDecl *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 79// This returns the parent DeclContext ensuring that the correct 80// parent DeclContext is returned for Lambdas 81inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) { 82 if (isLambdaCallOperator(DC)) 83 return DC->getParent()->getParent(); 84 else 85 return DC->getParent(); 86} 87 88} // clang 89 90#endif 91