1 //===--- 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 17 #include "clang/Basic/LLVM.h" 18 19 namespace clang { 20 namespace ast_matchers { 21 namespace dynamic { 22 23 MatcherList::MatcherList() : List() {} 24 25 MatcherList::MatcherList(const DynTypedMatcher &Matcher) 26 : List(1, Matcher.clone()) {} 27 28 MatcherList::MatcherList(const MatcherList& Other) { 29 *this = Other; 30 } 31 32 MatcherList::~MatcherList() { 33 reset(); 34 } 35 36 MatcherList &MatcherList::operator=(const MatcherList &Other) { 37 if (this == &Other) return *this; 38 reset(); 39 for (size_t i = 0, e = Other.List.size(); i != e; ++i) { 40 List.push_back(Other.List[i]->clone()); 41 } 42 return *this; 43 } 44 45 void MatcherList::add(const DynTypedMatcher &Matcher) { 46 List.push_back(Matcher.clone()); 47 } 48 49 void MatcherList::reset() { 50 for (size_t i = 0, e = List.size(); i != e; ++i) { 51 delete List[i]; 52 } 53 List.resize(0); 54 } 55 56 std::string MatcherList::getTypeAsString() const { 57 std::string Inner; 58 for (size_t I = 0, E = List.size(); I != E; ++I) { 59 if (I != 0) Inner += "|"; 60 Inner += List[I]->getSupportedKind().asStringRef(); 61 } 62 return (Twine("Matcher<") + Inner + ">").str(); 63 } 64 65 VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) { 66 *this = Other; 67 } 68 69 VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) { 70 setUnsigned(Unsigned); 71 } 72 73 VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) { 74 setString(String); 75 } 76 77 VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) { 78 setMatchers(MatcherList(Matcher)); 79 } 80 81 VariantValue::VariantValue(const MatcherList &Matchers) : Type(VT_Nothing) { 82 setMatchers(Matchers); 83 } 84 85 VariantValue::~VariantValue() { reset(); } 86 87 VariantValue &VariantValue::operator=(const VariantValue &Other) { 88 if (this == &Other) return *this; 89 reset(); 90 switch (Other.Type) { 91 case VT_Unsigned: 92 setUnsigned(Other.getUnsigned()); 93 break; 94 case VT_String: 95 setString(Other.getString()); 96 break; 97 case VT_Matchers: 98 setMatchers(Other.getMatchers()); 99 break; 100 case VT_Nothing: 101 Type = VT_Nothing; 102 break; 103 } 104 return *this; 105 } 106 107 void VariantValue::reset() { 108 switch (Type) { 109 case VT_String: 110 delete Value.String; 111 break; 112 case VT_Matchers: 113 delete Value.Matchers; 114 break; 115 // Cases that do nothing. 116 case VT_Unsigned: 117 case VT_Nothing: 118 break; 119 } 120 Type = VT_Nothing; 121 } 122 123 bool VariantValue::isUnsigned() const { 124 return Type == VT_Unsigned; 125 } 126 127 unsigned VariantValue::getUnsigned() const { 128 assert(isUnsigned()); 129 return Value.Unsigned; 130 } 131 132 void VariantValue::setUnsigned(unsigned NewValue) { 133 reset(); 134 Type = VT_Unsigned; 135 Value.Unsigned = NewValue; 136 } 137 138 bool VariantValue::isString() const { 139 return Type == VT_String; 140 } 141 142 const std::string &VariantValue::getString() const { 143 assert(isString()); 144 return *Value.String; 145 } 146 147 void VariantValue::setString(const std::string &NewValue) { 148 reset(); 149 Type = VT_String; 150 Value.String = new std::string(NewValue); 151 } 152 153 bool VariantValue::isMatchers() const { 154 return Type == VT_Matchers; 155 } 156 157 const MatcherList &VariantValue::getMatchers() const { 158 assert(isMatchers()); 159 return *Value.Matchers; 160 } 161 162 void VariantValue::setMatchers(const MatcherList &NewValue) { 163 reset(); 164 Type = VT_Matchers; 165 Value.Matchers = new MatcherList(NewValue); 166 } 167 168 std::string VariantValue::getTypeAsString() const { 169 switch (Type) { 170 case VT_String: return "String"; 171 case VT_Matchers: return getMatchers().getTypeAsString(); 172 case VT_Unsigned: return "Unsigned"; 173 case VT_Nothing: return "Nothing"; 174 } 175 llvm_unreachable("Invalid Type"); 176 } 177 178 } // end namespace dynamic 179 } // end namespace ast_matchers 180 } // end namespace clang 181