Home | History | Annotate | Download | only in Dynamic
      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