blob: a8fd7c6bbb9c6d2add5d68357381083d22467c95 [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 Benzaquen9d028072013-08-13 14:54:51 +000024VariantMatcher::VariantMatcher() : List() {}
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000025
Samuel Benzaquen9d028072013-08-13 14:54:51 +000026VariantMatcher::VariantMatcher(const VariantMatcher& Other) {
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000027 *this = Other;
28}
29
Samuel Benzaquen9d028072013-08-13 14:54:51 +000030VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
31 VariantMatcher Out;
32 Out.List.push_back(Matcher.clone());
33 return Out;
34}
35
36VariantMatcher
37VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) {
38 VariantMatcher Out;
39 for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
40 Out.List.push_back(Matchers[i]->clone());
41 }
42 return Out;
43}
44
45VariantMatcher::~VariantMatcher() {
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000046 reset();
47}
48
Samuel Benzaquen9d028072013-08-13 14:54:51 +000049VariantMatcher &VariantMatcher::operator=(const VariantMatcher &Other) {
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000050 if (this == &Other) return *this;
51 reset();
52 for (size_t i = 0, e = Other.List.size(); i != e; ++i) {
53 List.push_back(Other.List[i]->clone());
54 }
55 return *this;
56}
57
Samuel Benzaquen9d028072013-08-13 14:54:51 +000058bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const {
59 if (List.size() != 1) return false;
60 Out = List[0];
61 return true;
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000062}
63
Samuel Benzaquen9d028072013-08-13 14:54:51 +000064void VariantMatcher::reset() {
65 llvm::DeleteContainerPointers(List);
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000066}
67
Samuel Benzaquen9d028072013-08-13 14:54:51 +000068std::string VariantMatcher::getTypeAsString() const {
Samuel Benzaquenef7eb022013-06-21 15:51:31 +000069 std::string Inner;
70 for (size_t I = 0, E = List.size(); I != E; ++I) {
71 if (I != 0) Inner += "|";
72 Inner += List[I]->getSupportedKind().asStringRef();
73 }
74 return (Twine("Matcher<") + Inner + ">").str();
75}
76
Samuel Benzaquen9d028072013-08-13 14:54:51 +000077const DynTypedMatcher *VariantMatcher::getTypedMatcher(
78 bool (*CanConstructCallback)(const DynTypedMatcher &)) const {
79 const DynTypedMatcher *Out = NULL;
80 for (size_t i = 0, e = List.size(); i != e; ++i) {
81 if (CanConstructCallback(*List[i])) {
82 if (Out) return NULL;
83 Out = List[i];
84 }
85 }
86 return Out;
87}
88
Manuel Klimekf7f295f2013-05-14 09:13:00 +000089VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
90 *this = Other;
91}
92
Samuel Benzaquen7a337af2013-06-04 15:46:22 +000093VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
94 setUnsigned(Unsigned);
Manuel Klimekf7f295f2013-05-14 09:13:00 +000095}
96
97VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
98 setString(String);
99}
100
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000101VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
102 setMatcher(Matcher);
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000103}
104
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000105VariantValue::~VariantValue() { reset(); }
106
107VariantValue &VariantValue::operator=(const VariantValue &Other) {
108 if (this == &Other) return *this;
109 reset();
110 switch (Other.Type) {
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000111 case VT_Unsigned:
112 setUnsigned(Other.getUnsigned());
113 break;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000114 case VT_String:
115 setString(Other.getString());
116 break;
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000117 case VT_Matcher:
118 setMatcher(Other.getMatcher());
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000119 break;
120 case VT_Nothing:
121 Type = VT_Nothing;
122 break;
123 }
124 return *this;
125}
126
127void VariantValue::reset() {
128 switch (Type) {
129 case VT_String:
130 delete Value.String;
131 break;
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000132 case VT_Matcher:
133 delete Value.Matcher;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000134 break;
135 // Cases that do nothing.
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000136 case VT_Unsigned:
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000137 case VT_Nothing:
138 break;
139 }
140 Type = VT_Nothing;
141}
142
Samuel Benzaquen7a337af2013-06-04 15:46:22 +0000143bool VariantValue::isUnsigned() const {
144 return Type == VT_Unsigned;
145}
146
147unsigned VariantValue::getUnsigned() const {
148 assert(isUnsigned());
149 return Value.Unsigned;
150}
151
152void VariantValue::setUnsigned(unsigned NewValue) {
153 reset();
154 Type = VT_Unsigned;
155 Value.Unsigned = NewValue;
156}
157
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000158bool VariantValue::isString() const {
159 return Type == VT_String;
160}
161
162const std::string &VariantValue::getString() const {
163 assert(isString());
164 return *Value.String;
165}
166
167void VariantValue::setString(const std::string &NewValue) {
168 reset();
169 Type = VT_String;
170 Value.String = new std::string(NewValue);
171}
172
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000173bool VariantValue::isMatcher() const {
174 return Type == VT_Matcher;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000175}
176
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000177const VariantMatcher &VariantValue::getMatcher() const {
178 assert(isMatcher());
179 return *Value.Matcher;
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000180}
181
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000182void VariantValue::setMatcher(const VariantMatcher &NewValue) {
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000183 reset();
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000184 Type = VT_Matcher;
185 Value.Matcher = new VariantMatcher(NewValue);
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000186}
187
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000188std::string VariantValue::getTypeAsString() const {
189 switch (Type) {
190 case VT_String: return "String";
Samuel Benzaquen9d028072013-08-13 14:54:51 +0000191 case VT_Matcher: return getMatcher().getTypeAsString();
Samuel Benzaquen76c2f922013-06-20 14:28:32 +0000192 case VT_Unsigned: return "Unsigned";
193 case VT_Nothing: return "Nothing";
194 }
195 llvm_unreachable("Invalid Type");
196}
197
Manuel Klimekf7f295f2013-05-14 09:13:00 +0000198} // end namespace dynamic
199} // end namespace ast_matchers
200} // end namespace clang