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