[llvm] r242847 - [dsymutil] Implement ODR uniquing for C++ code.

David Blaikie dblaikie at gmail.com
Wed Jul 29 15:35:38 PDT 2015


On Wed, Jul 29, 2015 at 3:09 PM, Frédéric Riss <friss at apple.com> wrote:

> How about the attached patch. It would go with the checked-in
> odr-uniquing.o. This one just checks that all the basic types subject to
> uniquing are actually uniqued (or not if the -no-odr flag is passed). It
> requires only one object file because we can link it against itself using a
> made up debug map.
>

Sounds pretty good.

I certainly find it a bit more readable in this way (less checking, closer
to the code, etc). It's still got a fair few cases, but not very out of
character with other test cases we have.

Would it be possible/reasonable to interleave the CHECK lines with the
source code? Would save you having to have comments to describe the types
next to the CHECK lines - they'd be self documenting. You might have to
orchestrate the type emission order to match the source order with a bit of
finagling?

Some of your name checks are CHECK-NEXT after the TAG_*_type, while others
use CHECK-NOT: NULL, then CHECK: for the name (presumably because there are
attributes between the TAG and the name) - perhaps use the more general
form for consistency & resilience to unimportant changes in attribute
output from the tool?

It /might/ be smaller CHECK if you shared the checks for the variables and
their types in 'foo' (putting them under CHECK, rather than ODR/NOODR) - to
do that you'd need to use ODR/NOODR to check their original names.

Something like:

/* first CU */
ODR: [[X]] structure_type
NOODR: [[FIRST_X]] structure_type
CHECK: name "foo"
...
/* second CU */
NOODR: [[X]] structure_type
NOODR: name "foo"

CHECK: variable
CHECK: type [[X]]

(this is only relevant because you aren't CHECKing the types of the
variables in the first CU - which is OK, I suppose - they don't seem too
interesting?) Not sure how much, if at all, better that might be?

How's the tool handle the duplicate 'foo' function (that would be a link
error in the actual object link)?


> Other tests really requiring 2 or more object files would use what you
> suggested with eg #ifdef FILE1/FILE2.
>

*nod* those were the ones I was sort of interested to see if/how they were,
but at least the above seems like a good targeted test for the common
cases, at least. Provide the common foundation & then the interesting
things in separate tests, perhaps.


> I still want my higher-level integration tests, but I’ll find another spot
> than LLVM for these :-)
>

Fair enough - might be worth making them fully end-to-end, from clang
through to dlsym, etc.


