Refactor VariantMatcher::MatcherOps to reduce the amount of generated code.
Summary:
Refactor VariantMatcher::MatcherOps to reduce the amount of generated code.
- Make some code type agnostic and move it to the cpp file.
- Return a DynTypedMatcher instead of storing the object in MatcherOps.
This change reduces the number of symbols generated in Registry.cpp by
~19%, the object byte size by ~17% and the compilation time (in non-release mode) by ~20%.
Reviewers: klimek
Subscribers: klimek, cfe-commits
Differential Revision: http://reviews.llvm.org/D5124
llvm-svn: 217152
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 57c7b80..3d14157 100644
--- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -49,7 +49,32 @@
return true;
}
-VariantMatcher::MatcherOps::~MatcherOps() {}
+bool
+VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const {
+ IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
+ return Matcher.canConvertTo(NodeKind);
+}
+
+llvm::Optional<DynTypedMatcher>
+VariantMatcher::MatcherOps::constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> InnerMatchers) const {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (const auto &InnerMatcher : InnerMatchers) {
+ // Abort if any of the inner matchers can't be converted to
+ // Matcher<T>.
+ if (!InnerMatcher.Value)
+ return llvm::None;
+ llvm::Optional<DynTypedMatcher> Inner =
+ InnerMatcher.Value->getTypedMatcher(*this);
+ if (!Inner)
+ return llvm::None;
+ DynMatchers.push_back(*Inner);
+ }
+ return DynTypedMatcher::constructVariadic(Func, DynMatchers);
+}
+
VariantMatcher::Payload::~Payload() {}
class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
@@ -65,10 +90,12 @@
.str();
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
bool Ignore;
if (Ops.canConstructFrom(Matcher, Ignore))
- Ops.constructFrom(Matcher);
+ return Matcher;
+ return llvm::None;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -104,7 +131,8 @@
return (Twine("Matcher<") + Inner + ">").str();
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
bool FoundIsExact = false;
const DynTypedMatcher *Found = nullptr;
int NumFound = 0;
@@ -124,7 +152,8 @@
}
// We only succeed if we found exactly one, or if we found an exact match.
if (Found && (FoundIsExact || NumFound == 1))
- Ops.constructFrom(*Found);
+ return *Found;
+ return llvm::None;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -165,8 +194,9 @@
return Inner;
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
- Ops.constructVariadicOperator(Func, Args);
+ llvm::Optional<DynTypedMatcher>
+ getTypedMatcher(const MatcherOps &Ops) const override {
+ return Ops.constructVariadicOperator(Func, Args);
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,