blob: e4a02c522525518804cfc2eec487d6a21282fa5e [file] [log] [blame]
Manuel Klimek24db0f02013-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"
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000016#include "clang/Basic/LLVM.h"
Samuel Benzaquen0239b692013-08-13 14:54:51 +000017#include "llvm/ADT/STLExtras.h"
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000018
Manuel Klimek24db0f02013-05-14 09:13:00 +000019namespace clang {
20namespace ast_matchers {
21namespace dynamic {
22
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000023VariantMatcher::MatcherOps::~MatcherOps() {}
24VariantMatcher::Payload::~Payload() {}
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +000025
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000026class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
27public:
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000028 SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000029
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000030 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
31 return Matcher;
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000032 }
33
34 virtual std::string getTypeAsString() const {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000035 return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000036 .str();
37 }
38
Samuel Benzaquen4adca622013-08-28 18:42:04 +000039 virtual void makeTypedMatcher(MatcherOps &Ops) const {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000040 if (Ops.canConstructFrom(Matcher))
41 Ops.constructFrom(Matcher);
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000042 }
43
44private:
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000045 const DynTypedMatcher Matcher;
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000046};
47
48class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
49public:
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000050 PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
51 : Matchers(MatchersIn) {}
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000052
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000053 virtual ~PolymorphicPayload() {}
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000054
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000055 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000056 if (Matchers.size() != 1)
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000057 return llvm::Optional<DynTypedMatcher>();
58 return Matchers[0];
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000059 }
60
61 virtual std::string getTypeAsString() const {
62 std::string Inner;
63 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
64 if (i != 0)
65 Inner += "|";
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000066 Inner += Matchers[i].getSupportedKind().asStringRef();
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000067 }
68 return (Twine("Matcher<") + Inner + ">").str();
69 }
70
Samuel Benzaquen4adca622013-08-28 18:42:04 +000071 virtual void makeTypedMatcher(MatcherOps &Ops) const {
72 const DynTypedMatcher *Found = NULL;
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000073 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000074 if (Ops.canConstructFrom(Matchers[i])) {
Samuel Benzaquen4adca622013-08-28 18:42:04 +000075 if (Found)
76 return;
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000077 Found = &Matchers[i];
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +000078 }
79 }
Samuel Benzaquen4adca622013-08-28 18:42:04 +000080 if (Found)
81 Ops.constructFrom(*Found);
82 }
83
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000084 const std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquen4adca622013-08-28 18:42:04 +000085};
86
87class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
88public:
89 VariadicOpPayload(ast_matchers::internal::VariadicOperatorFunction Func,
90 ArrayRef<VariantMatcher> Args)
91 : Func(Func), Args(Args) {}
92
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000093 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
94 return llvm::Optional<DynTypedMatcher>();
Samuel Benzaquen4adca622013-08-28 18:42:04 +000095 }
96
97 virtual std::string getTypeAsString() const {
98 std::string Inner;
99 for (size_t i = 0, e = Args.size(); i != e; ++i) {
100 if (i != 0)
101 Inner += "&";
102 Inner += Args[i].getTypeAsString();
103 }
104 return Inner;
105 }
106
107 virtual void makeTypedMatcher(MatcherOps &Ops) const {
108 Ops.constructVariadicOperator(Func, Args);
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +0000109 }
110
111private:
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000112 const ast_matchers::internal::VariadicOperatorFunction Func;
113 const std::vector<VariantMatcher> Args;
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +0000114};
115
116VariantMatcher::VariantMatcher() {}
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000117
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000118VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +0000119 return VariantMatcher(new SinglePayload(Matcher));
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000120}
121
122VariantMatcher
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000123VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +0000124 return VariantMatcher(new PolymorphicPayload(Matchers));
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000125}
126
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000127VariantMatcher VariantMatcher::VariadicOperatorMatcher(
128 ast_matchers::internal::VariadicOperatorFunction Func,
129 ArrayRef<VariantMatcher> Args) {
130 return VariantMatcher(new VariadicOpPayload(Func, Args));
131}
132
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000133llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
134 return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000135}
136
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +0000137void VariantMatcher::reset() { Value.reset(); }
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000138
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000139std::string VariantMatcher::getTypeAsString() const {
Samuel Benzaquen8c9f6332013-08-22 16:38:33 +0000140 if (Value) return Value->getTypeAsString();
141 return "<Nothing>";
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000142}
143
Manuel Klimek24db0f02013-05-14 09:13:00 +0000144VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
145 *this = Other;
146}
147
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000148VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
149 setUnsigned(Unsigned);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000150}
151
152VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
153 setString(String);
154}
155
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000156VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
157 setMatcher(Matcher);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000158}
159
Manuel Klimek24db0f02013-05-14 09:13:00 +0000160VariantValue::~VariantValue() { reset(); }
161
162VariantValue &VariantValue::operator=(const VariantValue &Other) {
163 if (this == &Other) return *this;
164 reset();
165 switch (Other.Type) {
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000166 case VT_Unsigned:
167 setUnsigned(Other.getUnsigned());
168 break;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000169 case VT_String:
170 setString(Other.getString());
171 break;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000172 case VT_Matcher:
173 setMatcher(Other.getMatcher());
Manuel Klimek24db0f02013-05-14 09:13:00 +0000174 break;
175 case VT_Nothing:
176 Type = VT_Nothing;
177 break;
178 }
179 return *this;
180}
181
182void VariantValue::reset() {
183 switch (Type) {
184 case VT_String:
185 delete Value.String;
186 break;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000187 case VT_Matcher:
188 delete Value.Matcher;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000189 break;
190 // Cases that do nothing.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000191 case VT_Unsigned:
Manuel Klimek24db0f02013-05-14 09:13:00 +0000192 case VT_Nothing:
193 break;
194 }
195 Type = VT_Nothing;
196}
197
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000198bool VariantValue::isUnsigned() const {
199 return Type == VT_Unsigned;
200}
201
202unsigned VariantValue::getUnsigned() const {
203 assert(isUnsigned());
204 return Value.Unsigned;
205}
206
207void VariantValue::setUnsigned(unsigned NewValue) {
208 reset();
209 Type = VT_Unsigned;
210 Value.Unsigned = NewValue;
211}
212
Manuel Klimek24db0f02013-05-14 09:13:00 +0000213bool VariantValue::isString() const {
214 return Type == VT_String;
215}
216
217const std::string &VariantValue::getString() const {
218 assert(isString());
219 return *Value.String;
220}
221
222void VariantValue::setString(const std::string &NewValue) {
223 reset();
224 Type = VT_String;
225 Value.String = new std::string(NewValue);
226}
227
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000228bool VariantValue::isMatcher() const {
229 return Type == VT_Matcher;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000230}
231
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000232const VariantMatcher &VariantValue::getMatcher() const {
233 assert(isMatcher());
234 return *Value.Matcher;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000235}
236
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000237void VariantValue::setMatcher(const VariantMatcher &NewValue) {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000238 reset();
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000239 Type = VT_Matcher;
240 Value.Matcher = new VariantMatcher(NewValue);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000241}
242
Samuel Benzaquen81ef9292013-06-20 14:28:32 +0000243std::string VariantValue::getTypeAsString() const {
244 switch (Type) {
245 case VT_String: return "String";
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000246 case VT_Matcher: return getMatcher().getTypeAsString();
Samuel Benzaquen81ef9292013-06-20 14:28:32 +0000247 case VT_Unsigned: return "Unsigned";
248 case VT_Nothing: return "Nothing";
249 }
250 llvm_unreachable("Invalid Type");
251}
252
Manuel Klimek24db0f02013-05-14 09:13:00 +0000253} // end namespace dynamic
254} // end namespace ast_matchers
255} // end namespace clang