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