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