<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Thanks Hartmut.  It's interesting that visual c++ has problems compiling it.  Just so that is easier to spot patches like this, in the future could you separate (when possible) patches into smaller patches?  For example, the patch to the serialization code has nothing to do with your modifications to the CodeGen code, so making two separate patches here would have made it easier to see what changed.  Basically I see two orthogonal concepts here; making patches include only related changes makes them easier to read.<div><br class="webkit-block-placeholder"></div><div>Another point I should mention is that while your patch is correct, it goes against the design I was going after (which illustrates that my design is not portable).  Template specialization of inner classes without having to specialize the outer class is a useful feature when you don't want to redefine (i.e. specialize) the entire outer class.  Since I only had one example in my code of doing specialization of an inner class, this design point didn't show up in my code.  Clearly visual c++ doesn't support this, so I will have to find another way.</div><div><br class="webkit-block-placeholder"></div><div>Thanks so much for spotting this!</div><div><br class="webkit-block-placeholder"></div><div>Ted<div><br><div><div>On Oct 17, 2007, at 8:00 AM, Hartmut Kaiser wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; ">==============================================================================<br>--- cfe/trunk/Driver/SerializationTest.cpp (original)<br>+++ cfe/trunk/Driver/SerializationTest.cpp Wed Oct 17 10:00:17 2007<br>@@ -196,29 +196,32 @@<br><br><br>template<><span class="Apple-converted-space"> </span><br>-struct IntrospectionTrait<clang::IdentifierInfo>::Flags {<br>-  enum { isPod = false,  // Cannot copy via memcpy.  Must use copy-ctor.    <br>-         hasUniqueInstances = true, // Two pointers with different<br>-                                    // addreses point to objects<br>-                                    // that are not equal to each other.    <br>-         hasUniqueReferences = true // Two (non-temporary) pointers                                    <br>-                                    // will point to distinct instances.<br>+struct IntrospectionTrait<clang::IdentifierInfo> {<br>+<br>+  struct Flags {<span class="Apple-converted-space"> </span><br>+    enum { isPod = false,  // Cannot copy via memcpy.  Must use copy-ctor.    <br>+           hasUniqueInstances = true, // Two pointers with different<br>+                                      // addreses point to objects<br>+                                      // that are not equal to each other.    <br>+           hasUniqueReferences = true // Two (non-temporary) pointers                                    <br>+                                      // will point to distinct instances.<br>+    };<br>+  };<br>+<br>+  template<typename Introspector><br>+  struct Ops {<br>+    static void Introspect(clang::IdentifierInfo& X, Introspector& I) {<br>+  //    I(X.getTokenID());<br>+      I(X.getBuiltinID(),9); // FIXME: do 9 bit specialization.<br>+  //    I(X.getObjCKeywordID());<br>+      I(X.hasMacroDefinition());<br>+      I(X.isExtensionToken());<br>+      I(X.isPoisoned());<br>+      I(X.isOtherTargetMacro());<br>+      I(X.isCPlusPlusOperatorKeyword());<br>+      I(X.isNonPortableBuiltin());<br>+    }<br>  };<br>-};<br>-  <br>-template<> template<typename Introspector><br>-struct IntrospectionTrait<clang::IdentifierInfo>::Ops<Introspector> {<br>-  static void Introspect(clang::IdentifierInfo& X, Introspector& I) {<br>-//    I(X.getTokenID());<br>-    I(X.getBuiltinID(),9); // FIXME: do 9 bit specialization.<br>-//    I(X.getObjCKeywordID());<br>-    I(X.hasMacroDefinition());<br>-    I(X.isExtensionToken());<br>-    I(X.isPoisoned());<br>-    I(X.isOtherTargetMacro());<br>-    I(X.isCPlusPlusOperatorKeyword());<br>-    I(X.isNonPortableBuiltin());<br>-  }<br>};<br><br>template<> template<><br><br>Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=43074&r1=43073&r2=43074&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=43074&r1=43073&r2=43074&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)<br>+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Wed Oct 17 10:00:17 2007<br>@@ -23,7 +23,7 @@<br><br><br>namespace llvm {<br>-  template<typename T> class IntrospectionTrait;<br>+  template <typename T> struct IntrospectionTrait;<br>  template <typename T> struct DenseMapInfo;<br>}<br><br>@@ -140,7 +140,11 @@<br>  void setFETokenInfo(void *T) { FETokenInfo = T; }<br><br>  // For serialization and profiling.<br>+#if defined(_MSC_VER) && _MSC_VER <= 1400   // workaround for VC++ upto V8.0<br>+  template<typename T> friend class /*llvm::*/IntrospectionTrait;<br>+#else<br>  template<typename T> friend class llvm::IntrospectionTrait;<br>+#endif<br>};<br><br>/// IdentifierTable - This table implements an efficient mapping from strings to<br>@@ -183,7 +187,11 @@<br>  void PrintStats() const;<br><br>  // For serialization and profiling.<br>+#if defined(_MSC_VER) && _MSC_VER <= 1400   // workaround for VC++ upto V8.0<br>+  template<typename T> friend class /*llvm::*/IntrospectionTrait;<br>+#else<br>  template<typename T> friend class llvm::IntrospectionTrait;<br>+#endif<br>private:<br>  void AddKeywords(const LangOptions &LangOpts);<br>};<br></span></blockquote></div><br></div></div></body></html>