[PATCH] ms-inline-asm: Scope inline asm labels to functions
Ehsan Akhgari
ehsan.akhgari at gmail.com
Sat Sep 6 14:03:41 PDT 2014
I started to look into this again, and I hit an issue that I'm not sure how
to solve. Creating a LabelDecl requires an IdentifierInfo corresponding to
the identifier token for the label name, but for these asm labels, we use a
different tokenizer on the LLVM side that doesn't know about
IdentifierInfo's at all. It looks like the IdentifierInfo argument is used
to construct a DeclarationName. I suppose one option that I have here is
to add a new NameKind to DeclarationName and make it possible to construct
a DeclarationName from that, but is there an easier option here?
On Thu, Jul 31, 2014 at 3:50 PM, Reid Kleckner <rnk at google.com> wrote:
> On Thu, Jul 24, 2014 at 4:26 PM, Ehsan Akhgari <ehsan.akhgari at gmail.com>
> wrote:
>
>> On Thu, Jul 24, 2014 at 2:52 PM, Reid Kleckner <rnk at google.com> wrote:
>>
>>> ================
>>> Comment at: lib/Parse/ParseStmtAsm.cpp:96
>>> @@ -95,1 +95,3 @@
>>>
>>> + void LookupInlineAsmLabel(StringRef &Identifier, llvm::SourceMgr &LSM,
>>> + llvm::SMLoc Location, bool Create) {
>>> ----------------
>>> You can return a StringRef directly.
>>>
>>> ================
>>> Comment at: lib/Sema/SemaDecl.cpp:1492
>>> @@ -1491,1 +1491,3 @@
>>>
>>> + HandleMSAsmLabelsOnScopePop();
>>> +
>>> ----------------
>>> I believe ActOnPopScope happens on any closing curly brace, so this
>>> won't do the "right" thing:
>>> void f() {
>>> bool failed;
>>> __asm retry:
>>> {
>>> failed = g();
>>> } // The label is cleared here.
>>> if (failed)
>>> __asm jmp retry
>>> }
>>>
>>> Thinking more carefully, I don't think having the label map right on
>>> Sema works at all in the general case of nested functions. Consider this
>>> C++ example with inner classes:
>>> void f() {
>>> __asm some_label:
>>> struct A {
>>> static void g() {
>>> __asm jmp some_label ; This should jump forwards
>>> __asm some_label:
>>> __asm nop
>>> }
>>> };
>>> }
>>>
>>> You can build similar test cases from C++11 lambdas and Obj-C blocks,
>>> and now OpenMP captured statements.
>>>
>>> We need to associate this label map with the function we're currently
>>> processing. Now that I'm considering the actual implementation
>>> difficulties, I'm going back to your "proposal #3" on PR20023, where we
>>> model these labels as regular label statements. That way, we reuse all the
>>> right name lookup machinery. We won't be able to 'goto' a label from an
>>> inline asm statement or 'jmp' to a non-asm label, so if you go this way,
>>> please diagnose both cases. You can probably add a bit to LabelDecl to
>>> track whether the label was from MS inline asm or regular source code.
>>>
>>> Apologies for the runaround, but I think it's probably better to rewrite
>>> along these lines. What do you think?
>>>
>>
>> Hmm, there are a number of problems with that approach. One is that we
>> need to break up __asm blocks and perhaps remember part of the parser state
>> until we hit the end of the function (such as the number of braces we have
>> seen, their source locations, etc.) which complicates the parsing code, and
>> actually needs us to do something at the end of the function too. It also
>> means that we won't be able to reuse LookupInlineAsmIdentifier, since
>> AFAICT labels are not Expr's. Also, it will mean that the __asm blocks
>> will be disjoint across labels, even after my __asm block joining patch.
>>
>
> I'm don't want to support going to labels in asm or jumping out: we
> shouldn't break up __asm blobs and introduce new LabelStmts. Instead, we
> should synthesize a LabelDecl with no associated LabelStmt and use the rest
> of the usual label machinery to insert it into the correct function scope.
> However, when we see 'goto label_from_asm', we'll have to add code to
> reject that. Presumably we can tell the two kinds of LabelDecl apart by
> the presence or absence of a LabelStmt.
>
>
>> It seems like your main objection to this approach is to storing the
>> label map on Sema, and that is quite fair (and I should add tests for
>> that!). But isn't a much easier solution to that to store the label map at
>> the right place? I've been looking at the code that handles LabelDecl's,
>> and I think we can get by with storing the map on Scope objects, and do
>> something similar to Sema::LookupOrCreateLabel to make sure we are
>> accessing the right function scope. I think with that change, everything
>> else in my patch will work properly.
>>
>
> That would work too, but I think you'll end up duplicating lots of the
> label processing logic if you go that way.
>
> It's probably also worth thinking about how to handle these kinds of test
> cases:
>
> void foo() {
> __asm jmp bar ; is 'bar' a function name or label?
> }
> void bar();
>
--
Ehsan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140906/955403ab/attachment.html>
More information about the cfe-commits
mailing list