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