>
>
>
>
> Fred
>
>
> On Jul 27, 2015, at 2:47 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>
>
> On Mon, Jul 27, 2015 at 2:25 PM, Frédéric Riss <friss at apple.com> wrote:
>
>>
>> On Jul 27, 2015, at 1:03 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>
>>
>>
>> On Mon, Jul 27, 2015 at 12:33 PM, Frédéric Riss <friss at apple.com> wrote:
>>
>>> Reordering a bit the questions, because understanding the answer to the
>>> last one is pretty crucial.
>>>
>>> The reason I did everything together, is to avoid recompiling odr1.ll
>>>> multiple times and to avoid having to pattern match the contents of the
>>>> DWARF for that file in every test. The story of the test in odr-1.test is:
>>>>
>>>> - compile all the odr[1-7].ll files into object files
>>>> - using a dummy debug map,
>>>>
>>>
>>> What's a debug map?
>>>
>>>
>>> The debug map is the main input to the dwarf linker. It’s how it’s
>>> called in the Darwin world, but the concept is pretty generic. It’s the
>>> list of all the linked objects, and for each of these the list of linked
>>> symbols (along with the link addresses). Usually, the debug map in embedded
>>> into the executable by the linker in STABS format (it’s read inside
>>> MachODebugMapParser.cpp in llvm-dsymutil). For testing llvm-dsymutil (but
>>> also for help diagnosing issues in the field) I made the debug map
>>> serializable in YAML. And these days, I’m using mostly YAML based debug
>>> maps to test llvm-dsymutil.
>>> You can’t just say link foo.o and bar.o together, because the linker
>>> might have thrown some symbols away. These symbols (and their
>>> dependencies)) must be stripped from the debug info.
>>>
>>
>> Would it be worth it/handy to have a mapless mode for easy testing that
>> just assumes nothing was thrown away?
>>
>>
>> Possibly, but you’d still need a way to communicate which objects to link.
>>
>
> I was thinking something like "if there are object files specified, link
> them all together with a default map" (& treat any map files as normal,
> ignoring any object files specified on the command line, etc) - but I know
> very little about dlsym or its command line interface.
>
>
>> I could add command line options for that purpose. I’ll think about it.
>>
>> On Jul 24, 2015, at 11:22 AM, David Blaikie <dblaikie at gmail.com> wrote:
>>> On Tue, Jul 21, 2015 at 5:02 PM, Frédéric Riss <friss at apple.com> wrote:
>>>
>>>>
>>>> On Jul 21, 2015, at 4:05 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>>>
>>>>
>>>>
>>>> On Tue, Jul 21, 2015 at 3:41 PM, Frederic Riss <friss at apple.com> wrote:
>>>>
>>>>> Author: friss
>>>>> Date: Tue Jul 21 17:41:43 2015
>>>>> New Revision: 242847
>>>>>
>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=242847&view=rev
>>>>> Log:
>>>>> [dsymutil] Implement ODR uniquing for C++ code.
>>>>>
>>>>> This optimization allows the DWARF linker to reuse definition of
>>>>> types it has emitted in previous CUs rather than reemitting them
>>>>> in each CU that references them. The size and link time gains are
>>>>> huge. For example when linking the DWARF for a debug build of
>>>>> clang, this generates a ~150M dwarf file instead of a ~700M one
>>>>> (the numbers date back a bit and must not be totally accurate
>>>>> these days).
>>>>>
>>>>> As with all the other parts of the llvm-dsymutil codebase, the
>>>>> goal is to keep bit-for-bit compatibility with dsymutil-classic.
>>>>> The code is littered with a lot of FIXMEs that should be
>>>>> addressed once we can get rid of the compatibilty goal.
>>>>>
>>>>
>>>> Did dsymutil-classic do this ODR uniquing too? (not quite clear to me
>>>> from your description here - where you mention compatibility, etc) How does
>>>> its implementation compare?
>>>>
>>>>
>>>> Yes it existed, but it wasn’t enabled by default before Xcode 7 (I
>>>> actually wonder if it found its way into any previous release). But it was
>>>> definitely there when I started llvm-dsymutil. The dsymutil-classic and
>>>> llvm-dsymutil that come with Xcode 7 have it both enabled by default and
>>>> should be bit-for-bit compatible (this has been tested for every dSYM
>>>> bundle that our internal build system generates).
>>>>
>>>
>>> Do you mean bit-for-bit identical? Or compatible in some way (such as
>>> "doesn't require changes to the debug info consumers on the platform" to
>>> pass <some tests>?)? Or something else?
>>>
>>>
>>> Bit-for-bit identical. At least for a start. That’s how we tested that
>>> there would be no regression for users (It allowed to compare outputs using
>>> a simple ‘cpp’ command. Otherwise comparing debug-info is really hard). We
>>> tested the bit-for-bit compatibility on all the internal codebases for both
>>> OS X and iOS. I want to keep that goal for now, as I’d like to be able to
>>> relaunch one such validation campaign once I have everything upstreamed.
>>> After that I can start breaking compatibility and removing the FIXMEs in
>>> the code.
>>>
>>>
>>>>
>>>>> Added:
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll
>>>>>
>>>>
>>>> Might be useful to have more distinguishing names for the test files
>>>> here? (I assume each ODR test only needs two files - or do some need more
>>>> than that?)
>>>>
>>>>
>>>> The tests are mostly between what’s in odr1.o and each every other file.
>>>>
>>>>
>>>
>>> So parts of odr1 are used in various odin?
>>>
>>>
>>> Yes. odr1, is first used again itself (using a forged debug map) to see
>>> that everything gets unique. Then the various other odr* files are linked
>>> to test special cases that needed to be in different files.
>>>
>>> (side note: why is the IR checked in, rather than built object files?
>>> Given that the C++ source is provided, does the IR provide much else here?)
>>>
>>>
>>> I’m pretty proud of that :-) I think that if we can avoid committing
>>> binaries, we should do so.
>>>
>>
>> In general, I agree.
>>
>>
>>> I have a bunch of binaries checked in, because there are things you just
>>> can’t test without that, but for most tests now I prefer to generate the
>>> object files from IR. Some of the other advantages I see:
>>>  - These are easier to augment with new cases (when I modify the ODR
>>> implementation or when we find bugs).
>>>
>>
>> How so? You still have to update the source code, regenerate the IR and
>> regenerate the object files? Not having the IR checked in seems like it'd
>> simplify updates to the test cases, not complicate it.
>>
>>
>> The object files aren’t checked in. I generate them within the test from
>> the IR.
>>
>
> Ah, right - sorry, didn't have that all clear in my head.
>
>
>> One thing I definitely want to avoid is updates to checked-in object
>> files.
>>
>
> From my perspective, that's the contract of dlsym "given these object
> files/debug map, expect this output" - testing anything else is out of
> scope & makes the tests brittle.
>
> LLVM isn't perfect about this, for sure - but we generally try to isolate
> tests to make debugging and updating tests easier. The IR parser/writer are
> certainly an exception - but testing the whole codegen/debug info
> generation path when testing dlsym. The same reason we don't test debug
> info object output in Clang, for example - we just test that the right IR
> came out. (& don't test LLVM's behavior on Clang's (live) output in LLVM's
> tests - which is a more accurate comparison & the project structure
> enforces that separation, but it'd be an intentional choice, even if it
> weren't blocked by that boundary)
>
>
>>
>>  - debug info IR changes will be tested right-away with llvm-dsymutil
>>>
>>
>> This, I think, is unfortunate - debug info IR should be tested in LLVM.
>> Having it exposed elsewhere makes it brittle when updating things - it
>> means updates to LLVM IR break the dsymutil tests when dsymutil doesn't
>> actually depend on the textual IR at all.
>>
>>
>> llvm-dsymutil might not care about the textual IR, but it obviously cares
>> about the emitted DWARF.
>>
>
> As LLVM cares about Clang's IR output (for debug info or just all the
> normal code generation). Yet we test separately up to that boundary in
> Clang, and beyond the boundary in LLVM - not across the boundary.
>
>
>>  I’m not only thinking about updates to the textual IR, but also for
>> example changes in the order we emit things, or in the type of relocations
>> we emit, adding a new DW_AT_artificial to some member, … (i.e.. I care more
>> about semantics than syntax). Regenerating the object file with llc allows
>> these kind of (semantic) changes to be directly tested by one of the
>> consumers of debug info. My thinking is that I don’t want some addition to
>> our debug info representation to break dsymutil without it getting noticed.
>> Of course I’m happy to handle any fallout of such changes, but I want to be
>> able to make sure that they don’t actually matter.
>>
>>
>>
>>>  - It makes it pretty clear what’s in the output. While a discrepancy
>>> between the source and the IR can happen, the IR makes it clear what to
>>> expect in the .o file without resorting to any binary inspection tool.
>>>
>>
>> Perhaps - but if there are discrepancies between the source and object,
>> then equally there can be discrepancies between IR and object - adding
>> another input to "vote" on which is correct doesn't seem like it adds a lot
>> of value.
>>
>>
>>> I'm wondering if we could use a more isolated approach rather than test
>>> cases that seem to exercise several different things across many files.
>>> Something more like:
>>>
>>> // The checked in object files were produced by:
>>> // compile -DOTHER -o testname-a.o
>>> // compile testname-b.o
>>> // CHECK: dsymutil testname-a.o testname-b.o | dwarfdump | FileCheck
>>>
>>> struct foo {
>>> };
>>> namespace {
>>> struct bar {
>>> }
>>> };
>>>
>>> #ifdef OTHER
>>> foo f1;
>>> bar b1;
>>> #else
>>> foo f2;
>>> bar b2;
>>> #endif
>>>
>>> // CHECK: that foo is defined once, bar is defined twice, and
>>> f1/b1/f2/b2 reference those definitions
>>>
>>>
>>> dsymutil doesn’t take .o files as input, but a debug map. I chose to put
>>> the CHECK lines in the debug map because I think it make more sense there
>>> (And use only one test file to avoid having to re-match the contents of
>>> odr1.o in every test).
>>>
>>
>> I'm suggesting not having a universal file like odr1 - by having the
>> source near the check lines and only having the relevant source for each
>> test case there wouldn't be so much redundant matching so it'd be easy-ish
>> to have them separated.
>>
>>
>> While I see your point, I think there’s not too much to split. The types
>> being declared in the same file is part of the test. I wanted a single
>> global context that contains types with the same name (here mostly S and C)
>> redefined in multiple contexts with different meanings (::S, ::N::C,
>> ::N::N::C, ::U::S, ::U::C) to make sure that dsymutil doesn’t confuse them.
>>
>
> Sure - but this kind of broad testing can make tests hard to
> follow/understand. Is there something about the design of your code that
> means, for example, the ::N::N::C case is interesting? What's the
> interesting codepath that that covers that isn't covered by ::N::C? (or
> ::C/::S?)
>
> By having each test case separated, to some degree (certainly in LLVM and
> Clang we have test files with multiple test cases - but, usually, we can
> keep the input and the expected output (CHECK) lines together (debug info
> tests don't fit this model perfectly - which is why we tend towards more
> fine-grained debug info tests (and debug info metadata or DWARF is verbose,
> so having lots in one file becomes unweildy))) it can be easier to
> understand the justification for each one rather than "here's a whole bunch
> of stuff that should be correct".
>
>
>> As to having the comments closer the the source, more on that bellow.
>>
>> I found no way to put the debug map in the same file as any of the other
>>> inputs (I definitely thought about that, but the only thing that came to
>>> mind was to invent some container format to package IR and YAML together.)
>>>
>>
>> Could possibly use a common, single debug map that just lists a single
>> symbol that's in all files? (I guess not, because you wanted to test things
>> like implicit ctors, etc - in which case see the earlier question about
>> possibly having a test-convenience no-map version that just assumes all
>> symbols are emitted?)
>>
>>
>> odr-1.test is basically that single debug map you’re referring to. It
>> lists all the files and the interesting symbols in each of them.
>>
>
> Right, sorry, I meant a single debug map that would be the same for every
> file/test, so it would be uninteresting background like "oh, every test
> includes a 'foo' function, because that's the debug info anchor point".
>
>
>>
>> In any case, even if the maps were included - they seem incidental/mostly
>> a side-effect, not the core thing that's being tested, so keeping the CHECK
>> lines near the source/features being tested would make the tests easier for
>> me to read, at least.
>>
>>
>> I agree that the maps aren’t what is being tested. But at least they are
>> part of the link process. The alternative would be to put the sources in
>> the test directory and the maps in the Inputs directory.
>>
>
> Strangely, that may be more consistent (especially if you end up with
> checked in object files) - the map is the input to the linker, not the
> object files. But that's just a silly technicality/semantic argument.
>
>
>> It just seemed much more logical to me to have the sources alongside
>> their derived IR files in the Inputs directory and to use the map (that’s
>> actually part of the link command) as the test file. But I’m not against
>> changing that. I’d need to play around with the idea to see how the tests
>> look like. It just seems odd to have the source in the test directory and
>> the IR in the Inputs directory. I’d need to add a comment to the generated
>> IRs to point to the location of the source.
>>
>
> If they're consistently named, I wouldn't worry about adding comments
> (foo.cpp, Inputs/foo-1.ll, Inputs/foo-2.ll) I think we have test cases like
> this, for example, for LTO debug info in LLVM maybe?
>
>
>>
>>
>>> (or this could even be two separate tests, one for anonymous namespaced
>>> types, one for external types, etc - same sort of thing we do in other
>>> tests, where we group some related things together, but while keeping more
>>> of the information together so the checks are more legible because you can
>>> see the scenario they're trying to check. Spreading a single set of CHECKs
>>> across 8 files and a header makes it a bit difficult to follow - reading
>>> the CHECK lines and then trying to consult all the files to see what it
>>> should be)
>>>
>>>
>>> As I said above, the link is debug map based, so the CHECK lines are
>>> stored with the YAML debug map. I could have done a few things differently,
>>> but considering that any test for the ODR uniquing involves at least 3
>>> files (2 object files and the debug map), I did my best to keep things as
>>> condensed as possible.
>>>
>>>
>>>
>>>> Some of them require more though for example odr6 and 7 (see specifics
>>>> below) are separate on purpose, because want to check that the result of
>>>> the odr7 link didn’t reuse the odr6 results.
>>>>
>>>> I see it's all in odr-1.test - it's a bit monolithic, isn't it? I'm not
>>>> sure I understand the motivation for 7 different inputs and then checking
>>>> all together. Could you explain it?
>>>>
>>>>
>>>> You can see in the name (odr-*1*.test) that I initially planned on
>>>> having multiple tests. However, I found it easier to put everything in the
>>>> same file (which is big, I agree, but it’s also pretty well commented if
>>>> one understands what it’s talking about :-)).
>>>>
>>>
>>> The big test file says things like "this is class N::C" - that doesn't
>>> mean much to me as a reader without going through all the source files to
>>> see how it is used and referenced.
>>>
>>> "this is a lambda inside func" - if I could see the source, that would
>>> be helpful. But as it is I don't know what interesting property you're
>>> trying to test for in that thing - that it's not duplicated? That it is?
>>>
>>>
>>> Reading linearly through the test file, the comments and structure read
>>> this way:
>>> # Totally made up debug map to test ODR uniquing
>>> <debug map part pulling odr1.o>
>>> # Check that all our types are in the first CU.
>>> < DWARF matching for odr1 CU>
>>> # This is "struct S”
>>> < DWARF for struct S>
>>> # This is "class N::C"
>>> < DWARF for N::C>
>>> # This is "class N::N::C"
>>> < DWARF for N::N::C>
>>> # This is "AliasForS"
>>> < DWARF for AliasForS>
>>> < DWARF and comments for the rest of odr1.o>
>>>
>>> < Debug map part pulling in odr1.o again>
>>> # We relink the same file a second time. In the ODR case, everything
>>> (except for the
>>> # union for now) should be uniqued. In the non-ODR case, we should get
>>> every type
>>> # duplicated.
>>> < DWARF and comments for the uniqued version of odr1.o
>>>
>>> < debug map pulling in odr2.o and odr3.o>
>>> # odr2.cpp and odr3.cpp test that a simple overloaded function doesn't
>>> break the
>>> # uniquing (contrary to what we'll see with template/artificial)
>>> functions.
>>> < DWARF for odr2 and odr3>
>>>
>>> <etc…>
>>>
>>> I honestly think these are pretty awesome comments.
>>>
>>
>> As a new reader to this file - how do you make sense of the checks and
>> their comments? It's pretty hard to tell what the entities are that the
>> comments are referring to. For example:
>>
>> I'm not sure why there's a double-nested namespace N (what codepath does
>> that test that a single level of namespacing (or none?) wouldn't?)
>>
>>
>> As I said above this is more above not confusing something called N::C in
>> 2 different contexts. To be honest, the types in odr1 were mostly about
>> getting a bit of every unique-able stuff, while the tests in odr2-7 are
>> more about getting code coverage of corner cases.
>>
>
> Which is perhaps adding to the confusion I'm having - the types are used
> for multiple things so they may have superfluous features for one thing or
> the other, which adds complexity when trying to understand one particular
> test case in isolation.
>
>
>>
>> The descriptions of code in the comments seem like they're a stand-in for
>> being able to read the code itself/having it nearby. Mostly the code is
>> short enough that if it were nearby it'd be fairly self documenting, or at
>> least add a bit of extra detail in cases where the comments may not be
>> sufficient.
>>
>>
>> And I’ll try to play with that idea. I’m just interested in your feeling
>> about the source vs derived files location thing.
>>
>> (side note, while looking through the comments I came across "contrary
>> to what we'll see with template/artificial" - I guess what you want there
>> is "contrary to what we'll see with inline functions" (implicit special
>> members and implicit template specializations are interesting ways that
>> inline functions arise - but normal inline functions are the more
>> obvious/common case and the term "inline function" describes all of these
>> things)?)
>>
>>
>> For templates and implicit special members, their DW_TAG_subprogram will
>> only be added to the type when they are codegened (generating a new
>> non-uniquable version of the type in the process). I would have expected
>> the DISubprogram for an inline member to be included in the type (but not
>> referenced by any DW_AT_specification in that CU), but maybe I’m wrong?
>>
>
> Ah, no, you're right - if it's specifically about member functions, not
> free functions - implicit special members, implicit member function
> template specializations.
>
> You might want to also add nested types to that? Check the debug info for
> something like this:
>
> struct foo {
> struct bar;
> };
>
> ...
>
> struct foo::bar { // put this in one file using 'foo' and link it with
> another file (without this definition) that also uses 'foo'
> };
>
>
>
>
>>
>> Just trying to describe how I read/look at this test & the difficulties I
>> find with understanding it... perhaps other people have other ideas about
>> the ease with which they can understand them.
>>
>>
>> And I’m happy to take your feedback into account :-)
>>
>> Fred
>>
>> - David
>>
>>
>>> As for all the other tests, you need some really good understanding of
>>> what’s supposed to go on in the first place though. But I definitely
>>> invested time in trying to make them more palatable.
>>>
>>> Fred
>>>
>>>
>>>
>>>> The reason I did everything together, is to avoid recompiling odr1.ll
>>>> multiple times and to avoid having to pattern match the contents of the
>>>> DWARF for that file in every test. The story of the test in odr-1.test is:
>>>>
>>>> - compile all the odr[1-7].ll files into object files
>>>> - using a dummy debug map,
>>>>
>>>
>>> What's a debug map?
>>>
>>>
>>>> link all these together (including linking odr1.o twice) once with ODR
>>>> uniquing and once without
>>>> - The odr1.ll file instantiates all the types contained in odr-types.h,
>>>> thus its debug info will contain all the definitions. This is basically the
>>>> ODR context pool that should be reused
>>>> - Then the other odr*.ll that have been linked are tested like this:
>>>>   * odr1.o is linked a second time, and I check that no types (except
>>>> for one corner case) have been duplicated and that everything links to the
>>>> first CU
>>>>   * odr2.o and odr3.o both instantiate a different version of an
>>>> overloaded inline function. We test that both these CUs do not contain a
>>>> copy of the corresponding type and that uniquing was applied correctly.
>>>>   * odr4.o checks that we do not unique different thing with the same
>>>> name inside anonymous namespaces
>>>>   * odr5.o and odr6.o are similar to 2/3, except that they instantiate
>>>> a template member function. These ones can’t be uniqued with the content in
>>>> odr1.o because the type is extended with a different member function each
>>>> time.
>>>>   * odr7.o checks that we can correctly reference directly a nested
>>>> type.
>>>>
>>>> I could definitely merge some of the unrelated ones together (say 2 4
>>>> and 7), it just seemed nice that each one tackled a slightly different
>>>> issue. I could have named them according to their contents though. Would
>>>> you like that I rename them? Or I could merge some of them, but then
>>>> renaming make less sense.
>>>>
>>>> Fred
>>>>
>>>> - Dave
>>>>
>>>>
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr7.cpp
>>>>>     llvm/trunk/test/tools/dsymutil/Inputs/odr7.ll
>>>>>     llvm/trunk/test/tools/dsymutil/X86/odr-1.test
>>>>> Modified:
>>>>>     llvm/trunk/tools/dsymutil/DwarfLinker.cpp
>>>>>     llvm/trunk/tools/dsymutil/dsymutil.cpp
>>>>>     llvm/trunk/tools/dsymutil/dsymutil.h
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr-types.h Tue Jul 21
>>>>> 17:41:43 2015
>>>>> @@ -0,0 +1,51 @@
>>>>> +struct S {
>>>>> +       int I;
>>>>> +
>>>>> +       void incr() __attribute__((always_inline)) { I++; }
>>>>> +       void incr(int Add) __attribute__((always_inline)) { I += Add; }
>>>>> +
>>>>> +       typedef int SInt;
>>>>> +
>>>>> +       struct Nested {
>>>>> +               double D;
>>>>> +
>>>>> +               template<typename T> void init(T Val) { D =
>>>>> double(Val); }
>>>>> +       };
>>>>> +
>>>>> +       Nested D;
>>>>> +
>>>>> +public:
>>>>> +       int foo() { return I; }
>>>>> +};
>>>>> +
>>>>> +typedef S AliasForS;
>>>>> +
>>>>> +namespace N {
>>>>> +class C {
>>>>> +       AliasForS S;
>>>>> +};
>>>>> +}
>>>>> +
>>>>> +namespace N {
>>>>> +namespace N {
>>>>> +class C {
>>>>> +        int S;
>>>>> +};
>>>>> +}
>>>>> +}
>>>>> +
>>>>> +namespace {
>>>>> +       class AnonC {
>>>>> +       };
>>>>> +}
>>>>> +
>>>>> +union U {
>>>>> +       class C {} C;
>>>>> +       struct S {} S;
>>>>> +};
>>>>> +
>>>>> +inline int func() {
>>>>> +       struct CInsideFunc { int i; };
>>>>> +       auto functor = []() { CInsideFunc dummy; return dummy.i; };
>>>>> +       return functor();
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr1.cpp Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,11 @@
>>>>> +#include "odr-types.h"
>>>>> +
>>>>> +int foo() {
>>>>> +       AliasForS s;
>>>>> +       N::C nc;
>>>>> +       N::N::C nnc;
>>>>> +       AnonC ac;
>>>>> +       U u;
>>>>> +
>>>>> +       return func();
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr1.ll Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,153 @@
>>>>> +; Generated from odr1.cpp and odr-types.h by running:
>>>>> +; clang -emit-llvm -g -S -std=c++11 odr1.cpp
>>>>> +; ModuleID = 'odr1.cpp'
>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>> +target triple = "x86_64-apple-macosx10.11.0"
>>>>> +
>>>>> +%struct.S = type { i32, %"struct.S::Nested" }
>>>>> +%"struct.S::Nested" = type { double }
>>>>> +%"class.N::C" = type { %struct.S }
>>>>> +%"class.N::N::C" = type { i32 }
>>>>> +%"class.(anonymous namespace)::AnonC" = type { i8 }
>>>>> +%union.U = type { %"class.U::C" }
>>>>> +%"class.U::C" = type { i8 }
>>>>> +%class.anon = type { i8 }
>>>>> +%struct.CInsideFunc = type { i32 }
>>>>> +
>>>>> +; Function Attrs: ssp uwtable
>>>>> +define i32 @_Z3foov() #0 {
>>>>> +entry:
>>>>> +  %s = alloca %struct.S, align 8
>>>>> +  %nc = alloca %"class.N::C", align 8
>>>>> +  %nnc = alloca %"class.N::N::C", align 4
>>>>> +  %ac = alloca %"class.(anonymous namespace)::AnonC", align 1
>>>>> +  %u = alloca %union.U, align 1
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !59,
>>>>> metadata !60), !dbg !61
>>>>> +  call void @llvm.dbg.declare(metadata %"class.N::C"* %nc, metadata
>>>>> !62, metadata !60), !dbg !63
>>>>> +  call void @llvm.dbg.declare(metadata %"class.N::N::C"* %nnc,
>>>>> metadata !64, metadata !60), !dbg !65
>>>>> +  call void @llvm.dbg.declare(metadata %"class.(anonymous
>>>>> namespace)::AnonC"* %ac, metadata !66, metadata !60), !dbg !69
>>>>> +  call void @llvm.dbg.declare(metadata %union.U* %u, metadata !70,
>>>>> metadata !60), !dbg !71
>>>>> +  %call = call i32 @_Z4funcv(), !dbg !72
>>>>> +  ret i32 %call, !dbg !73
>>>>> +}
>>>>> +
>>>>> +; Function Attrs: nounwind readnone
>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>> +
>>>>> +; Function Attrs: inlinehint ssp uwtable
>>>>> +define linkonce_odr i32 @_Z4funcv() #2 {
>>>>> +entry:
>>>>> +  %functor = alloca %class.anon, align 1
>>>>> +  call void @llvm.dbg.declare(metadata %class.anon* %functor,
>>>>> metadata !74, metadata !60), !dbg !75
>>>>> +  %call = call i32 @_ZZ4funcvENKUlvE_clEv(%class.anon* %functor),
>>>>> !dbg !76
>>>>> +  ret i32 %call, !dbg !77
>>>>> +}
>>>>> +
>>>>> +; Function Attrs: inlinehint nounwind ssp uwtable
>>>>> +define linkonce_odr i32 @_ZZ4funcvENKUlvE_clEv(%class.anon* %this) #3
>>>>> align 2 {
>>>>> +entry:
>>>>> +  %this.addr = alloca %class.anon*, align 8
>>>>> +  %dummy = alloca %struct.CInsideFunc, align 4
>>>>> +  store %class.anon* %this, %class.anon** %this.addr, align 8
>>>>> +  call void @llvm.dbg.declare(metadata %class.anon** %this.addr,
>>>>> metadata !78, metadata !60), !dbg !80
>>>>> +  %this1 = load %class.anon*, %class.anon** %this.addr
>>>>> +  call void @llvm.dbg.declare(metadata %struct.CInsideFunc* %dummy,
>>>>> metadata !81, metadata !60), !dbg !82
>>>>> +  %i = getelementptr inbounds %struct.CInsideFunc,
>>>>> %struct.CInsideFunc* %dummy, i32 0, i32 0, !dbg !83
>>>>> +  %0 = load i32, i32* %i, align 4, !dbg !83
>>>>> +  ret i32 %0, !dbg !84
>>>>> +}
>>>>> +
>>>>> +attributes #0 = { ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +attributes #1 = { nounwind readnone }
>>>>> +attributes #2 = { inlinehint ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +attributes #3 = { inlinehint nounwind ssp uwtable
>>>>> "disable-tail-calls"="false" "less-precise-fpmad"="false"
>>>>> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
>>>>> "no-infs-fp-math"="false" "no-nans-fp-math"="false"
>>>>> "stack-protector-buffer-size"="8" "target-cpu"="core2"
>>>>> "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false"
>>>>> "use-soft-float"="false" }
>>>>> +
>>>>> +!llvm.dbg.cu = !{!0}
>>>>> +!llvm.module.flags = !{!55, !56, !57}
>>>>> +!llvm.ident = !{!58}
>>>>> +
>>>>> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
>>>>> producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false,
>>>>> runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3,
>>>>> subprograms: !52)
>>>>> +!1 = !DIFile(filename: "odr1.cpp", directory: "/Inputs")
>>>>> +!2 = !{}
>>>>> +!3 = !{!4, !20, !24, !29, !33, !37, !38, !39, !49}
>>>>> +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file:
>>>>> !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")
>>>>> +!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")
>>>>> +!6 = !{!7, !9, !10, !14, !17}
>>>>> +!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S",
>>>>> file: !5, line: 2, baseType: !8, size: 32, align: 32)
>>>>> +!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding:
>>>>> DW_ATE_signed)
>>>>> +!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S",
>>>>> file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64,
>>>>> offset: 64)
>>>>> +!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition:
>>>>> false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!11 = !DISubroutineType(types: !12)
>>>>> +!12 = !{null, !13}
>>>>> +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S",
>>>>> size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope:
>>>>> !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition:
>>>>> false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!15 = !DISubroutineType(types: !16)
>>>>> +!16 = !{null, !13, !8}
>>>>> +!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition:
>>>>> false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!18 = !DISubroutineType(types: !19)
>>>>> +!19 = !{!8, !13}
>>>>> +!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
>>>>> scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21,
>>>>> identifier: "_ZTSN1S6NestedE")
>>>>> +!21 = !{!22}
>>>>> +!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope:
>>>>> !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)
>>>>> +!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding:
>>>>> DW_ATE_float)
>>>>> +!24 = !DICompositeType(tag: DW_TAG_class_type, name: "C", scope: !25,
>>>>> file: !5, line: 24, size: 128, align: 64, elements: !26, identifier:
>>>>> "_ZTSN1N1CE")
>>>>> +!25 = !DINamespace(name: "N", scope: null, file: !5, line: 23)
>>>>> +!26 = !{!27}
>>>>> +!27 = !DIDerivedType(tag: DW_TAG_member, name: "S", scope:
>>>>> !"_ZTSN1N1CE", file: !5, line: 25, baseType: !28, size: 128, align: 64)
>>>>> +!28 = !DIDerivedType(tag: DW_TAG_typedef, name: "AliasForS", file:
>>>>> !5, line: 21, baseType: !"_ZTS1S")
>>>>> +!29 = !DICompositeType(tag: DW_TAG_class_type, name: "C", scope: !30,
>>>>> file: !5, line: 31, size: 32, align: 32, elements: !31, identifier:
>>>>> "_ZTSN1N1N1CE")
>>>>> +!30 = !DINamespace(name: "N", scope: !25, file: !5, line: 30)
>>>>> +!31 = !{!32}
>>>>> +!32 = !DIDerivedType(tag: DW_TAG_member, name: "S", scope:
>>>>> !"_ZTSN1N1N1CE", file: !5, line: 32, baseType: !8, size: 32, align: 32)
>>>>> +!33 = !DICompositeType(tag: DW_TAG_union_type, name: "U", file: !5,
>>>>> line: 42, size: 8, align: 8, elements: !34, identifier: "_ZTS1U")
>>>>> +!34 = !{!35, !36}
>>>>> +!35 = !DIDerivedType(tag: DW_TAG_member, name: "C", scope: !"_ZTS1U",
>>>>> file: !5, line: 43, baseType: !"_ZTSN1U1CE", size: 8, align: 8)
>>>>> +!36 = !DIDerivedType(tag: DW_TAG_member, name: "S", scope: !"_ZTS1U",
>>>>> file: !5, line: 44, baseType: !"_ZTSN1U1SE", size: 8, align: 8)
>>>>> +!37 = !DICompositeType(tag: DW_TAG_class_type, name: "C", scope:
>>>>> !"_ZTS1U", file: !5, line: 43, size: 8, align: 8, elements: !2, identifier:
>>>>> "_ZTSN1U1CE")
>>>>> +!38 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", scope:
>>>>> !"_ZTS1U", file: !5, line: 44, size: 8, align: 8, elements: !2, identifier:
>>>>> "_ZTSN1U1SE")
>>>>> +!39 = !DICompositeType(tag: DW_TAG_class_type, scope: !40, file: !5,
>>>>> line: 49, size: 8, align: 8, elements: !43, identifier: "_ZTSZ4funcvEUlvE_")
>>>>> +!40 = !DISubprogram(name: "func", linkageName: "_Z4funcv", scope: !5,
>>>>> file: !5, line: 47, type: !41, isLocal: false, isDefinition: true,
>>>>> scopeLine: 47, flags: DIFlagPrototyped, isOptimized: false, function: i32
>>>>> ()* @_Z4funcv, variables: !2)
>>>>> +!41 = !DISubroutineType(types: !42)
>>>>> +!42 = !{!8}
>>>>> +!43 = !{!44}
>>>>> +!44 = !DISubprogram(name: "operator()", scope: !"_ZTSZ4funcvEUlvE_",
>>>>> file: !5, line: 49, type: !45, isLocal: false, isDefinition: false,
>>>>> scopeLine: 49, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false)
>>>>> +!45 = !DISubroutineType(types: !46)
>>>>> +!46 = !{!8, !47}
>>>>> +!47 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !48, size:
>>>>> 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!48 = !DIDerivedType(tag: DW_TAG_const_type, baseType:
>>>>> !"_ZTSZ4funcvEUlvE_")
>>>>> +!49 = !DICompositeType(tag: DW_TAG_structure_type, name:
>>>>> "CInsideFunc", scope: !40, file: !5, line: 48, size: 32, align: 32,
>>>>> elements: !50, identifier: "_ZTSZ4funcvE11CInsideFunc")
>>>>> +!50 = !{!51}
>>>>> +!51 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope:
>>>>> !"_ZTSZ4funcvE11CInsideFunc", file: !5, line: 48, baseType: !8, size: 32,
>>>>> align: 32)
>>>>> +!52 = !{!53, !40, !54}
>>>>> +!53 = !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1,
>>>>> file: !1, line: 3, type: !41, isLocal: false, isDefinition: true,
>>>>> scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32
>>>>> ()* @_Z3foov, variables: !2)
>>>>> +!54 = !DISubprogram(name: "operator()", linkageName:
>>>>> "_ZZ4funcvENKUlvE_clEv", scope: !"_ZTSZ4funcvEUlvE_", file: !5, line: 49,
>>>>> type: !45, isLocal: false, isDefinition: true, scopeLine: 49, flags:
>>>>> DIFlagPrototyped, isOptimized: false, function: i32 (%class.anon*)*
>>>>> @_ZZ4funcvENKUlvE_clEv, declaration: !44, variables: !2)
>>>>> +!55 = !{i32 2, !"Dwarf Version", i32 2}
>>>>> +!56 = !{i32 2, !"Debug Info Version", i32 3}
>>>>> +!57 = !{i32 1, !"PIC Level", i32 2}
>>>>> +!58 = !{!"clang version 3.8.0 (trunk 242534)"}
>>>>> +!59 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", scope:
>>>>> !53, file: !1, line: 4, type: !28)
>>>>> +!60 = !DIExpression()
>>>>> +!61 = !DILocation(line: 4, column: 12, scope: !53)
>>>>> +!62 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "nc", scope:
>>>>> !53, file: !1, line: 5, type: !"_ZTSN1N1CE")
>>>>> +!63 = !DILocation(line: 5, column: 7, scope: !53)
>>>>> +!64 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "nnc", scope:
>>>>> !53, file: !1, line: 6, type: !"_ZTSN1N1N1CE")
>>>>> +!65 = !DILocation(line: 6, column: 10, scope: !53)
>>>>> +!66 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ac", scope:
>>>>> !53, file: !1, line: 7, type: !67)
>>>>> +!67 = !DICompositeType(tag: DW_TAG_class_type, name: "AnonC", scope:
>>>>> !68, file: !5, line: 38, size: 8, align: 8, elements: !2)
>>>>> +!68 = !DINamespace(scope: null, file: !5, line: 37)
>>>>> +!69 = !DILocation(line: 7, column: 8, scope: !53)
>>>>> +!70 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "u", scope:
>>>>> !53, file: !1, line: 8, type: !"_ZTS1U")
>>>>> +!71 = !DILocation(line: 8, column: 4, scope: !53)
>>>>> +!72 = !DILocation(line: 10, column: 9, scope: !53)
>>>>> +!73 = !DILocation(line: 10, column: 2, scope: !53)
>>>>> +!74 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "functor",
>>>>> scope: !40, file: !5, line: 49, type: !"_ZTSZ4funcvEUlvE_")
>>>>> +!75 = !DILocation(line: 49, column: 7, scope: !40)
>>>>> +!76 = !DILocation(line: 50, column: 9, scope: !40)
>>>>> +!77 = !DILocation(line: 50, column: 2, scope: !40)
>>>>> +!78 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg:
>>>>> 1, scope: !54, type: !79, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!79 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !48, size:
>>>>> 64, align: 64)
>>>>> +!80 = !DILocation(line: 0, scope: !54)
>>>>> +!81 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "dummy",
>>>>> scope: !54, file: !5, line: 49, type: !"_ZTSZ4funcvE11CInsideFunc")
>>>>> +!82 = !DILocation(line: 49, column: 36, scope: !54)
>>>>> +!83 = !DILocation(line: 49, column: 56, scope: !54)
>>>>> +!84 = !DILocation(line: 49, column: 43, scope: !54)
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr2.cpp Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,7 @@
>>>>> +#include "odr-types.h"
>>>>> +
>>>>> +int bar() {
>>>>> +       S s;
>>>>> +       s.incr();
>>>>> +       return s.foo();
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr2.ll Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,99 @@
>>>>> +; Generated from odr2.cpp and odr-types.h by running:
>>>>> +; clang -emit-llvm -g -S -std=c++11 odr2.cpp
>>>>> +; ModuleID = 'odr2.cpp'
>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>> +target triple = "x86_64-apple-macosx10.11.0"
>>>>> +
>>>>> +%struct.S = type { i32, %"struct.S::Nested" }
>>>>> +%"struct.S::Nested" = type { double }
>>>>> +
>>>>> +; Function Attrs: ssp uwtable
>>>>> +define i32 @_Z3barv() #0 {
>>>>> +entry:
>>>>> +  %this.addr.i = alloca %struct.S*, align 8
>>>>> +  %s = alloca %struct.S, align 8
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !34,
>>>>> metadata !35), !dbg !36
>>>>> +  store %struct.S* %s, %struct.S** %this.addr.i, align 8, !dbg !37
>>>>> +  %this1.i = load %struct.S*, %struct.S** %this.addr.i, !dbg !37
>>>>> +  %I.i = getelementptr inbounds %struct.S, %struct.S* %this1.i, i32
>>>>> 0, i32 0, !dbg !38
>>>>> +  %0 = load i32, i32* %I.i, align 4, !dbg !40
>>>>> +  %inc.i = add nsw i32 %0, 1, !dbg !40
>>>>> +  store i32 %inc.i, i32* %I.i, align 4, !dbg !40
>>>>> +  %call = call i32 @_ZN1S3fooEv(%struct.S* %s), !dbg !41
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S** %this.addr.i,
>>>>> metadata !42, metadata !35), !dbg !44
>>>>> +  ret i32 %call, !dbg !45
>>>>> +}
>>>>> +
>>>>> +; Function Attrs: nounwind readnone
>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>> +
>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>> +define linkonce_odr i32 @_ZN1S3fooEv(%struct.S* %this) #2 align 2 {
>>>>> +entry:
>>>>> +  %this.addr = alloca %struct.S*, align 8
>>>>> +  store %struct.S* %this, %struct.S** %this.addr, align 8
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S** %this.addr,
>>>>> metadata !46, metadata !35), !dbg !47
>>>>> +  %this1 = load %struct.S*, %struct.S** %this.addr
>>>>> +  %I = getelementptr inbounds %struct.S, %struct.S* %this1, i32 0,
>>>>> i32 0, !dbg !48
>>>>> +  %0 = load i32, i32* %I, align 4, !dbg !48
>>>>> +  ret i32 %0, !dbg !49
>>>>> +}
>>>>> +
>>>>> +attributes #0 = { ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +attributes #1 = { nounwind readnone }
>>>>> +attributes #2 = { nounwind ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +
>>>>> +!llvm.dbg.cu = !{!0}
>>>>> +!llvm.module.flags = !{!30, !31, !32}
>>>>> +!llvm.ident = !{!33}
>>>>> +
>>>>> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
>>>>> producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false,
>>>>> runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3,
>>>>> subprograms: !24)
>>>>> +!1 = !DIFile(filename: "odr2.cpp", directory: "/Inputs")
>>>>> +!2 = !{}
>>>>> +!3 = !{!4, !20}
>>>>> +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file:
>>>>> !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")
>>>>> +!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")
>>>>> +!6 = !{!7, !9, !10, !14, !17}
>>>>> +!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S",
>>>>> file: !5, line: 2, baseType: !8, size: 32, align: 32)
>>>>> +!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding:
>>>>> DW_ATE_signed)
>>>>> +!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S",
>>>>> file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64,
>>>>> offset: 64)
>>>>> +!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition:
>>>>> false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!11 = !DISubroutineType(types: !12)
>>>>> +!12 = !{null, !13}
>>>>> +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S",
>>>>> size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope:
>>>>> !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition:
>>>>> false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!15 = !DISubroutineType(types: !16)
>>>>> +!16 = !{null, !13, !8}
>>>>> +!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition:
>>>>> false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!18 = !DISubroutineType(types: !19)
>>>>> +!19 = !{!8, !13}
>>>>> +!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
>>>>> scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21,
>>>>> identifier: "_ZTSN1S6NestedE")
>>>>> +!21 = !{!22}
>>>>> +!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope:
>>>>> !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)
>>>>> +!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding:
>>>>> DW_ATE_float)
>>>>> +!24 = !{!25, !28, !29}
>>>>> +!25 = !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1,
>>>>> file: !1, line: 3, type: !26, isLocal: false, isDefinition: true,
>>>>> scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32
>>>>> ()* @_Z3barv, variables: !2)
>>>>> +!26 = !DISubroutineType(types: !27)
>>>>> +!27 = !{!8}
>>>>> +!28 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition:
>>>>> true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false,
>>>>> declaration: !10, variables: !2)
>>>>> +!29 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition:
>>>>> true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, function:
>>>>> i32 (%struct.S*)* @_ZN1S3fooEv, declaration: !17, variables: !2)
>>>>> +!30 = !{i32 2, !"Dwarf Version", i32 2}
>>>>> +!31 = !{i32 2, !"Debug Info Version", i32 3}
>>>>> +!32 = !{i32 1, !"PIC Level", i32 2}
>>>>> +!33 = !{!"clang version 3.8.0 (trunk 242534)"}
>>>>> +!34 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", scope:
>>>>> !25, file: !1, line: 4, type: !"_ZTS1S")
>>>>> +!35 = !DIExpression()
>>>>> +!36 = !DILocation(line: 4, column: 4, scope: !25)
>>>>> +!37 = !DILocation(line: 5, column: 2, scope: !25)
>>>>> +!38 = !DILocation(line: 4, column: 47, scope: !28, inlinedAt: !39)
>>>>> +!39 = distinct !DILocation(line: 5, column: 2, scope: !25)
>>>>> +!40 = !DILocation(line: 4, column: 48, scope: !28, inlinedAt: !39)
>>>>> +!41 = !DILocation(line: 6, column: 9, scope: !25)
>>>>> +!42 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg:
>>>>> 1, scope: !28, type: !43, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!43 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S",
>>>>> size: 64, align: 64)
>>>>> +!44 = !DILocation(line: 0, scope: !28, inlinedAt: !39)
>>>>> +!45 = !DILocation(line: 6, column: 2, scope: !25)
>>>>> +!46 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg:
>>>>> 1, scope: !29, type: !43, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!47 = !DILocation(line: 0, scope: !29)
>>>>> +!48 = !DILocation(line: 18, column: 21, scope: !29)
>>>>> +!49 = !DILocation(line: 18, column: 14, scope: !29)
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr3.cpp Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,7 @@
>>>>> +#include "odr-types.h"
>>>>> +
>>>>> +int bar() {
>>>>> +       S s;
>>>>> +       s.incr(42);
>>>>> +       return s.foo();
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr3.ll Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,106 @@
>>>>> +; Generated from odr3.cpp and odr-types.h by running:
>>>>> +; clang -emit-llvm -g -S -std=c++11 odr3.cpp
>>>>> +; ModuleID = 'odr3.cpp'
>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>> +target triple = "x86_64-apple-macosx10.11.0"
>>>>> +
>>>>> +%struct.S = type { i32, %"struct.S::Nested" }
>>>>> +%"struct.S::Nested" = type { double }
>>>>> +
>>>>> +; Function Attrs: ssp uwtable
>>>>> +define i32 @_Z3barv() #0 {
>>>>> +entry:
>>>>> +  %this.addr.i = alloca %struct.S*, align 8
>>>>> +  %Add.addr.i = alloca i32, align 4
>>>>> +  %s = alloca %struct.S, align 8
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S* %s, metadata !34,
>>>>> metadata !35), !dbg !36
>>>>> +  store %struct.S* %s, %struct.S** %this.addr.i, align 8, !dbg !37
>>>>> +  store i32 42, i32* %Add.addr.i, align 4, !dbg !37
>>>>> +  %this1.i = load %struct.S*, %struct.S** %this.addr.i, !dbg !37
>>>>> +  %0 = load i32, i32* %Add.addr.i, align 4, !dbg !38
>>>>> +  %I.i = getelementptr inbounds %struct.S, %struct.S* %this1.i, i32
>>>>> 0, i32 0, !dbg !40
>>>>> +  %1 = load i32, i32* %I.i, align 4, !dbg !41
>>>>> +  %add.i = add nsw i32 %1, %0, !dbg !41
>>>>> +  store i32 %add.i, i32* %I.i, align 4, !dbg !41
>>>>> +  %call = call i32 @_ZN1S3fooEv(%struct.S* %s), !dbg !42
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S** %this.addr.i,
>>>>> metadata !43, metadata !35), !dbg !45
>>>>> +  call void @llvm.dbg.declare(metadata i32* %Add.addr.i, metadata
>>>>> !46, metadata !35), !dbg !47
>>>>> +  ret i32 %call, !dbg !48
>>>>> +}
>>>>> +
>>>>> +; Function Attrs: nounwind readnone
>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>> +
>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>> +define linkonce_odr i32 @_ZN1S3fooEv(%struct.S* %this) #2 align 2 {
>>>>> +entry:
>>>>> +  %this.addr = alloca %struct.S*, align 8
>>>>> +  store %struct.S* %this, %struct.S** %this.addr, align 8
>>>>> +  call void @llvm.dbg.declare(metadata %struct.S** %this.addr,
>>>>> metadata !49, metadata !35), !dbg !50
>>>>> +  %this1 = load %struct.S*, %struct.S** %this.addr
>>>>> +  %I = getelementptr inbounds %struct.S, %struct.S* %this1, i32 0,
>>>>> i32 0, !dbg !51
>>>>> +  %0 = load i32, i32* %I, align 4, !dbg !51
>>>>> +  ret i32 %0, !dbg !52
>>>>> +}
>>>>> +
>>>>> +attributes #0 = { ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +attributes #1 = { nounwind readnone }
>>>>> +attributes #2 = { nounwind ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +
>>>>> +!llvm.dbg.cu = !{!0}
>>>>> +!llvm.module.flags = !{!30, !31, !32}
>>>>> +!llvm.ident = !{!33}
>>>>> +
>>>>> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
>>>>> producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false,
>>>>> runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3,
>>>>> subprograms: !24)
>>>>> +!1 = !DIFile(filename: "odr3.cpp", directory: "/Inputs")
>>>>> +!2 = !{}
>>>>> +!3 = !{!4, !20}
>>>>> +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file:
>>>>> !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")
>>>>> +!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")
>>>>> +!6 = !{!7, !9, !10, !14, !17}
>>>>> +!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S",
>>>>> file: !5, line: 2, baseType: !8, size: 32, align: 32)
>>>>> +!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding:
>>>>> DW_ATE_signed)
>>>>> +!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S",
>>>>> file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64,
>>>>> offset: 64)
>>>>> +!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition:
>>>>> false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!11 = !DISubroutineType(types: !12)
>>>>> +!12 = !{null, !13}
>>>>> +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S",
>>>>> size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope:
>>>>> !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition:
>>>>> false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!15 = !DISubroutineType(types: !16)
>>>>> +!16 = !{null, !13, !8}
>>>>> +!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition:
>>>>> false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!18 = !DISubroutineType(types: !19)
>>>>> +!19 = !{!8, !13}
>>>>> +!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
>>>>> scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21,
>>>>> identifier: "_ZTSN1S6NestedE")
>>>>> +!21 = !{!22}
>>>>> +!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope:
>>>>> !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)
>>>>> +!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding:
>>>>> DW_ATE_float)
>>>>> +!24 = !{!25, !28, !29}
>>>>> +!25 = !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1,
>>>>> file: !1, line: 3, type: !26, isLocal: false, isDefinition: true,
>>>>> scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32
>>>>> ()* @_Z3barv, variables: !2)
>>>>> +!26 = !DISubroutineType(types: !27)
>>>>> +!27 = !{!8}
>>>>> +!28 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope:
>>>>> !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition:
>>>>> true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false,
>>>>> declaration: !14, variables: !2)
>>>>> +!29 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition:
>>>>> true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, function:
>>>>> i32 (%struct.S*)* @_ZN1S3fooEv, declaration: !17, variables: !2)
>>>>> +!30 = !{i32 2, !"Dwarf Version", i32 2}
>>>>> +!31 = !{i32 2, !"Debug Info Version", i32 3}
>>>>> +!32 = !{i32 1, !"PIC Level", i32 2}
>>>>> +!33 = !{!"clang version 3.8.0 (trunk 242534)"}
>>>>> +!34 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "s", scope:
>>>>> !25, file: !1, line: 4, type: !"_ZTS1S")
>>>>> +!35 = !DIExpression()
>>>>> +!36 = !DILocation(line: 4, column: 4, scope: !25)
>>>>> +!37 = !DILocation(line: 5, column: 2, scope: !25)
>>>>> +!38 = !DILocation(line: 5, column: 59, scope: !28, inlinedAt: !39)
>>>>> +!39 = distinct !DILocation(line: 5, column: 2, scope: !25)
>>>>> +!40 = !DILocation(line: 5, column: 54, scope: !28, inlinedAt: !39)
>>>>> +!41 = !DILocation(line: 5, column: 56, scope: !28, inlinedAt: !39)
>>>>> +!42 = !DILocation(line: 6, column: 9, scope: !25)
>>>>> +!43 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg:
>>>>> 1, scope: !28, type: !44, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!44 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S",
>>>>> size: 64, align: 64)
>>>>> +!45 = !DILocation(line: 0, scope: !28, inlinedAt: !39)
>>>>> +!46 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "Add", arg: 2,
>>>>> scope: !28, file: !5, line: 5, type: !8)
>>>>> +!47 = !DILocation(line: 5, column: 16, scope: !28, inlinedAt: !39)
>>>>> +!48 = !DILocation(line: 6, column: 2, scope: !25)
>>>>> +!49 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg:
>>>>> 1, scope: !29, type: !44, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!50 = !DILocation(line: 0, scope: !29)
>>>>> +!51 = !DILocation(line: 18, column: 21, scope: !29)
>>>>> +!52 = !DILocation(line: 18, column: 14, scope: !29)
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr4.cpp Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,8 @@
>>>>> +namespace {
>>>>> +       class AnonC {
>>>>> +       };
>>>>> +}
>>>>> +
>>>>> +void baz() {
>>>>> +       AnonC ac;
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr4.ll Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,43 @@
>>>>> +; Generated from odr4.cpp and odr-types.h by running:
>>>>> +; clang -emit-llvm -g -S -std=c++11 odr4.cpp
>>>>> +; ModuleID = 'odr4.cpp'
>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>> +target triple = "x86_64-apple-macosx10.11.0"
>>>>> +
>>>>> +%"class.(anonymous namespace)::AnonC" = type { i8 }
>>>>> +
>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>> +define void @_Z3bazv() #0 {
>>>>> +entry:
>>>>> +  %ac = alloca %"class.(anonymous namespace)::AnonC", align 1
>>>>> +  call void @llvm.dbg.declare(metadata %"class.(anonymous
>>>>> namespace)::AnonC"* %ac, metadata !11, metadata !14), !dbg !15
>>>>> +  ret void, !dbg !16
>>>>> +}
>>>>> +
>>>>> +; Function Attrs: nounwind readnone
>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>> +
>>>>> +attributes #0 = { nounwind ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +attributes #1 = { nounwind readnone }
>>>>> +
>>>>> +!llvm.dbg.cu = !{!0}
>>>>> +!llvm.module.flags = !{!7, !8, !9}
>>>>> +!llvm.ident = !{!10}
>>>>> +
>>>>> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
>>>>> producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false,
>>>>> runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
>>>>> +!1 = !DIFile(filename: "odr4.cpp", directory: "/Inputs")
>>>>> +!2 = !{}
>>>>> +!3 = !{!4}
>>>>> +!4 = !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1,
>>>>> file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, scopeLine:
>>>>> 6, flags: DIFlagPrototyped, isOptimized: false, function: void ()*
>>>>> @_Z3bazv, variables: !2)
>>>>> +!5 = !DISubroutineType(types: !6)
>>>>> +!6 = !{null}
>>>>> +!7 = !{i32 2, !"Dwarf Version", i32 2}
>>>>> +!8 = !{i32 2, !"Debug Info Version", i32 3}
>>>>> +!9 = !{i32 1, !"PIC Level", i32 2}
>>>>> +!10 = !{!"clang version 3.8.0 (trunk 242534)"}
>>>>> +!11 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ac", scope:
>>>>> !4, file: !1, line: 7, type: !12)
>>>>> +!12 = !DICompositeType(tag: DW_TAG_class_type, name: "AnonC", scope:
>>>>> !13, file: !1, line: 2, size: 8, align: 8, elements: !2)
>>>>> +!13 = !DINamespace(scope: null, file: !1, line: 1)
>>>>> +!14 = !DIExpression()
>>>>> +!15 = !DILocation(line: 7, column: 8, scope: !4)
>>>>> +!16 = !DILocation(line: 8, column: 1, scope: !4)
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr5.cpp Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,7 @@
>>>>> +#include "odr-types.h"
>>>>> +
>>>>> +double baz() {
>>>>> +       S::Nested d;
>>>>> +       d.init(0);
>>>>> +       return d.D;
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr5.ll Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,101 @@
>>>>> +; Generated from odr5.cpp and odr-types.h by running:
>>>>> +; clang -emit-llvm -g -S -std=c++11 odr5.cpp
>>>>> +; ModuleID = 'odr5.cpp'
>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>> +target triple = "x86_64-apple-macosx10.11.0"
>>>>> +
>>>>> +%"struct.S::Nested" = type { double }
>>>>> +
>>>>> +; Function Attrs: ssp uwtable
>>>>> +define double @_Z3bazv() #0 {
>>>>> +entry:
>>>>> +  %d = alloca %"struct.S::Nested", align 8
>>>>> +  call void @llvm.dbg.declare(metadata %"struct.S::Nested"* %d,
>>>>> metadata !39, metadata !40), !dbg !41
>>>>> +  call void @_ZN1S6Nested4initIiEEvT_(%"struct.S::Nested"* %d, i32
>>>>> 0), !dbg !42
>>>>> +  %D = getelementptr inbounds %"struct.S::Nested",
>>>>> %"struct.S::Nested"* %d, i32 0, i32 0, !dbg !43
>>>>> +  %0 = load double, double* %D, align 8, !dbg !43
>>>>> +  ret double %0, !dbg !44
>>>>> +}
>>>>> +
>>>>> +; Function Attrs: nounwind readnone
>>>>> +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
>>>>> +
>>>>> +; Function Attrs: nounwind ssp uwtable
>>>>> +define linkonce_odr void
>>>>> @_ZN1S6Nested4initIiEEvT_(%"struct.S::Nested"* %this, i32 %Val) #2 align 2 {
>>>>> +entry:
>>>>> +  %this.addr = alloca %"struct.S::Nested"*, align 8
>>>>> +  %Val.addr = alloca i32, align 4
>>>>> +  store %"struct.S::Nested"* %this, %"struct.S::Nested"** %this.addr,
>>>>> align 8
>>>>> +  call void @llvm.dbg.declare(metadata %"struct.S::Nested"**
>>>>> %this.addr, metadata !45, metadata !40), !dbg !47
>>>>> +  store i32 %Val, i32* %Val.addr, align 4
>>>>> +  call void @llvm.dbg.declare(metadata i32* %Val.addr, metadata !48,
>>>>> metadata !40), !dbg !49
>>>>> +  %this1 = load %"struct.S::Nested"*, %"struct.S::Nested"** %this.addr
>>>>> +  %0 = load i32, i32* %Val.addr, align 4, !dbg !50
>>>>> +  %conv = sitofp i32 %0 to double, !dbg !50
>>>>> +  %D = getelementptr inbounds %"struct.S::Nested",
>>>>> %"struct.S::Nested"* %this1, i32 0, i32 0, !dbg !51
>>>>> +  store double %conv, double* %D, align 8, !dbg !52
>>>>> +  ret void, !dbg !53
>>>>> +}
>>>>> +
>>>>> +attributes #0 = { ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +attributes #1 = { nounwind readnone }
>>>>> +attributes #2 = { nounwind ssp uwtable "disable-tail-calls"="false"
>>>>> "less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
>>>>> "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
>>>>> "no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
>>>>> "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
>>>>> "unsafe-fp-math"="false" "use-soft-float"="false" }
>>>>> +
>>>>> +!llvm.dbg.cu = !{!0}
>>>>> +!llvm.module.flags = !{!35, !36, !37}
>>>>> +!llvm.ident = !{!38}
>>>>> +
>>>>> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,
>>>>> producer: "clang version 3.8.0 (trunk 242534)", isOptimized: false,
>>>>> runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !3,
>>>>> subprograms: !24)
>>>>> +!1 = !DIFile(filename: "odr5.cpp", directory: "/Inputs")
>>>>> +!2 = !{}
>>>>> +!3 = !{!4, !20, !23}
>>>>> +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "S", file:
>>>>> !5, line: 1, size: 128, align: 64, elements: !6, identifier: "_ZTS1S")
>>>>> +!5 = !DIFile(filename: "./odr-types.h", directory: "/Inputs")
>>>>> +!6 = !{!7, !9, !10, !14, !17}
>>>>> +!7 = !DIDerivedType(tag: DW_TAG_member, name: "I", scope: !"_ZTS1S",
>>>>> file: !5, line: 2, baseType: !8, size: 32, align: 32)
>>>>> +!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding:
>>>>> DW_ATE_signed)
>>>>> +!9 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope: !"_ZTS1S",
>>>>> file: !5, line: 15, baseType: !"_ZTSN1S6NestedE", size: 64, align: 64,
>>>>> offset: 64)
>>>>> +!10 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 4, type: !11, isLocal: false, isDefinition:
>>>>> false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!11 = !DISubroutineType(types: !12)
>>>>> +!12 = !{null, !13}
>>>>> +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1S",
>>>>> size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!14 = !DISubprogram(name: "incr", linkageName: "_ZN1S4incrEi", scope:
>>>>> !"_ZTS1S", file: !5, line: 5, type: !15, isLocal: false, isDefinition:
>>>>> false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!15 = !DISubroutineType(types: !16)
>>>>> +!16 = !{null, !13, !8}
>>>>> +!17 = !DISubprogram(name: "foo", linkageName: "_ZN1S3fooEv", scope:
>>>>> !"_ZTS1S", file: !5, line: 18, type: !18, isLocal: false, isDefinition:
>>>>> false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false)
>>>>> +!18 = !DISubroutineType(types: !19)
>>>>> +!19 = !{!8, !13}
>>>>> +!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nested",
>>>>> scope: !"_ZTS1S", file: !5, line: 9, size: 64, align: 64, elements: !21,
>>>>> identifier: "_ZTSN1S6NestedE")
>>>>> +!21 = !{!22}
>>>>> +!22 = !DIDerivedType(tag: DW_TAG_member, name: "D", scope:
>>>>> !"_ZTSN1S6NestedE", file: !5, line: 10, baseType: !23, size: 64, align: 64)
>>>>> +!23 = !DIBasicType(name: "double", size: 64, align: 64, encoding:
>>>>> DW_ATE_float)
>>>>> +!24 = !{!25, !28}
>>>>> +!25 = !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1,
>>>>> file: !1, line: 3, type: !26, isLocal: false, isDefinition: true,
>>>>> scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: double
>>>>> ()* @_Z3bazv, variables: !2)
>>>>> +!26 = !DISubroutineType(types: !27)
>>>>> +!27 = !{!23}
>>>>> +!28 = !DISubprogram(name: "init<int>", linkageName:
>>>>> "_ZN1S6Nested4initIiEEvT_", scope: !"_ZTSN1S6NestedE", file: !5, line: 12,
>>>>> type: !29, isLocal: false, isDefinition: true, scopeLine: 12, flags:
>>>>> DIFlagPrototyped, isOptimized: false, function: void (%"struct.S::Nested"*,
>>>>> i32)* @_ZN1S6Nested4initIiEEvT_, templateParams: !32, declaration: !34,
>>>>> variables: !2)
>>>>> +!29 = !DISubroutineType(types: !30)
>>>>> +!30 = !{null, !31, !8}
>>>>> +!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType:
>>>>> !"_ZTSN1S6NestedE", size: 64, align: 64, flags: DIFlagArtificial |
>>>>> DIFlagObjectPointer)
>>>>> +!32 = !{!33}
>>>>> +!33 = !DITemplateTypeParameter(name: "T", type: !8)
>>>>> +!34 = !DISubprogram(name: "init<int>", linkageName:
>>>>> "_ZN1S6Nested4initIiEEvT_", scope: !"_ZTSN1S6NestedE", file: !5, line: 12,
>>>>> type: !29, isLocal: false, isDefinition: false, scopeLine: 12, flags:
>>>>> DIFlagPrototyped, isOptimized: false, templateParams: !32)
>>>>> +!35 = !{i32 2, !"Dwarf Version", i32 2}
>>>>> +!36 = !{i32 2, !"Debug Info Version", i32 3}
>>>>> +!37 = !{i32 1, !"PIC Level", i32 2}
>>>>> +!38 = !{!"clang version 3.8.0 (trunk 242534)"}
>>>>> +!39 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "d", scope:
>>>>> !25, file: !1, line: 4, type: !"_ZTSN1S6NestedE")
>>>>> +!40 = !DIExpression()
>>>>> +!41 = !DILocation(line: 4, column: 12, scope: !25)
>>>>> +!42 = !DILocation(line: 5, column: 2, scope: !25)
>>>>> +!43 = !DILocation(line: 6, column: 11, scope: !25)
>>>>> +!44 = !DILocation(line: 6, column: 2, scope: !25)
>>>>> +!45 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "this", arg:
>>>>> 1, scope: !28, type: !46, flags: DIFlagArtificial | DIFlagObjectPointer)
>>>>> +!46 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType:
>>>>> !"_ZTSN1S6NestedE", size: 64, align: 64)
>>>>> +!47 = !DILocation(line: 0, scope: !28)
>>>>> +!48 = !DILocalVariable(tag: DW_TAG_arg_variable, name: "Val", arg: 2,
>>>>> scope: !28, file: !5, line: 12, type: !8)
>>>>> +!49 = !DILocation(line: 12, column: 36, scope: !28)
>>>>> +!50 = !DILocation(line: 12, column: 54, scope: !28)
>>>>> +!51 = !DILocation(line: 12, column: 43, scope: !28)
>>>>> +!52 = !DILocation(line: 12, column: 45, scope: !28)
>>>>> +!53 = !DILocation(line: 12, column: 60, scope: !28)
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr6.cpp Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,7 @@
>>>>> +#include "odr-types.h"
>>>>> +
>>>>> +double baz() {
>>>>> +       S::Nested d;
>>>>> +       d.init(0.0);
>>>>> +       return d.D;
>>>>> +}
>>>>>
>>>>> Added: llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll?rev=242847&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll (added)
>>>>> +++ llvm/trunk/test/tools/dsymutil/Inputs/odr6.ll Tue Jul 21 17:41:43
>>>>> 2015
>>>>> @@ -0,0 +1,100 @@
>>>>> +; Generated from odr6.cpp and odr-types.h by running:
>>>>> +; clang -emit-llvm -g -S -std=c++11 odr6.cpp
>>>>> +; ModuleID = 'odr6.cpp'
>>>>> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
>>>>> +target triple = "x86_64-apple-macosx10.11.0"
>>>>> +
>>>>> +%"struct.S::Nested" = type { double }
>>>>> +
>>>>> +; Function Attrs: ssp uwtable
>>>>> +define double @_Z3bazv() #0 {
>>>>> +entry:
>>>>> +  %d = alloca %"struct.S::Nested", align 8
>>>>> +  call void @llvm.dbg.declare(metadata %"struct.S::Nested"* %d,
>>>>> metadata !39, metadata !40), !dbg !41
>>>>> +  call void @_ZN1S6Nested4initIdEEvT_(%"struct.S::Nested"* %d, double
>>>>> 0.000000e+00), !dbg !42
>>>>> +  %D = getelementptr inbounds %"struct.S::Nested",
>>>>> %"struct.S::Nested"* %d, i32 0, i32 0, !dbg !43
>>>>> +  %0 = load double, double* %D, align 8, !dbg !43
>>>>> +  ret double %0, !dbg !44
>>>>>
>>>>
> ...
>
> [Message clipped]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150729/34a648f5/attachment.html>


More information about the llvm-commits mailing list