Hi klimek,

Remove some template instantiations to reduce the number of symbols.
Registry.cpp instantiates all the matchers and it fails to build under MSVC in 
debug mode.

http://reviews.llvm.org/D5072

Files:
  include/clang/ASTMatchers/ASTMatchersInternal.h
  include/clang/ASTMatchers/Dynamic/VariantValue.h
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -232,26 +232,27 @@
 public:
   /// \brief Takes ownership of the provided implementation pointer.
   explicit Matcher(MatcherInterface<T> *Implementation)
-      : Implementation(Implementation) {}
+      : Implementation(Implementation), ImplRefCount(Implementation) {}
 
   /// \brief Implicitly converts \c Other to a Matcher<T>.
   ///
   /// Requires \c T to be derived from \c From.
   template <typename From>
   Matcher(const Matcher<From> &Other,
           typename std::enable_if<std::is_base_of<From, T>::value &&
                                   !std::is_same<From, T>::value>::type * = 0)
-      : Implementation(new ImplicitCastMatcher<From>(Other)) {}
+      : Implementation(new ImplicitCastMatcher<From>(Other)),
+        ImplRefCount(Implementation) {}
 
   /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
   ///
   /// The resulting matcher is not strict, i.e. ignores qualifiers.
   template <typename TypeT>
   Matcher(const Matcher<TypeT> &Other,
-          typename std::enable_if<
-            std::is_same<T, QualType>::value &&
-            std::is_same<TypeT, Type>::value>::type* = 0)
-      : Implementation(new TypeToQualType<TypeT>(Other)) {}
+          typename std::enable_if<std::is_same<T, QualType>::value &&
+                                  std::is_same<TypeT, Type>::value>::type * = 0)
+      : Implementation(new TypeToQualType<TypeT>(Other)),
+        ImplRefCount(Implementation) {}
 
   /// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
   bool matches(const T &Node,
@@ -270,7 +271,7 @@
   uint64_t getID() const {
     /// FIXME: Document the requirements this imposes on matcher
     /// implementations (no new() implementation_ during a Matches()).
-    return reinterpret_cast<uint64_t>(Implementation.get());
+    return reinterpret_cast<uint64_t>(Implementation);
   }
 
   /// \brief Allows the conversion of a \c Matcher<Type> to a \c
@@ -313,7 +314,10 @@
     const Matcher<Base> From;
   };
 
-  IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
+  MatcherInterface<T> *Implementation;
+  // Do not instantiate IntrusiveRefCntPtr<> for each MatcherInterface<T>.
+  // This reduces the symbol bloat that breaks MSVC builds.
+  IntrusiveRefCntPtr<RefCountedBaseVPTR> ImplRefCount;
 };  // class Matcher
 
 /// \brief A convenient helper for creating a Matcher<T> without specifying
Index: include/clang/ASTMatchers/Dynamic/VariantValue.h
===================================================================
--- include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -206,15 +206,19 @@
   public:
     typedef ast_matchers::internal::Matcher<T> MatcherT;
 
+    TypedMatcherOps() : Out() {}
+    ~TypedMatcherOps() { delete Out; }
+
     virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
                                   bool &IsExactMatch) const {
       IsExactMatch = Matcher.getSupportedKind().isSame(
           ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
       return Matcher.canConvertTo<T>();
     }
 
     virtual void constructFrom(const DynTypedMatcher& Matcher) {
-      Out.reset(new MatcherT(Matcher.convertTo<T>()));
+      delete Out;
+      Out = new MatcherT(Matcher.convertTo<T>());
     }
 
     virtual void constructVariadicOperator(
@@ -229,16 +233,19 @@
         }
         DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
       }
-      Out.reset(new MatcherT(
+      delete Out;
+      Out = new MatcherT(
           new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
-              Func, DynMatchers)));
+              Func, DynMatchers));
     }
 
-    bool hasMatcher() const { return Out.get() != nullptr; }
+    bool hasMatcher() const { return Out != nullptr; }
     const MatcherT &matcher() const { return *Out; }
 
   private:
-    std::unique_ptr<MatcherT> Out;
+    // Do not instantiate std::unique_ptr<> for each MatcherT.
+    // This reduces the symbol bloat that breaks MSVC builds.
+    MatcherT* Out;
   };
 
   IntrusiveRefCntPtr<const Payload> Value;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to