Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h
Line
Count
Source (jump to first uncovered line)
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
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"
17
18
using llvm::StringRef;
19
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;
36
  };
37
38
  const llvm::StringMap<bool> &CallerFeatureMap;
39
40
23.0k
  FeatureListStatus getAndFeatures(StringRef FeatureList) {
41
23.0k
    int InParentheses = 0;
42
23.0k
    bool HasFeatures = true;
43
23.0k
    size_t SubexpressionStart = 0;
44
266k
    for (size_t i = 0, e = FeatureList.size(); i < e; 
++i243k
) {
45
250k
      char CurrentToken = FeatureList[i];
46
250k
      switch (CurrentToken) {
47
223k
      default:
48
223k
        break;
49
223k
      case '(':
50
2.19k
        if (InParentheses == 0)
51
2.19k
          SubexpressionStart = i + 1;
52
2.19k
        ++InParentheses;
53
2.19k
        break;
54
2.19k
      case ')':
55
2.19k
        --InParentheses;
56
2.19k
        assert(InParentheses >= 0 && "Parentheses are not in pair");
57
2.19k
        LLVM_FALLTHROUGH;
58
22.4k
      case '|':
59
25.4k
      case ',':
60
25.4k
        if (InParentheses == 0) {
61
12.2k
          if (HasFeatures && 
i != SubexpressionStart11.5k
) {
62
10.7k
            StringRef F = FeatureList.slice(SubexpressionStart, i);
63
10.7k
            HasFeatures = CurrentToken == ')' ? 
hasRequiredFeatures(F)1.86k
64
10.7k
                                              : 
CallerFeatureMap.lookup(F)8.91k
;
65
10.7k
          }
66
12.2k
          SubexpressionStart = i + 1;
67
12.2k
          if (CurrentToken == '|') {
68
7.06k
            return {HasFeatures, FeatureList.substr(SubexpressionStart)};
69
7.06k
          }
70
12.2k
        }
71
18.4k
        break;
72
250k
      }
73
250k
    }
74
15.9k
    assert(InParentheses == 0 && "Parentheses are not in pair");
75
15.9k
    if (HasFeatures && 
SubexpressionStart != FeatureList.size()15.5k
)
76
14.8k
      HasFeatures =
77
14.8k
          CallerFeatureMap.lookup(FeatureList.substr(SubexpressionStart));
78
15.9k
    return {HasFeatures, StringRef()};
79
23.0k
  }
80
81
public:
82
17.5k
  bool hasRequiredFeatures(StringRef FeatureList) {
83
17.5k
    FeatureListStatus FS = {false, FeatureList};
84
40.6k
    while (!FS.HasFeatures && 
!FS.CurFeaturesList.empty()24.0k
)
85
23.0k
      FS = getAndFeatures(FS.CurFeaturesList);
86
17.5k
    return FS.HasFeatures;
87
17.5k
  }
88
89
  TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap)
90
15.7k
      : CallerFeatureMap(CallerFeatureMap) {}
91
};
92
93
} // namespace Builtin
94
} // namespace clang
95
#endif /* CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H */