brintos

brintos / llvm-project-archived public Read only

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