Coverage Report

Created: 2021-01-23 06:44

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- Marshallers.cpp ----------------------------------------*- 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
#include "Marshallers.h"
10
#include "llvm/ADT/ArrayRef.h"
11
#include "llvm/ADT/Optional.h"
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/Support/Regex.h"
14
#include <string>
15
16
static llvm::Optional<std::string>
17
getBestGuess(llvm::StringRef Search, llvm::ArrayRef<llvm::StringRef> Allowed,
18
3
             llvm::StringRef DropPrefix = "", unsigned MaxEditDistance = 3) {
19
3
  if (MaxEditDistance != ~0U)
20
3
    ++MaxEditDistance;
21
3
  llvm::StringRef Res;
22
993
  for (const llvm::StringRef &Item : Allowed) {
23
993
    if (Item.equals_lower(Search)) {
24
0
      assert(!Item.equals(Search) && "This should be handled earlier on.");
25
0
      MaxEditDistance = 1;
26
0
      Res = Item;
27
0
      continue;
28
0
    }
29
993
    unsigned Distance = Item.edit_distance(Search);
30
993
    if (Distance < MaxEditDistance) {
31
1
      MaxEditDistance = Distance;
32
1
      Res = Item;
33
1
    }
34
993
  }
35
3
  if (!Res.empty())
36
1
    return Res.str();
37
2
  if (!DropPrefix.empty()) {
38
2
    --MaxEditDistance; // Treat dropping the prefix as 1 edit
39
476
    for (const llvm::StringRef &Item : Allowed) {
40
476
      auto NoPrefix = Item;
41
476
      if (!NoPrefix.consume_front(DropPrefix))
42
0
        continue;
43
476
      if (NoPrefix.equals_lower(Search)) {
44
1
        if (NoPrefix.equals(Search))
45
1
          return Item.str();
46
0
        MaxEditDistance = 1;
47
0
        Res = Item;
48
0
        continue;
49
0
      }
50
475
      unsigned Distance = NoPrefix.edit_distance(Search);
51
475
      if (Distance < MaxEditDistance) {
52
0
        MaxEditDistance = Distance;
53
0
        Res = Item;
54
0
      }
55
475
    }
56
1
    if (!Res.empty())
57
0
      return Res.str();
58
1
  }
59
1
  return llvm::None;
60
1
}
61
62
llvm::Optional<std::string>
63
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
64
3
    clang::attr::Kind>::getBestGuess(const VariantValue &Value) {
65
3
  static constexpr llvm::StringRef Allowed[] = {
66
993
#define ATTR(X) "attr::" #X,
67
3
#include "clang/Basic/AttrList.inc"
68
3
  };
69
3
  if (Value.isString())
70
3
    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
71
3
                          "attr::");
72
0
  return llvm::None;
73
0
}
74
75
llvm::Optional<std::string>
76
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
77
0
    clang::CastKind>::getBestGuess(const VariantValue &Value) {
78
0
  static constexpr llvm::StringRef Allowed[] = {
79
0
#define CAST_OPERATION(Name) "CK_" #Name,
80
0
#include "clang/AST/OperationKinds.def"
81
0
  };
82
0
  if (Value.isString())
83
0
    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
84
0
                          "CK_");
85
0
  return llvm::None;
86
0
}
87
88
llvm::Optional<std::string>
89
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
90
0
    clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) {
91
0
  static constexpr llvm::StringRef Allowed[] = {
92
0
#define GEN_CLANG_CLAUSE_CLASS
93
0
#define CLAUSE_CLASS(Enum, Str, Class) #Enum,
94
0
#include "llvm/Frontend/OpenMP/OMP.inc"
95
0
  };
96
0
  if (Value.isString())
97
0
    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
98
0
                          "OMPC_");
99
0
  return llvm::None;
100
0
}
101
102
llvm::Optional<std::string>
103
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
104
0
    clang::UnaryExprOrTypeTrait>::getBestGuess(const VariantValue &Value) {
105
0
  static constexpr llvm::StringRef Allowed[] = {
106
0
#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name,
107
0
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name,
108
0
#include "clang/Basic/TokenKinds.def"
109
0
  };
110
0
  if (Value.isString())
111
0
    return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
112
0
                          "UETT_");
113
0
  return llvm::None;
114
0
}
115
116
static constexpr std::pair<llvm::StringRef, llvm::Regex::RegexFlags>
117
    RegexMap[] = {
118
        {"NoFlags", llvm::Regex::RegexFlags::NoFlags},
119
        {"IgnoreCase", llvm::Regex::RegexFlags::IgnoreCase},
120
        {"Newline", llvm::Regex::RegexFlags::Newline},
121
        {"BasicRegex", llvm::Regex::RegexFlags::BasicRegex},
122
};
123
124
static llvm::Optional<llvm::Regex::RegexFlags>
125
8
getRegexFlag(llvm::StringRef Flag) {
126
26
  for (const auto &StringFlag : RegexMap) {
127
26
    if (Flag == StringFlag.first)
128
5
      return StringFlag.second;
129
26
  }
130
3
  return llvm::None;
131
8
}
132
133
static llvm::Optional<llvm::StringRef>
134
4
getCloseRegexMatch(llvm::StringRef Flag) {
135
12
  for (const auto &StringFlag : RegexMap) {
136
12
    if (Flag.edit_distance(StringFlag.first) < 3)
137
3
      return StringFlag.first;
138
12
  }
139
1
  return llvm::None;
140
4
}
141
142
llvm::Optional<llvm::Regex::RegexFlags>
143
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
144
5
    llvm::Regex::RegexFlags>::getFlags(llvm::StringRef Flags) {
145
5
  llvm::Optional<llvm::Regex::RegexFlags> Flag;
146
5
  SmallVector<StringRef, 4> Split;
147
5
  Flags.split(Split, '|', -1, false);
148
8
  for (StringRef OrFlag : Split) {
149
8
    if (llvm::Optional<llvm::Regex::RegexFlags> NextFlag =
150
5
            getRegexFlag(OrFlag.trim()))
151
5
      Flag = Flag.getValueOr(llvm::Regex::NoFlags) | *NextFlag;
152
3
    else
153
3
      return None;
154
8
  }
155
2
  return Flag;
156
5
}
157
158
llvm::Optional<std::string>
159
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
160
3
    llvm::Regex::RegexFlags>::getBestGuess(const VariantValue &Value) {
161
3
  if (!Value.isString())
162
0
    return llvm::None;
163
3
  SmallVector<StringRef, 4> Split;
164
3
  llvm::StringRef(Value.getString()).split(Split, '|', -1, false);
165
4
  for (llvm::StringRef &Flag : Split) {
166
4
    if (llvm::Optional<llvm::StringRef> BestGuess =
167
3
            getCloseRegexMatch(Flag.trim()))
168
3
      Flag = *BestGuess;
169
1
    else
170
1
      return None;
171
4
  }
172
2
  if (Split.empty())
173
0
    return None;
174
2
  return llvm::join(Split, " | ");
175
2
}