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

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 7 12:50:44 PDT 2015


Add the new list again

On Fri, Aug 7, 2015 at 12:49 PM, David Blaikie <dblaikie at gmail.com> wrote:

>
>
> On Fri, Aug 7, 2015 at 11:24 AM, Frédéric Riss <friss at apple.com> wrote:
>
>>
>> On Aug 7, 2015, at 11:02 AM, David Blaikie <dblaikie at gmail.com> wrote:
>>
>> Looks pretty good. Just going through it:
>>
>> odr-anon-namespace - any reason this isn't just the same file compiled
>> twice? (rather than having a FILE1 and FILE2 section which are more-or-less
>> (apart from the name of the foo function - which it seems like dsymutil is
>> OK with a duplicate of, based on other tests) the same?)
>>
>>
>> Yes. The current logic will unique types in anonymous namespaces if the
>> file/line matches. I want to test the case when they don’t match. I think
>> this is wrong (and there is a FIXME in the code). I can build a
>> (convoluted) test using preprocessor macros that breaks with the current
>> logic, but for the sake of compatibility with dsymutil-classic for now it
>> works this way.
>>
>
> Ah, OK - a comment describing that might be helpful. You could pare down
> the test by just having #ifdef FILE1 #line 3 #endif - which would tweak the
> line number without having to duplicate the whole struct & would be a handy
> place to have the comment.
>
>
>>
>> When matching between a tag and an attribute, you only need a CHECK-NOT:
>> DW_TAG (because you can't call into another tag's attributes without
>> passing the TAG first, regardless of the number of NULLs) - only need
>> {{DW_TAG|NULL}} when searching for the immediately next TAG and wanting to
>> ensure you don't end up outside (eg: if you're looking for a class in a
>> namespace you want to make sure there's no other classes/namespaces/etc
>> that you might now end up matching inside of, and that you didn't skip out
>> of the namespace either)
>>
>>
>> I know that, but I usually write my CHECK lines and then insert the
>> generic CHECK-NOT ones in one go. I’ll go through it and remove the useless
>> conditions.
>>
>> You could drop the explicit 'inline' keyword from the inline-defined
>> member functions in odr-member-functions.cpp - why did you need two of
>> them? (what's foo(int) checking that foo() didn't check? (and what's foo()
>> checking that foo(int) didn't check?))
>>
>>
>> /goes back to the test to check
>>
>> In the test as written, they do not test much. Their intent in the
>> original test was to verify that dsymutil wouldn’t confuse foo() and
>> foo(int). I’ll mark them always_inline add tests to check that the
>> DW_TAG_inlined_subroutine refer to the correct one.
>>
>
> Hmm, OK.
>
>
>>
>> Misspelling of implicit (implicit)
>>
>>
>> thanks
>>
>> One thing I was trying to explain previously, was the idea that maybe
>> there coudl be a generic .map file used by multiple of these tests. Would
>> that make any sense? I see now that the map file has the names of the
>> object files baked in, so I guess it doesn't make sense - unless the object
>> files used the same names for each test and were put in a subdirectory,
>> perhaps? (so there was foo/{1,2}.o, bar/{1,2}.o - and the map file would
>> just mention 1.o and 2.o and could be reused for both the foo and bar tests)
>>
>>
>> For these tests where the symbols don’t matter, I’d be more inclined to
>> work on a mode where we don’t need a debug map file at all. However that’s
>> a feature that would be useful only for that test and it’s not actually
>> totally trivial to implement. I could make it work by playing with the
>> paths in the tests, but I’m not sure it’s worth it. The current setup is
>> pretty clear even if a bit verbose.
>>
>
> Fair enough - just figured you'd be adding more & more tests and ensuring
> the cost of adding a new one is relatively low is a worthwhile investment
> sooner rather than later.
>
> Anyway - if these are starting to feel reasonable to you, they're looking
> at least in the ballpark of what I thought might be good, if/when it suits
> you to commit them. I imagine any further streamlining can be discovered
> organically/iteratively improved from here.
>
> - Dave
>
>
>>
>> Fred
>>
>>
>> On Mon, Aug 3, 2015 at 3:39 PM, Frédéric Riss <friss at apple.com> wrote:
>>
>>> Here’s a new patch that refactors all the tests of the monolithic
>>> odr-1.test into 3 different tests and hosts the CHECK lines with the source
>>> code.
>>> WDYT?
>>>
>>>
>>>
>>>
>>>
>>> On Jul 29, 2015, at 5:00 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>>
>>>
>>>
>>> On Wed, Jul 29, 2015 at 3:58 PM, Frédéric Riss <friss at apple.com> wrote:
>>>
>>>>
>>>> On Jul 29, 2015, at 3:35 PM, David Blaikie <dblaikie at gmail.com> wrote:
>>>>
>>>>
>>>>
>>>> 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?
>>>>
>>>>
>>>> I started this way and then moved the CHECKs away from the code. One
>>>> reason is that the typedef ends up being emitted last
>>>>
>>>
>>> That's curious - I would've expected types to be emitted in the order
>>> they are referenced by the variables in 'foo'.
>>>
>>> Oh, right, because all the class/struct types end up in the retained
>>> types list due to DITypeRef stuff. And they all get emitted first because
>>> we iterate the retained types first.
>>>
>>> So if you put the typedef after those, it'll be "in order"
>>>
>>>
>>>> and I didn’t find a way to have the debug info match the source order
>>>> (I didn’t try that hard though). The other reason is that the code became
>>>> nearly invisible in-between the CHECKs. Having all the code together makes
>>>> it IMO easier to read/search/refer to.
>>>>
>>>
>>> I assume you use a syntax highlighting text editor? With that I usually
>>> find it easy to see the alternating patches of code & comments, and
>>> associate them together - the same as I do when reading source code with
>>> detailed comments. Does this come out somewhat differently in terms of
>>> readability?
>>>
>>>
>>>>
>>>> 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?
>>>>
>>>>
>>>> I did CHECK-NEXT each time I could, just because it save a line. I can
>>>> move to always doing the CHECK-NOT dance, the test will just grow a bit.
>>>>
>>>
>>> Yeah, I'm on the fence. I have a small preference towards resilience/not
>>> relying on particular ordering of attribute output... but I know it becomes
>>> more verbose. *shrug* your call (actually, so long as dsymutil preserves
>>> the input attribute order, and you checkin binaries, you can depend on the
>>> ordering without the tests being overly brittle - at least they're only
>>> brittle to updates to the object file, which places the cost on you/the
>>> dsymutil developers (that may exist in the future) - so the tests won't
>>> break if we update LLVM to output in a different order, so it won't hurt
>>> me, Adrian, etc, anyone else working on LLVM debug info - so that's not too
>>> bad)
>>>
>>>
>>>>
>>>> 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?
>>>>
>>>>
>>>> I need to try it. When I first wrote the test (the one that’s checked
>>>> in), I started like that, but the differences where to big to share much.
>>>> Now that I narrowed a bit the test, it might very well be worth
>>>> re-exploring that possibility.
>>>>
>>>>
>>> For the record, I tried it, and due to the order of emission (anonymous
>>> namespace and typedef are emitted after the function that uses them), I
>>> find it more natural the way it is. I could do that for half the variables,
>>> but I prefer having a few more CHECK lines, but an overall CHECK structure
>>> that’s totally coherent.
>>>
>>> Fred
>>>
>>> How's the tool handle the duplicate 'foo' function (that would be a link
>>>> error in the actual object link)?
>>>>
>>>>
>>>> The linker couldn’t generate that, but dsymutil doesn’t care (actually,
>>>> the linker does generate such duplicate objects. Not with the same symbols,
>>>> but the same object file might appear multiple times in LTO links. Don’t
>>>> ask, I don’t know why. I need to figure that out.). llvm-dsymutil just
>>>> works per-object applying the relocations described in the debug map. It
>>>> doesn’t even need the symbol names most of the time.
>>>>
>>>> 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 thought you’d say that :-) They won’t be that different than this
>>>> one, except they’ll come with 2 (or maybe 3 for one of them) object files.
>>>> If there are less checks, the CHECK lines might also fit better inside the
>>>> code.
>>>>
>>>> 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.
>>>>
>>>>
>>>> Yes, that’s the plan. And BTW, you keep calling it dlsym when it’s
>>>> dsymutil. Either you have a pretty geeky auto-correct, or your muscle
>>>> memory gives away your love of dynamic loader interfaces :-)
>>>>
>>>
>>> Ah, right, thanks for the correction. Just my unfamiliarity with these
>>> mac things. Will try to get that right.
>>>
>>> - Dave
>>>
>>>
>>>>
>>>> Thanks,
>>>> Fred
>>>>
>>>>
>>>>>
>>>>>
>>>>>
>>>>> 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" }
>>>>>>>>> +attribut
>>>>>>>>
>>>>>>>>
>>> ...
>>>
>>> [Message clipped]
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150807/0c9650b8/attachment-0001.html>


More information about the llvm-commits mailing list