Rename GetLanguageInfo to GetLanguageSpecificData (#117012)
[llvm-project.git] / clang / lib / Basic / BuiltinTargetFeatures.h
blob9754acda2a68fe0cbd6a6df9ac07defd6b1872fa
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.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H
14 #define LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/ADT/StringRef.h"
18 using llvm::StringRef;
20 namespace clang {
21 namespace Builtin {
22 /// TargetFeatures - This class is used to check whether the builtin function
23 /// has the required tagert specific features. It is able to support the
24 /// combination of ','(and), '|'(or), and '()'. By default, the priority of
25 /// ',' 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 in
31 /// pairs.
32 class TargetFeatures {
33 struct FeatureListStatus {
34 bool HasFeatures;
35 StringRef CurFeaturesList;
38 const llvm::StringMap<bool> &CallerFeatureMap;
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);
66 SubexpressionStart = i + 1;
67 if (CurrentToken == '|') {
68 return {HasFeatures, FeatureList.substr(SubexpressionStart)};
71 break;
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()};
81 public:
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;
89 TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap)
90 : CallerFeatureMap(CallerFeatureMap) {}
93 } // namespace Builtin
94 } // namespace clang
95 #endif /* CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H */