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 <string>
14 
15 static llvm::Optional<std::string>
16 getBestGuess(llvm::StringRef Search, llvm::ArrayRef<llvm::StringRef> Allowed,
17              llvm::StringRef DropPrefix = "", unsigned MaxEditDistance = 3) {
18   if (MaxEditDistance != ~0U)
19     ++MaxEditDistance;
20   llvm::StringRef Res;
21   for (const llvm::StringRef &Item : Allowed) {
22     if (Item.equals_lower(Search)) {
23       assert(!Item.equals(Search) && "This should be handled earlier on.");
24       MaxEditDistance = 1;
25       Res = Item;
26       continue;
27     }
28     unsigned Distance = Item.edit_distance(Search);
29     if (Distance < MaxEditDistance) {
30       MaxEditDistance = Distance;
31       Res = Item;
32     }
33   }
34   if (!Res.empty())
35     return Res.str();
36   if (!DropPrefix.empty()) {
37     --MaxEditDistance; // Treat dropping the prefix as 1 edit
38     for (const llvm::StringRef &Item : Allowed) {
39       auto NoPrefix = Item;
40       if (!NoPrefix.consume_front(DropPrefix))
41         continue;
42       if (NoPrefix.equals_lower(Search)) {
43         if (NoPrefix.equals(Search))
44           return Item.str();
45         MaxEditDistance = 1;
46         Res = Item;
47         continue;
48       }
49       unsigned Distance = NoPrefix.edit_distance(Search);
50       if (Distance < MaxEditDistance) {
51         MaxEditDistance = Distance;
52         Res = Item;
53       }
54     }
55     if (!Res.empty())
56       return Res.str();
57   }
58   return llvm::None;
59 }
60 
61 llvm::Optional<std::string>
62 clang::ast_matchers::dynamic::internal::ArgTypeTraits<
63     clang::attr::Kind>::getBestGuess(const VariantValue &Value) {
64   static constexpr llvm::StringRef Allowed[] = {
65 #define ATTR(X) "attr::" #X,
66 #include "clang/Basic/AttrList.inc"
67   };
68   if (Value.isString())
69     return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
70                           "attr::");
71   return llvm::None;
72 }
73 
74 llvm::Optional<std::string>
75 clang::ast_matchers::dynamic::internal::ArgTypeTraits<
76     clang::CastKind>::getBestGuess(const VariantValue &Value) {
77   static constexpr llvm::StringRef Allowed[] = {
78 #define CAST_OPERATION(Name) "CK_" #Name,
79 #include "clang/AST/OperationKinds.def"
80   };
81   if (Value.isString())
82     return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
83                           "CK_");
84   return llvm::None;
85 }
86 
87 llvm::Optional<std::string>
88 clang::ast_matchers::dynamic::internal::ArgTypeTraits<
89     clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) {
90   static constexpr llvm::StringRef Allowed[] = {
91 #define OMP_CLAUSE_CLASS(Enum, Str, Class) #Enum,
92 #include "llvm/Frontend/OpenMP/OMPKinds.def"
93   };
94   if (Value.isString())
95     return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
96                           "OMPC_");
97   return llvm::None;
98 }
99 
100 llvm::Optional<std::string>
101 clang::ast_matchers::dynamic::internal::ArgTypeTraits<
102     clang::UnaryExprOrTypeTrait>::getBestGuess(const VariantValue &Value) {
103   static constexpr llvm::StringRef Allowed[] = {
104       "UETT_SizeOf",           "UETT_AlignOf",
105       "UETT_VecStep",          "UETT_OpenMPRequiredSimdAlign",
106       "UETT_PreferredAlignOf",
107   };
108   if (Value.isString())
109     return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
110                           "UETT_");
111   return llvm::None;
112 }
113