Updated the documentation. Replaced some "return NULL" with
llvm_unreachable().
Hi klimek,
http://llvm-reviews.chandlerc.com/D1446
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1446?vs=3597&id=3600#toc
Files:
include/clang/ASTMatchers/Dynamic/VariantValue.h
lib/ASTMatchers/Dynamic/VariantValue.cpp
Index: include/clang/ASTMatchers/Dynamic/VariantValue.h
===================================================================
--- include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -69,31 +69,31 @@
void reset();
/// \brief Whether the matcher is null.
- bool isNull() const { return List.empty(); }
+ bool isNull() const { return Tag == RT_Nothing; }
/// \brief Return a single matcher, if there is no ambiguity.
///
- /// \returns True, and set Out to the matcher, if there is only one matcher.
- /// False, if the underlying matcher is a polymorphic matcher with
+ /// \returns \c true, and set Out to the matcher, if there is only one
+ /// matcher. \c false, if the underlying matcher is a polymorphic matcher with
/// more than one representation.
bool getSingleMatcher(const DynTypedMatcher *&Out) const;
- /// \brief Determines if any of the contained matchers can be converted
- /// to \c Matcher<T>.
+ /// \brief Determines the contained matcher can be converted to \c Matcher<T>.
///
- /// Returns true if one, and only one, of the contained matchers can be
- /// converted to \c Matcher<T>. If there are more than one that can, the
- /// result would be ambigous and false is returned.
+ /// For the Single case, it returns true if it can be converted to
+ /// \c Matcher<T>.
+ /// For the Polymorphic case, it returns true if one, and only one, of the
+ /// overloads can be converted to \c Matcher<T>. If there are more than one
+ /// that can, the result would be ambiguous and false is returned.
template <class T>
bool hasTypedMatcher() const {
- return getTypedMatcher(
- &ast_matchers::internal::Matcher<T>::canConstructFrom) != NULL;
+ return hasTypedMatcher(
+ &ast_matchers::internal::Matcher<T>::canConstructFrom);
}
- /// \brief Wrap the correct matcher as a \c Matcher<T>.
+ /// \brief Return this matcher as a \c Matcher<T>.
///
- /// Selects the appropriate matcher from the wrapped matchers and returns it
- /// as a \c Matcher<T>.
+ /// Handles the different types (Single, Polymorphic) accordingly.
/// Asserts that \c hasTypedMatcher<T>() is true.
template <class T>
ast_matchers::internal::Matcher<T> getTypedMatcher() const {
@@ -109,13 +109,38 @@
std::string getTypeAsString() const;
private:
+ void setSingle(const DynTypedMatcher &Matcher);
+ void setPolymorphic(ArrayRef<const DynTypedMatcher *> Matchers);
+
+ /// \brief Returns whether the matcher passes the callback.
+ bool hasTypedMatcher(
+ bool (*CanConstructCallback)(const DynTypedMatcher &)) const;
+
/// \brief Returns the matcher that passes the callback.
///
- /// Returns NULL if no matcher passes the test, or if more than one do.
- const DynTypedMatcher *
- getTypedMatcher(bool (*CanConstructCallback)(const DynTypedMatcher &)) const;
+ /// The caller should have checked with hasTypedMatcher() before calling here.
+ /// This will always return non-NULL.
+ const DynTypedMatcher *getTypedMatcher(
+ bool (*CanConstructCallback)(const DynTypedMatcher &)) const;
+
+ enum RepresentationTag {
+ RT_Nothing,
+ RT_Single,
+ RT_Polymorphic
+ };
+ RepresentationTag Tag;
- std::vector<const DynTypedMatcher *> List;
+ struct SingleRep {
+ OwningPtr<const DynTypedMatcher> Matcher;
+ };
+ struct PolymorphicRep {
+ std::vector<const DynTypedMatcher *> Matchers;
+ ~PolymorphicRep();
+ };
+ union {
+ SingleRep *AsSingle;
+ PolymorphicRep *AsPolymorphic;
+ };
};
/// \brief Variant value class.
Index: lib/ASTMatchers/Dynamic/VariantValue.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -21,24 +21,26 @@
namespace ast_matchers {
namespace dynamic {
-VariantMatcher::VariantMatcher() : List() {}
+VariantMatcher::PolymorphicRep::~PolymorphicRep() {
+ llvm::DeleteContainerPointers(Matchers);
+}
+
+VariantMatcher::VariantMatcher() : Tag(RT_Nothing) {}
VariantMatcher::VariantMatcher(const VariantMatcher& Other) {
*this = Other;
}
VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
VariantMatcher Out;
- Out.List.push_back(Matcher.clone());
+ Out.setSingle(Matcher);
return Out;
}
VariantMatcher
VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) {
VariantMatcher Out;
- for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
- Out.List.push_back(Matchers[i]->clone());
- }
+ Out.setPolymorphic(Matchers);
return Out;
}
@@ -49,41 +51,117 @@
VariantMatcher &VariantMatcher::operator=(const VariantMatcher &Other) {
if (this == &Other) return *this;
reset();
- for (size_t i = 0, e = Other.List.size(); i != e; ++i) {
- List.push_back(Other.List[i]->clone());
+ switch (Other.Tag) {
+ case RT_Nothing:
+ break;
+ case RT_Single:
+ setSingle(*Other.AsSingle->Matcher);
+ break;
+ case RT_Polymorphic:
+ setPolymorphic(Other.AsPolymorphic->Matchers);
+ break;
}
return *this;
}
bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const {
- if (List.size() != 1) return false;
- Out = List[0];
- return true;
+ switch (Tag) {
+ case RT_Nothing:
+ return false;
+ case RT_Single:
+ Out = AsSingle->Matcher.get();
+ return true;
+ case RT_Polymorphic:
+ if (AsPolymorphic->Matchers.size() != 1)
+ return false;
+ Out = AsPolymorphic->Matchers[0];
+ return true;
+ }
}
void VariantMatcher::reset() {
- llvm::DeleteContainerPointers(List);
+ switch (Tag) {
+ case RT_Nothing:
+ break;
+ case RT_Single:
+ delete AsSingle;
+ break;
+ case RT_Polymorphic:
+ delete AsPolymorphic;
+ break;
+ }
+ Tag = RT_Nothing;
+}
+
+void VariantMatcher::setSingle(const DynTypedMatcher &Matcher) {
+ assert(Tag == RT_Nothing);
+ Tag = RT_Single;
+ AsSingle = new SingleRep;
+ AsSingle->Matcher.reset(Matcher.clone());
+}
+
+void
+VariantMatcher::setPolymorphic(ArrayRef<const DynTypedMatcher *> Matchers) {
+ assert(Tag == RT_Nothing);
+ Tag = RT_Polymorphic;
+ AsPolymorphic = new PolymorphicRep;
+ for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
+ AsPolymorphic->Matchers.push_back(Matchers[i]->clone());
+ }
}
std::string VariantMatcher::getTypeAsString() const {
- std::string Inner;
- for (size_t I = 0, E = List.size(); I != E; ++I) {
- if (I != 0) Inner += "|";
- Inner += List[I]->getSupportedKind().asStringRef();
+ switch (Tag) {
+ case RT_Nothing:
+ return "<Nothing>";
+ case RT_Single:
+ return (Twine("Matcher<") +
+ AsSingle->Matcher->getSupportedKind().asStringRef() + ">").str();
+ case RT_Polymorphic: {
+ std::string Inner;
+ for (size_t i = 0, e = AsPolymorphic->Matchers.size(); i != e; ++i) {
+ if (i != 0) Inner += "|";
+ Inner += AsPolymorphic->Matchers[i]->getSupportedKind().asStringRef();
+ }
+ return (Twine("Matcher<") + Inner + ">").str();
+ }
+ }
+}
+
+bool VariantMatcher::hasTypedMatcher(
+ bool (*CanConstructCallback)(const DynTypedMatcher &)) const {
+ switch (Tag) {
+ case RT_Nothing:
+ return false;
+ case RT_Single:
+ return CanConstructCallback(*AsSingle->Matcher);
+ case RT_Polymorphic: {
+ bool FoundOne = false;
+ for (size_t i = 0, e = AsPolymorphic->Matchers.size(); i != e; ++i) {
+ if (CanConstructCallback(*AsPolymorphic->Matchers[i])) {
+ if (FoundOne)
+ return false;
+ FoundOne = true;
+ }
+ }
+ return FoundOne;
+ }
}
- return (Twine("Matcher<") + Inner + ">").str();
}
const DynTypedMatcher *VariantMatcher::getTypedMatcher(
bool (*CanConstructCallback)(const DynTypedMatcher &)) const {
- const DynTypedMatcher *Out = NULL;
- for (size_t i = 0, e = List.size(); i != e; ++i) {
- if (CanConstructCallback(*List[i])) {
- if (Out) return NULL;
- Out = List[i];
+ assert(hasTypedMatcher(CanConstructCallback));
+ switch (Tag) {
+ case RT_Nothing: llvm_unreachable("hasTypedMatcher() == false");
+ case RT_Single: return AsSingle->Matcher.get();
+ case RT_Polymorphic:
+ for (size_t i = 0, e = AsPolymorphic->Matchers.size(); i != e; ++i) {
+ if (CanConstructCallback(*AsPolymorphic->Matchers[i]))
+ return AsPolymorphic->Matchers[i];
}
+ llvm_unreachable("hasTypedMatcher() == false");
}
- return Out;
}
VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits