ASTLambda.h 3.2 KB

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