blob: 3e49e1b8ef03b8c63fc9c56554a3db2a34764e74 [file] [log] [blame]
Manuel Klimekf7f295f2013-05-14 09:13:00 +00001//===--- VariantValue.cpp - Polymorphic value type -*- C++ -*-===/
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Polymorphic value type.
12///
13//===----------------------------------------------------------------------===//
14
15#include "clang/ASTMatchers/Dynamic/VariantValue.h"
16
Samuel Benzaquen76c2f922013-06-20 14:28:32 +000017#include "clang/Basic/LLVM.h"
Samuel Benzaquen9d028072013-08-13 14:54:51 +000018#include "llvm/ADT/STLExtras.h"
Samuel Benzaquen76c2f922013-06-20 14:28:32 +000019
Manuel Klimekf7f295f2013-05-14 09:13:00 +000020namespace clang {
21namespace ast_matchers {
22namespace dynamic {
23
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000024VariantMatcher::MatcherOps::~MatcherOps() {}
25VariantMatcher::Payload::~Payload() {}
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000026
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000027class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
28public:
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000029 SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000030
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000031 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
32 return Matcher;
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000033 }
34
35 virtual std::string getTypeAsString() const {
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000036 return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000037 .str();
38 }
39
Samuel Benzaquena7350902013-08-28 18:42:04 +000040 virtual void makeTypedMatcher(MatcherOps &Ops) const {
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000041 if (Ops.canConstructFrom(Matcher))
42 Ops.constructFrom(Matcher);
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000043 }
44
45private:
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000046 const DynTypedMatcher Matcher;
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000047};
48
49class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
50public:
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000051 PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
52 : Matchers(MatchersIn) {}
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000053
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000054 virtual ~PolymorphicPayload() {}
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000055
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000056 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000057 if (Matchers.size() != 1)
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000058 return llvm::Optional<DynTypedMatcher>();
59 return Matchers[0];
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000060 }
61
62 virtual std::string getTypeAsString() const {
63 std::string Inner;
64 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
65 if (i != 0)
66 Inner += "|";
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000067 Inner += Matchers[i].getSupportedKind().asStringRef();
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000068 }
69 return (Twine("Matcher<") + Inner + ">").str();
70 }
71
Samuel Benzaquena7350902013-08-28 18:42:04 +000072 virtual void makeTypedMatcher(MatcherOps &Ops) const {
73 const DynTypedMatcher *Found = NULL;
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000074 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000075 if (Ops.canConstructFrom(Matchers[i])) {
Samuel Benzaquena7350902013-08-28 18:42:04 +000076 if (Found)
77 return;
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000078 Found = &Matchers[i];
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +000079 }
80 }
Samuel Benzaquena7350902013-08-28 18:42:04 +000081 if (Found)
82 Ops.constructFrom(*Found);
83 }
84
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000085 const std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquena7350902013-08-28 18:42:04 +000086};
87
88class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
89public:
90 VariadicOpPayload(ast_matchers::internal::VariadicOperatorFunction Func,
91 ArrayRef<VariantMatcher> Args)
92 : Func(Func), Args(Args) {}
93
Samuel Benzaquenb7488d72013-10-29 14:37:15 +000094 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
95 return llvm::Optional<DynTypedMatcher>();
Samuel Benzaquena7350902013-08-28 18:42:04 +000096 }
97
98 virtual std::string getTypeAsString() const {
99 std::string Inner;
100 for (size_t i = 0, e = Args.size(); i != e; ++i) {
101 if (i != 0)
102 Inner += "&";
103 Inner += Args[i].getTypeAsString();
104 }
105 return Inner;
106 }
107
108 virtual void makeTypedMatcher(MatcherOps &Ops) const {
109 Ops.constructVariadicOperator(Func, Args);
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +0000110 }
111
112private:
Samuel Benzaquena7350902013-08-28 18:42:04 +0000113 const ast_matchers::internal::VariadicOperatorFunction Func;
114 const std::vector<VariantMatcher> Args;
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +0000115};
116
117VariantMatcher::VariantMatcher() {}
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000118
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000119VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +0000120 return VariantMatcher(new SinglePayload(Matcher));
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000121}
122
123VariantMatcher
Samuel Benzaquenb7488d72013-10-29 14:37:15 +0000124VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +0000125 return VariantMatcher(new PolymorphicPayload(Matchers));
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000126}
127
Samuel Benzaquena7350902013-08-28 18:42:04 +0000128VariantMatcher VariantMatcher::VariadicOperatorMatcher(
129 ast_matchers::internal::VariadicOperatorFunction Func,
130 ArrayRef<VariantMatcher> Args) {
131 return VariantMatcher(new VariadicOpPayload(Func, Args));
132}
133
Samuel Benzaquenb7488d72013-10-29 14:37:15 +0000134llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
135 return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000136}
137
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +0000138void VariantMatcher::reset() { Value.reset(); }
Samuel Benzaquenef7eb022013-06-21 15:51:31 +0000139
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000140std::string VariantMatcher::getTypeAsString() const {
Samuel Benzaquen544ae5b2013-08-22 16:38:33 +0000141 if (Value) return Value->getTypeAsString();
142 return "<Nothing>";
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000143}
144
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000145VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
146 *this = Other;
147}
148
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000149VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
150 setUnsigned(Unsigned);
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000151}
152
153VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
154 setString(String);
155}
156
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000157VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
158 setMatcher(Matcher);
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000159}
160
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000161VariantValue::~VariantValue() { reset(); }
162
163VariantValue &VariantValue::operator=(const VariantValue &Other) {
164 if (this == &Other) return *this;
165 reset();
166 switch (Other.Type) {
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000167 case VT_Unsigned:
168 setUnsigned(Other.getUnsigned());
169 break;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000170 case VT_String:
171 setString(Other.getString());
172 break;
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000173 case VT_Matcher:
174 setMatcher(Other.getMatcher());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000175 break;
176 case VT_Nothing:
177 Type = VT_Nothing;
178 break;
179 }
180 return *this;
181}
182
183void VariantValue::reset() {
184 switch (Type) {
185 case VT_String:
186 delete Value.String;
187 break;
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000188 case VT_Matcher:
189 delete Value.Matcher;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000190 break;
191 // Cases that do nothing.
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000192 case VT_Unsigned:
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000193 case VT_Nothing:
194 break;
195 }
196 Type = VT_Nothing;
197}
198
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000199bool VariantValue::isUnsigned() const {
200 return Type == VT_Unsigned;
201}
202
203unsigned VariantValue::getUnsigned() const {
204 assert(isUnsigned());
205 return Value.Unsigned;
206}
207
208void VariantValue::setUnsigned(unsigned NewValue) {
209 reset();
210 Type = VT_Unsigned;
211 Value.Unsigned = NewValue;
212}
213
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000214bool VariantValue::isString() const {
215 return Type == VT_String;
216}
217
218const std::string &VariantValue::getString() const {
219 assert(isString());
220 return *Value.String;
221}
222
223void VariantValue::setString(const std::string &NewValue) {
224 reset();
225 Type = VT_String;
226 Value.String = new std::string(NewValue);
227}
228
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000229bool VariantValue::isMatcher() const {
230 return Type == VT_Matcher;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000231}
232
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000233const VariantMatcher &VariantValue::getMatcher() const {
234 assert(isMatcher());
235 return *Value.Matcher;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000236}
237
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000238void VariantValue::setMatcher(const VariantMatcher &NewValue) {
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000239 reset();
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000240 Type = VT_Matcher;
241 Value.Matcher = new VariantMatcher(NewValue);
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000242}
243
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000244std::string VariantValue::getTypeAsString() const {
245 switch (Type) {
246 case VT_String: return "String";
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000247 case VT_Matcher: return getMatcher().getTypeAsString();
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000248 case VT_Unsigned: return "Unsigned";
249 case VT_Nothing: return "Nothing";
250 }
251 llvm_unreachable("Invalid Type");
252}
253
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000254} // end namespace dynamic
255} // end namespace ast_matchers
256} // end namespace clang