<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On Sep 23, 2014, at 1:28 PM, jahanian <<a href="mailto:fjahanian@apple.com">fjahanian@apple.com</a>> wrote:<br><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div><div>On Sep 22, 2014, at 5:15 PM, John McCall <<a href="mailto:rjmccall@apple.com">rjmccall@apple.com</a>> wrote:</div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On Sep 22, 2014, at 4:20 PM, jahanian <<a href="mailto:fjahanian@apple.com">fjahanian@apple.com</a>> wrote:<br><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">This patch allows mangling of microsoft’s __uuidof expression <span style="font-family: Menlo; font-size: 11px;">for the Itanium ABI when under -fms-extensions</span><div><span style="font-family: Menlo; font-size: 11px;">// <a href="rdar://">rdar://</a></span><span style="font-family: Menlo; font-size: 11px;">17784718</span></div></div></blockquote><div><br></div></div><div>+  case Expr::CXXUuidofExprClass: {</div><div>+    if (!getASTContext().getLangOpts().MicrosoftExt) {</div><div>+      DiagnosticsEngine &Diags = Context.getDiags();</div><div>+        unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,</div><div>+                                    "cannot yet mangle __uuidof expression");</div><div>+        Diags.Report(E->getExprLoc(), DiagID)</div><div>+        << E->getStmtClassName() << E->getSourceRange();</div><div><br></div><div>You don’t need this.  We should never see these expressions except that</div><div>language flag is set, and even if we do, it’s okay to mangle them this way.</div><div><br></div><div>+    } else {</div><div>+        const CXXUuidofExpr *UE = cast<CXXUuidofExpr>(E);</div><div>+        // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from</div><div>+        // const __s_GUID _GUID_{lower case UUID with underscores}</div><div>+        StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext());</div><div>+        std::string Name = "_GUID_" + Uuid.lower();</div><div>+        std::replace(Name.begin(), Name.end(), '-', '_');</div><div>+        Out << "$E?";</div><div>+        Out << Name << "@@3U__s_GUID@@B";</div><div>+    }</div><div><br></div><div>You need to use an Itanium-style mangling here, not a Microsoft-style one.</div><div>That specifically means only using alphanumeric characters.</div><div><br></div><div><div>Also, since we’re using a different mangling, we should also properly</div><div>handle dependent operands instead of assuming that the operand can</div><div>always be fully resolved.</div></div><div><br></div><div>In the Itanium scheme, this falls into the general category of a</div><div>vendor-extended operator, which is mangled as</div><div>  u <name-of-operator> <operands...></div><div>As far as I can tell, it’s impossible to demangle these without knowledge of</div><div>the specific vendor extension, because nothing in the mangling actually</div><div>indicates how many operands follow.  So I don’t see any reason to actually</div><div>insist that the operand actually be an expression, which is good, because</div><div>__uuidof is like sizeof in that its operand can be either a type or an expression.</div><div><br></div><div>For sizeof, the mangling prefix is either “st” or “sz”, respectively.</div><div>So let’s use these manglings:</div><div><br></div><div><font face="Courier">  u8__uuidoft <type>          # __uuidof (a type)</font></div><div><font face="Courier">  u8__uuidofz <expression>    # __uuidof (an expression)</font></div></div></blockquote><div><br></div>Hi John,</div><div>Please review the new patch.</div></div></blockquote><div><br></div>Looks good.  Please also test the dependent cases; this would look something like:</div><div><br></div><div>template <class T> void test_uuidofType(void(*arg)[sizeof(__uuidof(T))] = 0) {}</div><div>template <class T> void test_uuidofExpr(void(*arg)[sizeof(__uuidof(T::member))] = 0) {}</div><div>struct HasMember { typedef TestStruct member; };</div><div>void test() {</div><div>  test_uuidofType<TestStruct>();</div><div>  test_uuidofExpr<HasMember>();</div><div>}</div><div><br></div><div>John.</div></body></html>