BuiltinTargetFeatures.h 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. //===-- CodeGenFunction.h - Target features for builtin ---------*- 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. // This is the internal required target features for builtin.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H
  13. #define LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H
  14. #include "llvm/ADT/StringMap.h"
  15. #include "llvm/ADT/StringRef.h"
  16. using llvm::StringRef;
  17. namespace clang {
  18. namespace Builtin {
  19. /// TargetFeatures - This class is used to check whether the builtin function
  20. /// has the required tagert specific features. It is able to support the
  21. /// combination of ','(and), '|'(or), and '()'. By default, the priority of
  22. /// ',' is higher than that of '|' .
  23. /// E.g:
  24. /// A,B|C means the builtin function requires both A and B, or C.
  25. /// If we want the builtin function requires both A and B, or both A and C,
  26. /// there are two ways: A,B|A,C or A,(B|C).
  27. /// The FeaturesList should not contain spaces, and brackets must appear in
  28. /// pairs.
  29. class TargetFeatures {
  30. struct FeatureListStatus {
  31. bool HasFeatures;
  32. StringRef CurFeaturesList;
  33. };
  34. const llvm::StringMap<bool> &CallerFeatureMap;
  35. FeatureListStatus getAndFeatures(StringRef FeatureList) {
  36. int InParentheses = 0;
  37. bool HasFeatures = true;
  38. size_t SubexpressionStart = 0;
  39. for (size_t i = 0, e = FeatureList.size(); i < e; ++i) {
  40. char CurrentToken = FeatureList[i];
  41. switch (CurrentToken) {
  42. default:
  43. break;
  44. case '(':
  45. if (InParentheses == 0)
  46. SubexpressionStart = i + 1;
  47. ++InParentheses;
  48. break;
  49. case ')':
  50. --InParentheses;
  51. assert(InParentheses >= 0 && "Parentheses are not in pair");
  52. [[fallthrough]];
  53. case '|':
  54. case ',':
  55. if (InParentheses == 0) {
  56. if (HasFeatures && i != SubexpressionStart) {
  57. StringRef F = FeatureList.slice(SubexpressionStart, i);
  58. HasFeatures = CurrentToken == ')' ? hasRequiredFeatures(F)
  59. : CallerFeatureMap.lookup(F);
  60. }
  61. SubexpressionStart = i + 1;
  62. if (CurrentToken == '|') {
  63. return {HasFeatures, FeatureList.substr(SubexpressionStart)};
  64. }
  65. }
  66. break;
  67. }
  68. }
  69. assert(InParentheses == 0 && "Parentheses are not in pair");
  70. if (HasFeatures && SubexpressionStart != FeatureList.size())
  71. HasFeatures =
  72. CallerFeatureMap.lookup(FeatureList.substr(SubexpressionStart));
  73. return {HasFeatures, StringRef()};
  74. }
  75. public:
  76. bool hasRequiredFeatures(StringRef FeatureList) {
  77. FeatureListStatus FS = {false, FeatureList};
  78. while (!FS.HasFeatures && !FS.CurFeaturesList.empty())
  79. FS = getAndFeatures(FS.CurFeaturesList);
  80. return FS.HasFeatures;
  81. }
  82. TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap)
  83. : CallerFeatureMap(CallerFeatureMap) {}
  84. };
  85. } // namespace Builtin
  86. } // namespace clang
  87. #endif /* CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H */