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 #include "llvm/ADT/STLExtras.h" 19 20 namespace clang { 21 namespace ast_matchers { 22 namespace dynamic { 23 24 VariantMatcher::VariantMatcher() : List() {} 25 26 VariantMatcher::VariantMatcher(const VariantMatcher& Other) { 27 *this = Other; 28 } 29 30 VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) { 31 VariantMatcher Out; 32 Out.List.push_back(Matcher.clone()); 33 return Out; 34 } 35 36 VariantMatcher 37 VariantMatcher::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 45 VariantMatcher::~VariantMatcher() { 46 reset(); 47 } 48 49 VariantMatcher &VariantMatcher::operator=(const VariantMatcher &Other) { 50 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 58 bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const { 59 if (List.size() != 1) return false; 60 Out = List[0]; 61 return true; 62 } 63 64 void VariantMatcher::reset() { 65 llvm::DeleteContainerPointers(List); 66 } 67 68 std::string VariantMatcher::getTypeAsString() const { 69 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 77 const 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 89 VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) { 90 *this = Other; 91 } 92 93 VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) { 94 setUnsigned(Unsigned); 95 } 96 97 VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) { 98 setString(String); 99 } 100 101 VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) { 102 setMatcher(Matcher); 103 } 104 105 VariantValue::~VariantValue() { reset(); } 106 107 VariantValue &VariantValue::operator=(const VariantValue &Other) { 108 if (this == &Other) return *this; 109 reset(); 110 switch (Other.Type) { 111 case VT_Unsigned: 112 setUnsigned(Other.getUnsigned()); 113 break; 114 case VT_String: 115 setString(Other.getString()); 116 break; 117 case VT_Matcher: 118 setMatcher(Other.getMatcher()); 119 break; 120 case VT_Nothing: 121 Type = VT_Nothing; 122 break; 123 } 124 return *this; 125 } 126 127 void VariantValue::reset() { 128 switch (Type) { 129 case VT_String: 130 delete Value.String; 131 break; 132 case VT_Matcher: 133 delete Value.Matcher; 134 break; 135 // Cases that do nothing. 136 case VT_Unsigned: 137 case VT_Nothing: 138 break; 139 } 140 Type = VT_Nothing; 141 } 142 143 bool VariantValue::isUnsigned() const { 144 return Type == VT_Unsigned; 145 } 146 147 unsigned VariantValue::getUnsigned() const { 148 assert(isUnsigned()); 149 return Value.Unsigned; 150 } 151 152 void VariantValue::setUnsigned(unsigned NewValue) { 153 reset(); 154 Type = VT_Unsigned; 155 Value.Unsigned = NewValue; 156 } 157 158 bool VariantValue::isString() const { 159 return Type == VT_String; 160 } 161 162 const std::string &VariantValue::getString() const { 163 assert(isString()); 164 return *Value.String; 165 } 166 167 void VariantValue::setString(const std::string &NewValue) { 168 reset(); 169 Type = VT_String; 170 Value.String = new std::string(NewValue); 171 } 172 173 bool VariantValue::isMatcher() const { 174 return Type == VT_Matcher; 175 } 176 177 const VariantMatcher &VariantValue::getMatcher() const { 178 assert(isMatcher()); 179 return *Value.Matcher; 180 } 181 182 void VariantValue::setMatcher(const VariantMatcher &NewValue) { 183 reset(); 184 Type = VT_Matcher; 185 Value.Matcher = new VariantMatcher(NewValue); 186 } 187 188 std::string VariantValue::getTypeAsString() const { 189 switch (Type) { 190 case VT_String: return "String"; 191 case VT_Matcher: return getMatcher().getTypeAsString(); 192 case VT_Unsigned: return "Unsigned"; 193 case VT_Nothing: return "Nothing"; 194 } 195 llvm_unreachable("Invalid Type"); 196 } 197 198 } // end namespace dynamic 199 } // end namespace ast_matchers 200 } // end namespace clang 201