1 //===--- VariantValue.cpp - Polymorphic value type -*- C++ -*-===/
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Polymorphic value type.
13 //===----------------------------------------------------------------------===//
15 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
17 #include "clang/Basic/LLVM.h"
18 #include "llvm/ADT/STLExtras.h"
21 namespace ast_matchers {
24 VariantMatcher::MatcherOps::~MatcherOps() {}
25 VariantMatcher::Payload::~Payload() {}
27 class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
29 SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
31 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
35 virtual std::string getTypeAsString() const {
36 return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
40 virtual void makeTypedMatcher(MatcherOps &Ops) const {
41 if (Ops.canConstructFrom(Matcher))
42 Ops.constructFrom(Matcher);
46 const DynTypedMatcher Matcher;
49 class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
51 PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
52 : Matchers(MatchersIn) {}
54 virtual ~PolymorphicPayload() {}
56 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
57 if (Matchers.size() != 1)
58 return llvm::Optional<DynTypedMatcher>();
62 virtual std::string getTypeAsString() const {
64 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
67 Inner += Matchers[i].getSupportedKind().asStringRef();
69 return (Twine("Matcher<") + Inner + ">").str();
72 virtual void makeTypedMatcher(MatcherOps &Ops) const {
73 const DynTypedMatcher *Found = NULL;
74 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
75 if (Ops.canConstructFrom(Matchers[i])) {
82 Ops.constructFrom(*Found);
85 const std::vector<DynTypedMatcher> Matchers;
88 class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
90 VariadicOpPayload(ast_matchers::internal::VariadicOperatorFunction Func,
91 ArrayRef<VariantMatcher> Args)
92 : Func(Func), Args(Args) {}
94 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
95 return llvm::Optional<DynTypedMatcher>();
98 virtual std::string getTypeAsString() const {
100 for (size_t i = 0, e = Args.size(); i != e; ++i) {
103 Inner += Args[i].getTypeAsString();
108 virtual void makeTypedMatcher(MatcherOps &Ops) const {
109 Ops.constructVariadicOperator(Func, Args);
113 const ast_matchers::internal::VariadicOperatorFunction Func;
114 const std::vector<VariantMatcher> Args;
117 VariantMatcher::VariantMatcher() {}
119 VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
120 return VariantMatcher(new SinglePayload(Matcher));
124 VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
125 return VariantMatcher(new PolymorphicPayload(Matchers));
128 VariantMatcher VariantMatcher::VariadicOperatorMatcher(
129 ast_matchers::internal::VariadicOperatorFunction Func,
130 ArrayRef<VariantMatcher> Args) {
131 return VariantMatcher(new VariadicOpPayload(Func, Args));
134 llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
135 return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
138 void VariantMatcher::reset() { Value.reset(); }
140 std::string VariantMatcher::getTypeAsString() const {
141 if (Value) return Value->getTypeAsString();
145 VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
149 VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
150 setUnsigned(Unsigned);
153 VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
157 VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
161 VariantValue::~VariantValue() { reset(); }
163 VariantValue &VariantValue::operator=(const VariantValue &Other) {
164 if (this == &Other) return *this;
166 switch (Other.Type) {
168 setUnsigned(Other.getUnsigned());
171 setString(Other.getString());
174 setMatcher(Other.getMatcher());
183 void VariantValue::reset() {
189 delete Value.Matcher;
191 // Cases that do nothing.
199 bool VariantValue::isUnsigned() const {
200 return Type == VT_Unsigned;
203 unsigned VariantValue::getUnsigned() const {
204 assert(isUnsigned());
205 return Value.Unsigned;
208 void VariantValue::setUnsigned(unsigned NewValue) {
211 Value.Unsigned = NewValue;
214 bool VariantValue::isString() const {
215 return Type == VT_String;
218 const std::string &VariantValue::getString() const {
220 return *Value.String;
223 void VariantValue::setString(const std::string &NewValue) {
226 Value.String = new std::string(NewValue);
229 bool VariantValue::isMatcher() const {
230 return Type == VT_Matcher;
233 const VariantMatcher &VariantValue::getMatcher() const {
235 return *Value.Matcher;
238 void VariantValue::setMatcher(const VariantMatcher &NewValue) {
241 Value.Matcher = new VariantMatcher(NewValue);
244 std::string VariantValue::getTypeAsString() const {
246 case VT_String: return "String";
247 case VT_Matcher: return getMatcher().getTypeAsString();
248 case VT_Unsigned: return "Unsigned";
249 case VT_Nothing: return "Nothing";
251 llvm_unreachable("Invalid Type");
254 } // end namespace dynamic
255 } // end namespace ast_matchers
256 } // end namespace clang